diff options
Diffstat (limited to 'contrib/llvm/include')
436 files changed, 16831 insertions, 8946 deletions
diff --git a/contrib/llvm/include/llvm-c/Core.h b/contrib/llvm/include/llvm-c/Core.h index 620d088..e85fb97 100644 --- a/contrib/llvm/include/llvm-c/Core.h +++ b/contrib/llvm/include/llvm-c/Core.h @@ -21,8 +21,8 @@ /* Need these includes to support the LLVM 'cast' template for the C++ 'wrap' and 'unwrap' conversion functions. */ -#include "llvm/IRBuilder.h" -#include "llvm/Module.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Module.h" #include "llvm/PassRegistry.h" extern "C" { @@ -173,10 +173,11 @@ typedef enum { LLVMUWTable = 1 << 30, LLVMNonLazyBind = 1 << 31 - /* FIXME: This attribute is currently not included in the C API as + /* FIXME: These attributes are currently not included in the C API as a temporary measure until the API/ABI impact to the C API is understood and the path forward agreed upon. - LLVMAddressSafety = 1ULL << 32 + LLVMAddressSafety = 1ULL << 32, + LLVMStackProtectStrongAttribute = 1ULL<<33 */ } LLVMAttribute; @@ -357,6 +358,11 @@ typedef enum { void LLVMInitializeCore(LLVMPassRegistryRef R); +/** Deallocate and destroy all ManagedStatic variables. + @see llvm::llvm_shutdown + @see ManagedStatic */ +void LLVMShutdown(); + /*===-- Error handling ----------------------------------------------------===*/ @@ -2547,6 +2553,13 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path, char **OutMessage); LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage); +LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData, + size_t InputDataLength, + const char *BufferName, + LLVMBool RequiresNullTerminator); +LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData, + size_t InputDataLength, + const char *BufferName); void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf); /** @@ -2619,6 +2632,34 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM); */ /** + * @defgroup LLVMCCoreThreading Threading + * + * Handle the structures needed to make LLVM safe for multithreading. + * + * @{ + */ + +/** Allocate and initialize structures needed to make LLVM safe for + multithreading. The return value indicates whether multithreaded + initialization succeeded. Must be executed in isolation from all + other LLVM api calls. + @see llvm::llvm_start_multithreaded */ +LLVMBool LLVMStartMultithreaded(); + +/** Deallocate structures necessary to make LLVM safe for multithreading. + Must be executed in isolation from all other LLVM api calls. + @see llvm::llvm_stop_multithreaded */ +void LLVMStopMultithreaded(); + +/** Check whether LLVM is executing in thread-safe mode or not. + @see llvm::llvm_is_multithreaded */ +LLVMBool LLVMIsMultithreaded(); + +/** + * @} + */ + +/** * @} */ diff --git a/contrib/llvm/include/llvm-c/Disassembler.h b/contrib/llvm/include/llvm-c/Disassembler.h index b8c4ad9..df65a7b 100644 --- a/contrib/llvm/include/llvm-c/Disassembler.h +++ b/contrib/llvm/include/llvm-c/Disassembler.h @@ -139,13 +139,26 @@ extern "C" { * by passing a block of information in the DisInfo parameter and specifying the * TagType and callback functions as described above. These can all be passed * as NULL. If successful, this returns a disassembler context. If not, it - * returns NULL. + * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU() + * with an empty CPU name. */ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp); /** + * Create a disassembler for the TripleName and a specific CPU. Symbolic + * disassembly is supported by passing a block of information in the DisInfo + * parameter and specifying the TagType and callback functions as described + * above. These can all be passed * as NULL. If successful, this returns a + * disassembler context. If not, it returns NULL. + */ +LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, + void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); + +/** * Set the disassembler's options. Returns 1 if it can set the Options and 0 * otherwise. */ @@ -153,6 +166,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options); /* The option to produce marked up assembly. */ #define LLVMDisassembler_Option_UseMarkup 1 +/* The option to print immediates as hex. */ +#define LLVMDisassembler_Option_PrintImmHex 2 +/* The option use the other assembler printer variant */ +#define LLVMDisassembler_Option_AsmPrinterVariant 4 /** * Dispose of a disassembler context. diff --git a/contrib/llvm/include/llvm-c/EnhancedDisassembly.h b/contrib/llvm/include/llvm-c/EnhancedDisassembly.h deleted file mode 100644 index 71a0d49..0000000 --- a/contrib/llvm/include/llvm-c/EnhancedDisassembly.h +++ /dev/null @@ -1,530 +0,0 @@ -/*===-- llvm-c/EnhancedDisassembly.h - Disassembler 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 declares the C interface to EnhancedDisassembly.so, which *| -|* implements a disassembler with the ability to extract operand values and *| -|* individual tokens from assembly instructions. *| -|* *| -|* The header declares additional interfaces if the host compiler supports *| -|* the blocks API. *| -|* *| -\*===----------------------------------------------------------------------===*/ - -#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H -#define LLVM_C_ENHANCEDDISASSEMBLY_H - -#include "llvm/Support/DataTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup LLVMCEnhancedDisassembly Enhanced Disassembly - * @ingroup LLVMC - * @deprecated - * - * This module contains an interface to the Enhanced Disassembly (edis) - * library. The edis library is deprecated and will likely disappear in - * the near future. You should use the @ref LLVMCDisassembler interface - * instead. - * - * @{ - */ - -/*! - @typedef EDByteReaderCallback - Interface to memory from which instructions may be read. - @param byte A pointer whose target should be filled in with the data returned. - @param address The address of the byte to be read. - @param arg An anonymous argument for client use. - @result 0 on success; -1 otherwise. - */ -typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg); - -/*! - @typedef EDRegisterReaderCallback - Interface to registers from which registers may be read. - @param value A pointer whose target should be filled in with the value of the - register. - @param regID The LLVM register identifier for the register to read. - @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, - void* arg); - -/*! - @typedef EDAssemblySyntax_t - An assembly syntax for use in tokenizing instructions. - */ -enum { -/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */ - kEDAssemblySyntaxX86Intel = 0, -/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */ - kEDAssemblySyntaxX86ATT = 1, - kEDAssemblySyntaxARMUAL = 2 -}; -typedef unsigned EDAssemblySyntax_t; - -/*! - @typedef EDDisassemblerRef - Encapsulates a disassembler for a single CPU architecture. - */ -typedef void *EDDisassemblerRef; - -/*! - @typedef EDInstRef - Encapsulates a single disassembled instruction in one assembly syntax. - */ -typedef void *EDInstRef; - -/*! - @typedef EDTokenRef - Encapsulates a token from the disassembly of an instruction. - */ -typedef void *EDTokenRef; - -/*! - @typedef EDOperandRef - Encapsulates an operand of an instruction. - */ -typedef void *EDOperandRef; - -/*! - @functiongroup Getting a disassembler - */ - -/*! - @function EDGetDisassembler - Gets the disassembler for a given target. - @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. - @result 0 on success; -1 otherwise. - */ -int EDGetDisassembler(EDDisassemblerRef *disassembler, - const char *triple, - EDAssemblySyntax_t syntax); - -/*! - @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 - @param disassembler The disassembler to query for the name. - @param regID The register identifier, as returned by EDRegisterTokenValue. - @result 0 on success; -1 otherwise. - */ -int EDGetRegisterName(const char** regName, - EDDisassemblerRef disassembler, - unsigned regID); - -/*! - @function EDRegisterIsStackPointer - Determines if a register is one of the platform's stack-pointer registers. - @param disassembler The disassembler to query. - @param regID The register identifier, as returned by EDRegisterTokenValue. - @result 1 if true; 0 otherwise. - */ -int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, - unsigned regID); - -/*! - @function EDRegisterIsProgramCounter - Determines if a register is one of the platform's stack-pointer registers. - @param disassembler The disassembler to query. - @param regID The register identifier, as returned by EDRegisterTokenValue. - @result 1 if true; 0 otherwise. - */ -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 - be set to NULL. - @param count The maximum number of instructions to fill in. - @param disassembler The disassembler to use when decoding the instructions. - @param byteReader The function to use when reading the instruction's machine - code. - @param address The address of the first byte of the instruction. - @param arg An anonymous argument to be passed to byteReader. - @result The number of instructions read on success; 0 otherwise. - */ -unsigned int EDCreateInsts(EDInstRef *insts, - unsigned int count, - EDDisassemblerRef disassembler, - EDByteReaderCallback byteReader, - uint64_t address, - void *arg); - -/*! - @function EDReleaseInst - Frees the memory for an instruction. The instruction can no longer be accessed - after this call. - @param inst The instruction to be freed. - */ -void EDReleaseInst(EDInstRef inst); - -/*! - @function EDInstByteSize - @param inst The instruction to be queried. - @result The number of bytes in the instruction's machine-code representation. - */ -int EDInstByteSize(EDInstRef inst); - -/*! - @function EDGetInstString - Gets the disassembled text equivalent of the instruction. - @param buf A pointer whose target will be filled in with a pointer to the - string. (The string becomes invalid when the instruction is released.) - @param inst The instruction to be queried. - @result 0 on success; -1 otherwise. - */ -int EDGetInstString(const char **buf, - EDInstRef inst); - -/*! - @function EDInstID - @param instID A pointer whose target will be filled in with the LLVM identifier - for the instruction. - @param inst The instruction to be queried. - @result 0 on success; -1 otherwise. - */ -int EDInstID(unsigned *instID, EDInstRef inst); - -/*! - @function EDInstIsBranch - @param inst The instruction to be queried. - @result 1 if the instruction is a branch instruction; 0 if it is some other - type of instruction; -1 if there was an error. - */ -int EDInstIsBranch(EDInstRef inst); - -/*! - @function EDInstIsMove - @param inst The instruction to be queried. - @result 1 if the instruction is a move instruction; 0 if it is some other - type of instruction; -1 if there was an error. - */ -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 - EDCopyOperand. -1 if no such operand exists. - */ -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 - EDCopyOperand. -1 if no such operand exists. - */ -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 - EDCopyOperand. -1 if no such operand exists. - */ -int EDMoveTargetID(EDInstRef inst); - -/*! - @functiongroup Creating and querying tokens - */ - -/*! - @function EDNumTokens - @param inst The instruction to be queried. - @result The number of tokens in the instruction, or -1 on error. - */ -int EDNumTokens(EDInstRef inst); - -/*! - @function EDGetToken - Retrieves a token from an instruction. The token is valid until the - instruction is released. - @param token A pointer to be filled in with the token. - @param inst The instruction to be queried. - @param index The index of the token in the instruction. - @result 0 on success; -1 otherwise. - */ -int EDGetToken(EDTokenRef *token, - EDInstRef inst, - int index); - -/*! - @function EDGetTokenString - Gets the disassembled text for a token. - @param buf A pointer whose target will be filled in with a pointer to the - string. (The string becomes invalid when the token is released.) - @param token The token to be queried. - @result 0 on success; -1 otherwise. - */ -int EDGetTokenString(const char **buf, - EDTokenRef token); - -/*! - @function EDOperandIndexForToken - Returns the index of the operand to which a token belongs. - @param token The token to be queried. - @result The operand index on success; -1 otherwise - */ -int EDOperandIndexForToken(EDTokenRef token); - -/*! - @function EDTokenIsWhitespace - @param token The token to be queried. - @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. - @result 1 if the token is punctuation; 0 if not; -1 on error. - */ -int EDTokenIsPunctuation(EDTokenRef token); - -/*! - @function EDTokenIsOpcode - @param token The token to be queried. - @result 1 if the token is opcode; 0 if not; -1 on error. - */ -int EDTokenIsOpcode(EDTokenRef token); - -/*! - @function EDTokenIsLiteral - @param token The token to be queried. - @result 1 if the token is a numeric literal; 0 if not; -1 on error. - */ -int EDTokenIsLiteral(EDTokenRef token); - -/*! - @function EDTokenIsRegister - @param token The token to be queried. - @result 1 if the token identifies a register; 0 if not; -1 on error. - */ -int EDTokenIsRegister(EDTokenRef token); - -/*! - @function EDTokenIsNegativeLiteral - @param token The token to be queried. - @result 1 if the token is a negative signed literal; 0 if not; -1 on error. - */ -int EDTokenIsNegativeLiteral(EDTokenRef token); - -/*! - @function EDLiteralTokenAbsoluteValue - @param value A pointer whose target will be filled in with the absolute value - of the literal. - @param token The token to be queried. - @result 0 on success; -1 otherwise. - */ -int EDLiteralTokenAbsoluteValue(uint64_t *value, - EDTokenRef token); - -/*! - @function EDRegisterTokenValue - @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. - @result The number of operands in the instruction, or -1 on error. - */ -int EDNumOperands(EDInstRef inst); - -/*! - @function EDGetOperand - Retrieves an operand from an instruction. The operand is valid until the - instruction is released. - @param operand A pointer to be filled in with the operand. - @param inst The instruction to be queried. - @param index The index of the operand in the instruction. - @result 0 on success; -1 otherwise. - */ -int EDGetOperand(EDOperandRef *operand, - EDInstRef inst, - int index); - -/*! - @function EDOperandIsRegister - @param operand The operand to be queried. - @result 1 if the operand names a register; 0 if not; -1 on error. - */ -int EDOperandIsRegister(EDOperandRef operand); - -/*! - @function EDOperandIsImmediate - @param operand The operand to be queried. - @result 1 if the operand specifies an immediate value; 0 if not; -1 on error. - */ -int EDOperandIsImmediate(EDOperandRef operand); - -/*! - @function EDOperandIsMemory - @param operand The operand to be queried. - @result 1 if the operand specifies a location in memory; 0 if not; -1 on error. - */ -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. - @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 - immediate. - @param operand The operand to be queried. - @result 0 on success; -1 otherwise. - */ -int EDImmediateOperandValue(uint64_t *value, - EDOperandRef operand); - -/*! - @function EDEvaluateOperand - Evaluates an operand using a client-supplied register state accessor. Register - operands are evaluated by reading the value of the register; immediate operands - are evaluated by reporting the immediate value; memory operands are evaluated - by computing the target address (with only those relocations applied that were - already applied to the original bytes). - @param result A pointer whose target is to be filled with the result of - evaluating the operand. - @param operand The operand to be evaluated. - @param regReader The function to use when reading registers from the register - state. - @param arg An anonymous argument for client use. - @result 0 if the operand could be evaluated; -1 otherwise. - */ -int EDEvaluateOperand(uint64_t *result, - EDOperandRef operand, - EDRegisterReaderCallback regReader, - void *arg); - -#ifdef __BLOCKS__ - -/*! - @typedef EDByteBlock_t - Block-based interface to memory from which instructions may be read. - @param byte A pointer whose target should be filled in with the data returned. - @param address The address of the byte to be read. - @result 0 on success; -1 otherwise. - */ -typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address); - -/*! - @typedef EDRegisterBlock_t - Block-based interface to registers from which registers may be read. - @param value A pointer whose target should be filled in with the value of the - register. - @param regID The LLVM register identifier for the register to read. - @result 0 if the register could be read; -1 otherwise. - */ -typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID); - -/*! - @typedef EDTokenVisitor_t - Block-based handler for individual tokens. - @param token The current token being read. - @result 0 to continue; 1 to stop normally; -1 on error. - */ -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 - be set to NULL. - @param count The maximum number of instructions to fill in. - @param disassembler The disassembler to use when decoding the instructions. - @param byteBlock The block to use when reading the instruction's machine - code. - @param address The address of the first byte of the instruction. - @result The number of instructions read on success; 0 otherwise. - */ -unsigned int EDBlockCreateInsts(EDInstRef *insts, - int count, - EDDisassemblerRef disassembler, - EDByteBlock_t byteBlock, - uint64_t address); - -/*! - @function EDBlockEvaluateOperand - Evaluates an operand using a block to read registers. - @param result A pointer whose target is to be filled with the result of - evaluating the operand. - @param operand The operand to be evaluated. - @param regBlock The block to use when reading registers from the register - state. - @result 0 if the operand could be evaluated; -1 otherwise. - */ -int EDBlockEvaluateOperand(uint64_t *result, - EDOperandRef operand, - EDRegisterBlock_t regBlock); - -/*! - @function EDBlockVisitTokens - Visits every token with a visitor. - @param inst The instruction with the tokens to be visited. - @param visitor The visitor. - @result 0 if the visit ended normally; -1 if the visitor encountered an error - or there was some other error. - */ -int EDBlockVisitTokens(EDInstRef inst, - EDTokenVisitor_t visitor); - -/** - * @} - */ - -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/llvm/include/llvm-c/Initialization.h b/contrib/llvm/include/llvm-c/Initialization.h index cb3ab9e..ada4738 100644 --- a/contrib/llvm/include/llvm-c/Initialization.h +++ b/contrib/llvm/include/llvm-c/Initialization.h @@ -34,6 +34,7 @@ extern "C" { void LLVMInitializeCore(LLVMPassRegistryRef R); void LLVMInitializeTransformUtils(LLVMPassRegistryRef R); void LLVMInitializeScalarOpts(LLVMPassRegistryRef R); +void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R); void LLVMInitializeVectorization(LLVMPassRegistryRef R); void LLVMInitializeInstCombine(LLVMPassRegistryRef R); void LLVMInitializeIPO(LLVMPassRegistryRef R); diff --git a/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h b/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h index 5338d3f..7a0fbf6 100644 --- a/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h +++ b/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __LTO_CAPI_H__ -#define __LTO_CAPI_H__ +#ifndef LLVM_C_LINKTIMEOPTIMIZER_H +#define LLVM_C_LINKTIMEOPTIMIZER_H #ifdef __cplusplus extern "C" { diff --git a/contrib/llvm/include/llvm-c/TargetMachine.h b/contrib/llvm/include/llvm-c/TargetMachine.h index 29668de..691abdf 100644 --- a/contrib/llvm/include/llvm-c/TargetMachine.h +++ b/contrib/llvm/include/llvm-c/TargetMachine.h @@ -20,6 +20,7 @@ #define LLVM_C_TARGETMACHINE_H #include "llvm-c/Core.h" +#include "llvm-c/Target.h" #ifdef __cplusplus extern "C" { diff --git a/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h b/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h index cee6e5a..82e513d 100644 --- a/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h +++ b/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h @@ -11,8 +11,8 @@ |* *| \*===----------------------------------------------------------------------===*/ -#ifndef LLVM_C_PASSMANAGERBUILDER -#define LLVM_C_PASSMANAGERBUILDER +#ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H +#define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H #include "llvm-c/Core.h" @@ -77,8 +77,8 @@ LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB, /** See llvm::PassManagerBuilder::populateLTOPassManager. */ void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, - bool Internalize, - bool RunInliner); + LLVMBool Internalize, + LLVMBool RunInliner); /** * @} diff --git a/contrib/llvm/include/llvm-c/lto.h b/contrib/llvm/include/llvm-c/lto.h index f43d365..40110fd 100644 --- a/contrib/llvm/include/llvm-c/lto.h +++ b/contrib/llvm/include/llvm-c/lto.h @@ -13,8 +13,8 @@ |* *| \*===----------------------------------------------------------------------===*/ -#ifndef LTO_H -#define LTO_H 1 +#ifndef LLVM_C_LTO_H +#define LLVM_C_LTO_H #include <stdbool.h> #include <stddef.h> @@ -291,6 +291,13 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); extern void lto_codegen_debug_options(lto_code_gen_t cg, const char *); +/** + * Initializes LLVM disassemblers. + * FIXME: This doesn't really belong here. + */ +extern void +lto_initialize_disassembler(void); + #ifdef __cplusplus } #endif diff --git a/contrib/llvm/include/llvm/ADT/APFloat.h b/contrib/llvm/include/llvm/ADT/APFloat.h index 31c6e6a..14bcaef 100644 --- a/contrib/llvm/include/llvm/ADT/APFloat.h +++ b/contrib/llvm/include/llvm/ADT/APFloat.h @@ -97,8 +97,8 @@ nexttoward. */ -#ifndef LLVM_FLOAT_H -#define LLVM_FLOAT_H +#ifndef LLVM_ADT_APFLOAT_H +#define LLVM_ADT_APFLOAT_H // APInt contains static functions implementing bignum arithmetic. #include "llvm/ADT/APInt.h" @@ -184,9 +184,9 @@ namespace llvm { APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, fltCategory, bool negative); APFloat(const fltSemantics &, uninitializedTag); + APFloat(const fltSemantics &, const APInt &); explicit APFloat(double d); explicit APFloat(float f); - explicit APFloat(const APInt &, bool isIEEE = false); APFloat(const APFloat &); ~APFloat(); @@ -300,7 +300,7 @@ namespace llvm { /* The definition of equality is not straightforward for floating point, so we won't use operator==. Use one of the following, or write whatever it is you really mean. */ - // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT + bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION; /* IEEE comparison with another floating point number (NaNs compare unordered, 0==-0). */ @@ -327,6 +327,7 @@ namespace llvm { bool isNegative() const { return sign; } bool isPosZero() const { return isZero() && !isNegative(); } bool isNegZero() const { return isZero() && isNegative(); } + bool isDenormal() const; APFloat& operator=(const APFloat &); @@ -422,7 +423,7 @@ namespace llvm { APInt convertQuadrupleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; APInt convertPPCDoubleDoubleAPFloatToAPInt() const; - void initFromAPInt(const APInt& api, bool isIEEE = false); + void initFromAPInt(const fltSemantics *Sem, const APInt& api); void initFromHalfAPInt(const APInt& api); void initFromFloatAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api); @@ -462,4 +463,4 @@ namespace llvm { hash_code hash_value(const APFloat &Arg); } /* namespace llvm */ -#endif /* LLVM_FLOAT_H */ +#endif /* LLVM_ADT_APFLOAT_H */ diff --git a/contrib/llvm/include/llvm/ADT/APInt.h b/contrib/llvm/include/llvm/ADT/APInt.h index c7c8016b..3d8b72d 100644 --- a/contrib/llvm/include/llvm/ADT/APInt.h +++ b/contrib/llvm/include/llvm/ADT/APInt.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_APINT_H -#define LLVM_APINT_H +#ifndef LLVM_ADT_APINT_H +#define LLVM_ADT_APINT_H #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" @@ -274,7 +274,7 @@ public: initSlowCase(that); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES /// @brief Move Constructor. APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) { that.BitWidth = 0; @@ -427,7 +427,7 @@ public: /// @returns the all-ones value for an APInt of the specified bit-width. /// @brief Get the all-ones value. static APInt getAllOnesValue(unsigned numBits) { - return APInt(numBits, -1ULL, true); + return APInt(numBits, UINT64_MAX, true); } /// @returns the '0' value for an APInt of the specified bit-width. @@ -498,13 +498,24 @@ public: if (loBitsSet == 0) return APInt(numBits, 0); if (loBitsSet == APINT_BITS_PER_WORD) - return APInt(numBits, -1ULL); + return APInt(numBits, UINT64_MAX); // For small values, return quickly. if (loBitsSet <= APINT_BITS_PER_WORD) - return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet)); + return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet)); return getAllOnesValue(numBits).lshr(numBits - loBitsSet); } + /// \brief Return a value containing V broadcasted over NewLen bits. + static APInt getSplat(unsigned NewLen, const APInt &V) { + assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!"); + + APInt Val = V.zextOrSelf(NewLen); + for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1) + Val |= Val << I; + + return Val; + } + /// \brief Determine if two APInts have the same value, after zero-extending /// one of them (if needed!) to ensure that the bit-widths match. static bool isSameValue(const APInt &I1, const APInt &I2) { @@ -601,7 +612,7 @@ public: return AssignSlowCase(RHS); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES /// @brief Move assignment operator. APInt& operator=(APInt&& that) { if (!isSingleWord()) @@ -799,16 +810,7 @@ public: /// Signed divide this APInt by APInt RHS. /// @brief Signed division function for APInt. - APInt sdiv(const APInt &RHS) const { - if (isNegative()) - if (RHS.isNegative()) - return (-(*this)).udiv(-RHS); - else - return -((-(*this)).udiv(RHS)); - else if (RHS.isNegative()) - return -(this->udiv(-RHS)); - return this->udiv(RHS); - } + APInt sdiv(const APInt &RHS) const; /// Perform an unsigned remainder operation on this APInt with RHS being the /// divisor. Both this and RHS are treated as unsigned quantities for purposes @@ -821,16 +823,7 @@ public: /// Signed remainder operation on APInt. /// @brief Function for signed remainder operation. - APInt srem(const APInt &RHS) const { - if (isNegative()) - if (RHS.isNegative()) - return -((-(*this)).urem(-RHS)); - else - return -((-(*this)).urem(RHS)); - else if (RHS.isNegative()) - return this->urem(-RHS); - return this->urem(RHS); - } + APInt srem(const APInt &RHS) const; /// Sometimes it is convenient to divide two APInt values and obtain both the /// quotient and remainder. This function does both operations in the same @@ -842,24 +835,9 @@ public: APInt &Quotient, APInt &Remainder); static void sdivrem(const APInt &LHS, const APInt &RHS, - APInt &Quotient, APInt &Remainder) { - if (LHS.isNegative()) { - if (RHS.isNegative()) - APInt::udivrem(-LHS, -RHS, Quotient, Remainder); - else { - APInt::udivrem(-LHS, RHS, Quotient, Remainder); - Quotient = -Quotient; - } - Remainder = -Remainder; - } else if (RHS.isNegative()) { - APInt::udivrem(LHS, -RHS, Quotient, Remainder); - Quotient = -Quotient; - } else { - APInt::udivrem(LHS, RHS, Quotient, Remainder); - } - } - - + APInt &Quotient, APInt &Remainder); + + // Operations that return overflow indicators. APInt sadd_ov(const APInt &RHS, bool &Overflow) const; APInt uadd_ov(const APInt &RHS, bool &Overflow) const; @@ -1113,11 +1091,11 @@ public: /// @brief Set every bit to 1. void setAllBits() { if (isSingleWord()) - VAL = -1ULL; + VAL = UINT64_MAX; else { // Set all the bits in all the words. for (unsigned i = 0; i < getNumWords(); ++i) - pVal[i] = -1ULL; + pVal[i] = UINT64_MAX; } // Clear the unused ones clearUnusedBits(); @@ -1142,10 +1120,10 @@ public: /// @brief Toggle every bit to its opposite value. void flipAllBits() { if (isSingleWord()) - VAL ^= -1ULL; + VAL ^= UINT64_MAX; else { for (unsigned i = 0; i < getNumWords(); ++i) - pVal[i] ^= -1ULL; + pVal[i] ^= UINT64_MAX; } clearUnusedBits(); } @@ -1191,7 +1169,8 @@ public: /// APInt. This is used in conjunction with getActiveData to extract the raw /// value of the APInt. unsigned getActiveWords() const { - return whichWord(getActiveBits()-1) + 1; + unsigned numActiveBits = getActiveBits(); + return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1; } /// Computes the minimum bit width for this APInt while considering it to be diff --git a/contrib/llvm/include/llvm/ADT/APSInt.h b/contrib/llvm/include/llvm/ADT/APSInt.h index 048c65c..11be4c5 100644 --- a/contrib/llvm/include/llvm/ADT/APSInt.h +++ b/contrib/llvm/include/llvm/ADT/APSInt.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_APSINT_H -#define LLVM_APSINT_H +#ifndef LLVM_ADT_APSINT_H +#define LLVM_ADT_APSINT_H #include "llvm/ADT/APInt.h" @@ -23,7 +23,7 @@ class APSInt : public APInt { bool IsUnsigned; public: /// Default constructor that creates an uninitialized APInt. - explicit APSInt() {} + explicit APSInt() : IsUnsigned(false) {} /// APSInt ctor - Create an APSInt with the specified width, default to /// unsigned. @@ -161,11 +161,11 @@ public: } APSInt& operator++() { - static_cast<APInt&>(*this)++; + ++(static_cast<APInt&>(*this)); return *this; } APSInt& operator--() { - static_cast<APInt&>(*this)--; + --(static_cast<APInt&>(*this)); return *this; } APSInt operator++(int) { diff --git a/contrib/llvm/include/llvm/ADT/ArrayRef.h b/contrib/llvm/include/llvm/ADT/ArrayRef.h index 1e35d62..c555c1c 100644 --- a/contrib/llvm/include/llvm/ADT/ArrayRef.h +++ b/contrib/llvm/include/llvm/ADT/ArrayRef.h @@ -33,6 +33,8 @@ namespace llvm { typedef const T *const_iterator; typedef size_t size_type; + typedef std::reverse_iterator<iterator> reverse_iterator; + private: /// The start of the array, in an external buffer. const T *Data; @@ -84,6 +86,9 @@ namespace llvm { iterator begin() const { return Data; } iterator end() const { return Data + Length; } + reverse_iterator rbegin() const { return reverse_iterator(end()); } + reverse_iterator rend() const { return reverse_iterator(begin()); } + /// empty - Check if the array is empty. bool empty() const { return Length == 0; } @@ -171,41 +176,41 @@ namespace llvm { /// Construct an empty ArrayRef. /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} - + /// Construct an MutableArrayRef from a single element. /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} - + /// Construct an MutableArrayRef from a pointer and length. /*implicit*/ MutableArrayRef(T *data, size_t length) : ArrayRef<T>(data, length) {} - + /// Construct an MutableArrayRef from a range. MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {} - + /// Construct an MutableArrayRef from a SmallVector. /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec) : ArrayRef<T>(Vec) {} - + /// Construct a MutableArrayRef from a std::vector. /*implicit*/ MutableArrayRef(std::vector<T> &Vec) : ArrayRef<T>(Vec) {} - + /// Construct an MutableArrayRef from a C array. template <size_t N> /*implicit*/ MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {} - + T *data() const { return const_cast<T*>(ArrayRef<T>::data()); } iterator begin() const { return data(); } iterator end() const { return data() + this->size(); } - + /// front - Get the first element. T &front() const { assert(!this->empty()); return data()[0]; } - + /// back - Get the last element. T &back() const { assert(!this->empty()); @@ -217,14 +222,14 @@ namespace llvm { assert(N <= this->size() && "Invalid specifier"); return MutableArrayRef<T>(data()+N, this->size()-N); } - + /// slice(n, m) - Chop off the first N elements of the array, and keep M /// elements in the array. MutableArrayRef<T> slice(unsigned N, unsigned M) const { assert(N+M <= this->size() && "Invalid specifier"); return MutableArrayRef<T>(data()+N, M); } - + /// @} /// @name Operator Overloads /// @{ @@ -301,5 +306,5 @@ namespace llvm { static const bool value = true; }; } - + #endif diff --git a/contrib/llvm/include/llvm/ADT/BitVector.h b/contrib/llvm/include/llvm/ADT/BitVector.h index 9d6388f..82cfdf4 100644 --- a/contrib/llvm/include/llvm/ADT/BitVector.h +++ b/contrib/llvm/include/llvm/ADT/BitVector.h @@ -98,7 +98,7 @@ public: std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord)); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES BitVector(BitVector &&RHS) : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) { RHS.Bits = 0; @@ -452,7 +452,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES const BitVector &operator=(BitVector &&RHS) { if (this == &RHS) return *this; diff --git a/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h index 2dfed07..3dd862c 100644 --- a/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h +++ b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h @@ -9,8 +9,8 @@ #ifndef LLVM_ADT_DAGDELTAALGORITHM_H #define LLVM_ADT_DAGDELTAALGORITHM_H -#include <vector> #include <set> +#include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h index 7bf7960..4d07e04 100644 --- a/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h +++ b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h @@ -9,8 +9,8 @@ #ifndef LLVM_ADT_DELTAALGORITHM_H #define LLVM_ADT_DELTAALGORITHM_H -#include <vector> #include <set> +#include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/ADT/DenseMap.h b/contrib/llvm/include/llvm/ADT/DenseMap.h index ac4bdbd..d410619 100644 --- a/contrib/llvm/include/llvm/ADT/DenseMap.h +++ b/contrib/llvm/include/llvm/ADT/DenseMap.h @@ -14,20 +14,20 @@ #ifndef LLVM_ADT_DENSEMAP_H #define LLVM_ADT_DENSEMAP_H -#include "llvm/Support/Compiler.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/AlignOf.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/type_traits.h" -#include "llvm/ADT/DenseMapInfo.h" #include <algorithm> -#include <iterator> -#include <new> -#include <utility> #include <cassert> #include <climits> #include <cstddef> #include <cstring> +#include <iterator> +#include <new> +#include <utility> namespace llvm { @@ -75,7 +75,7 @@ public: void clear() { if (getNumEntries() == 0 && getNumTombstones() == 0) return; - + // If the capacity of the array is huge, and the # elements used is small, // shrink the array. if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) { @@ -159,6 +159,24 @@ public: return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); } +#if LLVM_HAS_RVALUE_REFERENCES + // Inserts key,value pair into the map if the key isn't already in the map. + // If the key is already in the map, it returns false and doesn't update the + // value. + std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) { + BucketT *TheBucket; + if (LookupBucketFor(KV.first, TheBucket)) + return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), + false); // Already in map. + + // Otherwise, insert the new element. + TheBucket = InsertIntoBucket(std::move(KV.first), + std::move(KV.second), + TheBucket); + return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); + } +#endif + /// insert - Range insertion of pairs. template<typename InputIt> void insert(InputIt I, InputIt E) { @@ -198,7 +216,7 @@ public: return FindAndConstruct(Key).second; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES value_type& FindAndConstruct(KeyT &&Key) { BucketT *TheBucket; if (LookupBucketFor(Key, TheBucket)) @@ -383,7 +401,7 @@ private: return TheBucket; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, BucketT *TheBucket) { TheBucket = InsertIntoBucketImpl(Key, TheBucket); @@ -430,7 +448,8 @@ private: incrementNumEntries(); // If we are writing over a tombstone, remember this. - if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) + const KeyT EmptyKey = getEmptyKey(); + if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey)) decrementNumTombstones(); return TheBucket; @@ -474,7 +493,6 @@ private: if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) { // If we've already seen a tombstone while probing, fill it in instead // of the empty bucket we eventually probed to. - if (FoundTombstone) ThisBucket = FoundTombstone; FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; return false; } @@ -531,13 +549,13 @@ public: init(NumInitBuckets); } - DenseMap(const DenseMap &other) { + DenseMap(const DenseMap &other) : BaseT() { init(0); copyFrom(other); } -#if LLVM_USE_RVALUE_REFERENCES - DenseMap(DenseMap &&other) { +#if LLVM_HAS_RVALUE_REFERENCES + DenseMap(DenseMap &&other) : BaseT() { init(0); swap(other); } @@ -566,7 +584,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES DenseMap& operator=(DenseMap &&other) { this->destroyAll(); operator delete(Buckets); @@ -700,7 +718,7 @@ public: copyFrom(other); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap(SmallDenseMap &&other) { init(0); swap(other); @@ -795,7 +813,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallDenseMap& operator=(SmallDenseMap &&other) { this->destroyAll(); deallocateBuckets(); @@ -1027,7 +1045,7 @@ private: ++Ptr; } }; - + template<typename KeyT, typename ValueT, typename KeyInfoT> static inline size_t capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) { diff --git a/contrib/llvm/include/llvm/ADT/DenseSet.h b/contrib/llvm/include/llvm/ADT/DenseSet.h index 8ab9a33..d699ad5 100644 --- a/contrib/llvm/include/llvm/ADT/DenseSet.h +++ b/contrib/llvm/include/llvm/ADT/DenseSet.h @@ -32,8 +32,10 @@ public: bool empty() const { return TheMap.empty(); } unsigned size() const { return TheMap.size(); } + size_t getMemorySize() const { return TheMap.getMemorySize(); } - /// Grow the denseset so that it has at least Size buckets. Does not shrink + /// Grow the DenseSet so that it has at least Size buckets. Will not shrink + /// the Size of the set. void resize(size_t Size) { TheMap.resize(Size); } void clear() { diff --git a/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h index 519b180..6445442 100644 --- a/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h +++ b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h @@ -34,8 +34,8 @@ #define LLVM_ADT_DEPTHFIRSTITERATOR_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" #include <set> #include <vector> diff --git a/contrib/llvm/include/llvm/ADT/FoldingSet.h b/contrib/llvm/include/llvm/ADT/FoldingSet.h index 375d84a..91794de 100644 --- a/contrib/llvm/include/llvm/ADT/FoldingSet.h +++ b/contrib/llvm/include/llvm/ADT/FoldingSet.h @@ -16,9 +16,9 @@ #ifndef LLVM_ADT_FOLDINGSET_H #define LLVM_ADT_FOLDINGSET_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class APFloat; diff --git a/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h b/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h index fa7ccb9..6793c6b 100644 --- a/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h +++ b/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H -#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H +#ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H +#define LLVM_ADT_IMMUTABLEINTERVALMAP_H #include "llvm/ADT/ImmutableMap.h" diff --git a/contrib/llvm/include/llvm/ADT/ImmutableList.h b/contrib/llvm/include/llvm/ADT/ImmutableList.h index 20bdd90..7f0c239 100644 --- a/contrib/llvm/include/llvm/ADT/ImmutableList.h +++ b/contrib/llvm/include/llvm/ADT/ImmutableList.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_IMLIST_H -#define LLVM_ADT_IMLIST_H +#ifndef LLVM_ADT_IMMUTABLELIST_H +#define LLVM_ADT_IMMUTABLELIST_H -#include "llvm/Support/Allocator.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" #include <cassert> diff --git a/contrib/llvm/include/llvm/ADT/ImmutableMap.h b/contrib/llvm/include/llvm/ADT/ImmutableMap.h index 4883c5b..a667479 100644 --- a/contrib/llvm/include/llvm/ADT/ImmutableMap.h +++ b/contrib/llvm/include/llvm/ADT/ImmutableMap.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_IMMAP_H -#define LLVM_ADT_IMMAP_H +#ifndef LLVM_ADT_IMMUTABLEMAP_H +#define LLVM_ADT_IMMUTABLEMAP_H #include "llvm/ADT/ImmutableSet.h" @@ -211,17 +211,22 @@ public: friend class ImmutableMap; public: - value_type_ref operator*() const { return itr->getValue(); } - value_type* operator->() const { return &itr->getValue(); } + typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type; + typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference; + typedef typename iterator::value_type *pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + typename iterator::reference operator*() const { return itr->getValue(); } + typename iterator::pointer operator->() const { return &itr->getValue(); } key_type_ref getKey() const { return itr->getValue().first; } data_type_ref getData() const { return itr->getValue().second; } - iterator& operator++() { ++itr; return *this; } iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } iterator& operator--() { --itr; return *this; } iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } + bool operator==(const iterator& RHS) const { return RHS.itr == itr; } bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } }; @@ -288,6 +293,13 @@ public: Factory(F) { if (Root) { Root->retain(); } } + + explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X, + typename ImmutableMap<KeyT, ValT>::Factory &F) + : Root(X.getRootWithoutRetain()), + Factory(F.getTreeFactory()) { + if (Root) { Root->retain(); } + } ImmutableMapRef(const ImmutableMapRef &X) : Root(X.Root), @@ -318,12 +330,20 @@ public: return ImmutableMapRef(0, F); } - ImmutableMapRef add(key_type_ref K, data_type_ref D) { + void manualRetain() { + if (Root) Root->retain(); + } + + void manualRelease() { + if (Root) Root->release(); + } + + ImmutableMapRef add(key_type_ref K, data_type_ref D) const { TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D)); return ImmutableMapRef(NewT, Factory); } - ImmutableMapRef remove(key_type_ref K) { + ImmutableMapRef remove(key_type_ref K) const { TreeTy *NewT = Factory->remove(Root, K); return ImmutableMapRef(NewT, Factory); } diff --git a/contrib/llvm/include/llvm/ADT/ImmutableSet.h b/contrib/llvm/include/llvm/ADT/ImmutableSet.h index 3900f96..fbdf066 100644 --- a/contrib/llvm/include/llvm/ADT/ImmutableSet.h +++ b/contrib/llvm/include/llvm/ADT/ImmutableSet.h @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_IMSET_H -#define LLVM_ADT_IMSET_H +#ifndef LLVM_ADT_IMMUTABLESET_H +#define LLVM_ADT_IMMUTABLESET_H -#include "llvm/Support/Allocator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> @@ -1054,18 +1054,27 @@ public: class iterator { typename TreeTy::iterator itr; + + iterator() {} iterator(TreeTy* t) : itr(t) {} friend class ImmutableSet<ValT,ValInfo>; + public: - iterator() {} - inline value_type_ref operator*() const { return itr->getValue(); } - inline iterator& operator++() { ++itr; return *this; } - inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } - inline iterator& operator--() { --itr; return *this; } - inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } - inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; } - inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } - inline value_type *operator->() const { return &(operator*()); } + typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; + typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; + typedef typename iterator::value_type *pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + typename iterator::reference operator*() const { return itr->getValue(); } + typename iterator::pointer operator->() const { return &(operator*()); } + + iterator& operator++() { ++itr; return *this; } + iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } + iterator& operator--() { --itr; return *this; } + iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } + + bool operator==(const iterator& RHS) const { return RHS.itr == itr; } + bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } }; iterator begin() const { return iterator(Root); } diff --git a/contrib/llvm/include/llvm/ADT/IntervalMap.h b/contrib/llvm/include/llvm/ADT/IntervalMap.h index 931b67e..c4083ee 100644 --- a/contrib/llvm/include/llvm/ADT/IntervalMap.h +++ b/contrib/llvm/include/llvm/ADT/IntervalMap.h @@ -99,8 +99,8 @@ #ifndef LLVM_ADT_INTERVALMAP_H #define LLVM_ADT_INTERVALMAP_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/RecyclingAllocator.h" #include <iterator> @@ -151,6 +151,26 @@ struct IntervalMapInfo { }; +template <typename T> +struct IntervalMapHalfOpenInfo { + + /// startLess - Return true if x is not in [a;b). + static inline bool startLess(const T &x, const T &a) { + return x < a; + } + + /// stopLess - Return true if x is not in [a;b). + static inline bool stopLess(const T &b, const T &x) { + return b <= x; + } + + /// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce. + static inline bool adjacent(const T &a, const T &b) { + return a == b; + } + +}; + /// IntervalMapImpl - Namespace used for IntervalMap implementation details. /// It should be considered private to the implementation. namespace IntervalMapImpl { diff --git a/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h index a9724ee..b8b8861 100644 --- a/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -18,8 +18,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR -#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR +#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H +#define LLVM_ADT_INTRUSIVEREFCNTPTR_H #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -123,7 +123,7 @@ namespace llvm { retain(); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { S.Obj = 0; } @@ -226,13 +226,13 @@ namespace llvm { template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > { typedef T* SimpleType; - static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) { + static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) { return Val.getPtr(); } }; template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > { - typedef T* SimpleType; + typedef /*const*/ T* SimpleType; static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) { return Val.getPtr(); } @@ -240,4 +240,4 @@ namespace llvm { } // end namespace llvm -#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR +#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H diff --git a/contrib/llvm/include/llvm/ADT/MapVector.h b/contrib/llvm/include/llvm/ADT/MapVector.h index 6aacca5..f6fcb08 100644 --- a/contrib/llvm/include/llvm/ADT/MapVector.h +++ b/contrib/llvm/include/llvm/ADT/MapVector.h @@ -19,6 +19,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include <vector> namespace llvm { @@ -63,6 +64,11 @@ public: return Vector.empty(); } + std::pair<KeyT, ValueT> &front() { return Vector.front(); } + const std::pair<KeyT, ValueT> &front() const { return Vector.front(); } + std::pair<KeyT, ValueT> &back() { return Vector.back(); } + const std::pair<KeyT, ValueT> &back() const { return Vector.back(); } + void clear() { Map.clear(); Vector.clear(); @@ -79,10 +85,46 @@ public: return Vector[I].second; } + ValueT lookup(const KeyT &Key) const { + typename MapType::const_iterator Pos = Map.find(Key); + return Pos == Map.end()? ValueT() : Vector[Pos->second].second; + } + + std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { + std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0); + std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); + unsigned &I = Result.first->second; + if (Result.second) { + Vector.push_back(std::make_pair(KV.first, KV.second)); + I = Vector.size() - 1; + return std::make_pair(llvm::prior(end()), true); + } + return std::make_pair(begin() + I, false); + } + unsigned count(const KeyT &Key) const { typename MapType::const_iterator Pos = Map.find(Key); return Pos == Map.end()? 0 : 1; } + + iterator find(const KeyT &Key) { + typename MapType::const_iterator Pos = Map.find(Key); + return Pos == Map.end()? Vector.end() : + (Vector.begin() + Pos->second); + } + + const_iterator find(const KeyT &Key) const { + typename MapType::const_iterator Pos = Map.find(Key); + return Pos == Map.end()? Vector.end() : + (Vector.begin() + Pos->second); + } + + /// \brief Remove the last element from the vector. + void pop_back() { + typename MapType::iterator Pos = Map.find(Vector.back().first); + Map.erase(Pos); + Vector.pop_back(); + } }; } diff --git a/contrib/llvm/include/llvm/ADT/None.h b/contrib/llvm/include/llvm/ADT/None.h new file mode 100644 index 0000000..5793bd2 --- /dev/null +++ b/contrib/llvm/include/llvm/ADT/None.h @@ -0,0 +1,27 @@ +//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides None, an enumerator for use in implicit constructors +// of various (usually templated) types to make such construction more +// terse. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_NONE_H +#define LLVM_ADT_NONE_H + +namespace llvm { +/// \brief A simple null object to allow implicit construction of Optional<T> +/// and similar types without having to spell out the specialization's name. +enum NoneType { + None +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/ADT/NullablePtr.h b/contrib/llvm/include/llvm/ADT/NullablePtr.h index a9c47a1..8ddfd5d 100644 --- a/contrib/llvm/include/llvm/ADT/NullablePtr.h +++ b/contrib/llvm/include/llvm/ADT/NullablePtr.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_NULLABLE_PTR_H -#define LLVM_ADT_NULLABLE_PTR_H +#ifndef LLVM_ADT_NULLABLEPTR_H +#define LLVM_ADT_NULLABLEPTR_H #include <cassert> #include <cstddef> diff --git a/contrib/llvm/include/llvm/ADT/Optional.h b/contrib/llvm/include/llvm/ADT/Optional.h index f43aeb1..194e53f 100644 --- a/contrib/llvm/include/llvm/ADT/Optional.h +++ b/contrib/llvm/include/llvm/ADT/Optional.h @@ -13,13 +13,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_OPTIONAL -#define LLVM_ADT_OPTIONAL +#ifndef LLVM_ADT_OPTIONAL_H +#define LLVM_ADT_OPTIONAL_H +#include "llvm/ADT/None.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/AlignOf.h" #include <cassert> -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES #include <utility> #endif @@ -27,54 +29,116 @@ namespace llvm { template<typename T> class Optional { - T x; - unsigned hasVal : 1; + AlignedCharArrayUnion<T> storage; + bool hasVal; public: - explicit Optional() : x(), hasVal(false) {} - Optional(const T &y) : x(y), hasVal(true) {} + Optional(NoneType) : hasVal(false) {} + explicit Optional() : hasVal(false) {} + Optional(const T &y) : hasVal(true) { + new (storage.buffer) T(y); + } + Optional(const Optional &O) : hasVal(O.hasVal) { + if (hasVal) + new (storage.buffer) T(*O); + } -#if LLVM_USE_RVALUE_REFERENCES - Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {} +#if LLVM_HAS_RVALUE_REFERENCES + Optional(T &&y) : hasVal(true) { + new (storage.buffer) T(std::forward<T>(y)); + } + Optional(Optional<T> &&O) : hasVal(O) { + if (O) { + new (storage.buffer) T(std::move(*O)); + O.reset(); + } + } + Optional &operator=(T &&y) { + if (hasVal) + **this = std::move(y); + else { + new (storage.buffer) T(std::move(y)); + hasVal = true; + } + return *this; + } + Optional &operator=(Optional &&O) { + if (!O) + reset(); + else { + *this = std::move(*O); + O.reset(); + } + return *this; + } #endif static inline Optional create(const T* y) { return y ? Optional(*y) : Optional(); } + // FIXME: these assignments (& the equivalent const T&/const Optional& ctors) + // could be made more efficient by passing by value, possibly unifying them + // with the rvalue versions above - but this could place a different set of + // requirements (notably: the existence of a default ctor) when implemented + // in that way. Careful SFINAE to avoid such pitfalls would be required. Optional &operator=(const T &y) { - x = y; - hasVal = true; + if (hasVal) + **this = y; + else { + new (storage.buffer) T(y); + hasVal = true; + } return *this; } - - const T* getPointer() const { assert(hasVal); return &x; } - const T& getValue() const { assert(hasVal); return x; } - operator bool() const { return hasVal; } - bool hasValue() const { return hasVal; } - const T* operator->() const { return getPointer(); } - const T& operator*() const { assert(hasVal); return x; } -}; + Optional &operator=(const Optional &O) { + if (!O) + reset(); + else + *this = *O; + return *this; + } -template<typename T> struct simplify_type; + void reset() { + if (hasVal) { + (**this).~T(); + hasVal = false; + } + } -template <typename T> -struct simplify_type<const Optional<T> > { - typedef const T* SimpleType; - static SimpleType getSimplifiedValue(const Optional<T> &Val) { - return Val.getPointer(); + ~Optional() { + reset(); } + + const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); } + T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); } + const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + + LLVM_EXPLICIT operator bool() const { return hasVal; } + bool hasValue() const { return hasVal; } + const T* operator->() const { return getPointer(); } + T* operator->() { return getPointer(); } + const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + +#if LLVM_HAS_RVALUE_REFERENCE_THIS + T&& getValue() && { assert(hasVal); return std::move(*getPointer()); } + T&& operator*() && { assert(hasVal); return std::move(*getPointer()); } +#endif }; -template <typename T> -struct simplify_type<Optional<T> > - : public simplify_type<const Optional<T> > {}; +template <typename T> struct isPodLike; +template <typename T> struct isPodLike<Optional<T> > { + // An Optional<T> is pod-like if T is. + static const bool value = isPodLike<T>::value; +}; /// \brief Poison comparison between two \c Optional objects. Clients needs to /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator==(const Optional<T> &X, const Optional<U> &Y); @@ -83,7 +147,7 @@ void operator==(const Optional<T> &X, const Optional<U> &Y); /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator!=(const Optional<T> &X, const Optional<U> &Y); @@ -92,7 +156,7 @@ void operator!=(const Optional<T> &X, const Optional<U> &Y); /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator<(const Optional<T> &X, const Optional<U> &Y); @@ -101,7 +165,7 @@ void operator<(const Optional<T> &X, const Optional<U> &Y); /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator<=(const Optional<T> &X, const Optional<U> &Y); @@ -110,7 +174,7 @@ void operator<=(const Optional<T> &X, const Optional<U> &Y); /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator>=(const Optional<T> &X, const Optional<U> &Y); @@ -119,7 +183,7 @@ void operator>=(const Optional<T> &X, const Optional<U> &Y); /// explicitly compare the underlying values and account for empty \c Optional /// objects. /// -/// This routine will never be defined. It returns \c void to help diagnose +/// This routine will never be defined. It returns \c void to help diagnose /// errors at compile time. template<typename T, typename U> void operator>(const Optional<T> &X, const Optional<U> &Y); diff --git a/contrib/llvm/include/llvm/ADT/OwningPtr.h b/contrib/llvm/include/llvm/ADT/OwningPtr.h index 05bcd40..86f9fee 100644 --- a/contrib/llvm/include/llvm/ADT/OwningPtr.h +++ b/contrib/llvm/include/llvm/ADT/OwningPtr.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_OWNING_PTR_H -#define LLVM_ADT_OWNING_PTR_H +#ifndef LLVM_ADT_OWNINGPTR_H +#define LLVM_ADT_OWNINGPTR_H #include "llvm/Support/Compiler.h" #include <cassert> @@ -32,7 +32,7 @@ class OwningPtr { public: explicit OwningPtr(T *P = 0) : Ptr(P) {} -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} OwningPtr &operator=(OwningPtr &&Other) { @@ -95,7 +95,7 @@ class OwningArrayPtr { public: explicit OwningArrayPtr(T *P = 0) : Ptr(P) {} -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {} OwningArrayPtr &operator=(OwningArrayPtr &&Other) { diff --git a/contrib/llvm/include/llvm/ADT/PointerIntPair.h b/contrib/llvm/include/llvm/ADT/PointerIntPair.h index 71c379b..cce2efb 100644 --- a/contrib/llvm/include/llvm/ADT/PointerIntPair.h +++ b/contrib/llvm/include/llvm/ADT/PointerIntPair.h @@ -57,11 +57,13 @@ class PointerIntPair { }; public: PointerIntPair() : Value(0) {} - PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { + PointerIntPair(PointerTy Ptr, IntType Int) { assert(IntBits <= PtrTraits::NumLowBitsAvailable && "PointerIntPair formed with integer size too large for pointer"); - setPointer(Ptr); - setInt(Int); + setPointerAndInt(Ptr, Int); + } + explicit PointerIntPair(PointerTy Ptr) { + initWithPointer(Ptr); } PointerTy getPointer() const { @@ -91,6 +93,25 @@ public: Value |= IntVal << IntShift; // Set new integer. } + void initWithPointer(PointerTy Ptr) { + intptr_t PtrVal + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); + assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + Value = PtrVal; + } + + void setPointerAndInt(PointerTy Ptr, IntType Int) { + intptr_t PtrVal + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); + assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + intptr_t IntVal = Int; + assert(IntVal < (1 << IntBits) && "Integer too large for field"); + + Value = PtrVal | (IntVal << IntShift); + } + PointerTy const *getAddrOfPointer() const { return const_cast<PointerIntPair *>(this)->getAddrOfPointer(); } diff --git a/contrib/llvm/include/llvm/ADT/PointerUnion.h b/contrib/llvm/include/llvm/ADT/PointerUnion.h index a9e86d2..f42515a 100644 --- a/contrib/llvm/include/llvm/ADT/PointerUnion.h +++ b/contrib/llvm/include/llvm/ADT/PointerUnion.h @@ -95,15 +95,11 @@ namespace llvm { public: PointerUnion() {} - PointerUnion(PT1 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))); - Val.setInt(0); + PointerUnion(PT1 V) : Val( + const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) { } - PointerUnion(PT2 V) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V))); - Val.setInt(1); + PointerUnion(PT2 V) : Val( + const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) { } /// isNull - Return true if the pointer held in the union is null, @@ -160,15 +156,14 @@ namespace llvm { /// Assignment operators - Allow assigning into this union from either /// pointer type, setting the discriminator to remember what it came from. const PointerUnion &operator=(const PT1 &RHS) { - Val.setPointer( + Val.initWithPointer( const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS))); - Val.setInt(0); return *this; } const PointerUnion &operator=(const PT2 &RHS) { - Val.setPointer( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS))); - Val.setInt(1); + Val.setPointerAndInt( + const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)), + 1); return *this; } diff --git a/contrib/llvm/include/llvm/ADT/PostOrderIterator.h b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h index 7f6350e..59fa3f3 100644 --- a/contrib/llvm/include/llvm/ADT/PostOrderIterator.h +++ b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h @@ -260,7 +260,7 @@ class ReversePostOrderTraversal { typedef typename GT::NodeType NodeType; std::vector<NodeType*> Blocks; // Block list in normal PO order inline void Initialize(NodeType *BB) { - copy(po_begin(BB), po_end(BB), back_inserter(Blocks)); + std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks)); } public: typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator; diff --git a/contrib/llvm/include/llvm/ADT/PriorityQueue.h b/contrib/llvm/include/llvm/ADT/PriorityQueue.h index bf8a687..827d0b3 100644 --- a/contrib/llvm/include/llvm/ADT/PriorityQueue.h +++ b/contrib/llvm/include/llvm/ADT/PriorityQueue.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_PRIORITY_QUEUE_H -#define LLVM_ADT_PRIORITY_QUEUE_H +#ifndef LLVM_ADT_PRIORITYQUEUE_H +#define LLVM_ADT_PRIORITYQUEUE_H #include <algorithm> #include <queue> diff --git a/contrib/llvm/include/llvm/ADT/SCCIterator.h b/contrib/llvm/include/llvm/ADT/SCCIterator.h index 48436c6..8ce4fd5 100644 --- a/contrib/llvm/include/llvm/ADT/SCCIterator.h +++ b/contrib/llvm/include/llvm/ADT/SCCIterator.h @@ -21,8 +21,8 @@ #ifndef LLVM_ADT_SCCITERATOR_H #define LLVM_ADT_SCCITERATOR_H -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" #include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/ADT/STLExtras.h b/contrib/llvm/include/llvm/ADT/STLExtras.h index aee500d..dacda36 100644 --- a/contrib/llvm/include/llvm/ADT/STLExtras.h +++ b/contrib/llvm/include/llvm/ADT/STLExtras.h @@ -246,10 +246,10 @@ inline int array_pod_sort_comparator(const void *P1, const void *P2) { return 0; } -/// get_array_pad_sort_comparator - This is an internal helper function used to +/// get_array_pod_sort_comparator - This is an internal helper function used to /// get type deduction of T right. template<typename T> -inline int (*get_array_pad_sort_comparator(const T &)) +inline int (*get_array_pod_sort_comparator(const T &)) (const void*, const void*) { return array_pod_sort_comparator<T>; } @@ -274,7 +274,7 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) { // Don't dereference start iterator of empty sequence. if (Start == End) return; qsort(&*Start, End-Start, sizeof(*Start), - get_array_pad_sort_comparator(*Start)); + get_array_pod_sort_comparator(*Start)); } template<class IteratorTy> diff --git a/contrib/llvm/include/llvm/ADT/SmallBitVector.h b/contrib/llvm/include/llvm/ADT/SmallBitVector.h index a9cd54e..652492a 100644 --- a/contrib/llvm/include/llvm/ADT/SmallBitVector.h +++ b/contrib/llvm/include/llvm/ADT/SmallBitVector.h @@ -153,7 +153,7 @@ public: switchToLarge(new BitVector(*RHS.getPointer())); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { RHS.X = 1; } @@ -178,9 +178,9 @@ public: unsigned count() const { if (isSmall()) { uintptr_t Bits = getSmallBits(); - if (sizeof(uintptr_t) * CHAR_BIT == 32) + if (NumBaseBits == 32) return CountPopulation_32(Bits); - if (sizeof(uintptr_t) * CHAR_BIT == 64) + if (NumBaseBits == 64) return CountPopulation_64(Bits); llvm_unreachable("Unsupported!"); } @@ -215,9 +215,9 @@ public: uintptr_t Bits = getSmallBits(); if (Bits == 0) return -1; - if (sizeof(uintptr_t) * CHAR_BIT == 32) + if (NumBaseBits == 32) return CountTrailingZeros_32(Bits); - if (sizeof(uintptr_t) * CHAR_BIT == 64) + if (NumBaseBits == 64) return CountTrailingZeros_64(Bits); llvm_unreachable("Unsupported!"); } @@ -233,9 +233,9 @@ public: Bits &= ~uintptr_t(0) << (Prev + 1); if (Bits == 0 || Prev + 1 >= getSmallSize()) return -1; - if (sizeof(uintptr_t) * CHAR_BIT == 32) + if (NumBaseBits == 32) return CountTrailingZeros_32(Bits); - if (sizeof(uintptr_t) * CHAR_BIT == 64) + if (NumBaseBits == 64) return CountTrailingZeros_64(Bits); llvm_unreachable("Unsupported!"); } @@ -472,7 +472,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES const SmallBitVector &operator=(SmallBitVector &&RHS) { if (this != &RHS) { clear(); diff --git a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h index 3bb8830..8c73041 100644 --- a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h +++ b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h @@ -54,8 +54,6 @@ protected: /// then the set is in 'small mode'. const void **CurArray; /// CurArraySize - The allocated size of CurArray, always a power of two. - /// Note that CurArray points to an array that has CurArraySize+1 elements in - /// it, so that the end iterator actually points to valid memory. unsigned CurArraySize; // If small, this is # elts allocated consecutively @@ -68,9 +66,6 @@ protected: SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) { assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 && "Initial size must be a power of two!"); - // The end pointer, always valid, is set to a valid element to help the - // iterator. - CurArray[SmallSize] = 0; clear(); } ~SmallPtrSetImpl(); @@ -147,9 +142,11 @@ protected: class SmallPtrSetIteratorImpl { protected: const void *const *Bucket; + const void *const *End; public: - explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) { - AdvanceIfNotValid(); + explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E) + : Bucket(BP), End(E) { + AdvanceIfNotValid(); } bool operator==(const SmallPtrSetIteratorImpl &RHS) const { @@ -164,8 +161,10 @@ protected: /// that is. This is guaranteed to stop because the end() bucket is marked /// valid. void AdvanceIfNotValid() { - while (*Bucket == SmallPtrSetImpl::getEmptyMarker() || - *Bucket == SmallPtrSetImpl::getTombstoneMarker()) + assert(Bucket <= End); + while (Bucket != End && + (*Bucket == SmallPtrSetImpl::getEmptyMarker() || + *Bucket == SmallPtrSetImpl::getTombstoneMarker())) ++Bucket; } }; @@ -182,12 +181,13 @@ public: typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; - explicit SmallPtrSetIterator(const void *const *BP) - : SmallPtrSetIteratorImpl(BP) {} + explicit SmallPtrSetIterator(const void *const *BP, const void *const *E) + : SmallPtrSetIteratorImpl(BP, E) {} // Most methods provided by baseclass. const PtrTy operator*() const { + assert(Bucket < End); return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket)); } @@ -236,9 +236,8 @@ template<class PtrType, unsigned SmallSize> class SmallPtrSet : public SmallPtrSetImpl { // Make sure that SmallSize is a power of two, round up if not. enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val }; - /// SmallStorage - Fixed size storage used in 'small mode'. The extra element - /// ensures that the end iterator actually points to valid memory. - const void *SmallStorage[SmallSizePowTwo+1]; + /// SmallStorage - Fixed size storage used in 'small mode'. + const void *SmallStorage[SmallSizePowTwo]; typedef PointerLikeTypeTraits<PtrType> PtrTraits; public: SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {} @@ -275,10 +274,10 @@ public: typedef SmallPtrSetIterator<PtrType> iterator; typedef SmallPtrSetIterator<PtrType> const_iterator; inline iterator begin() const { - return iterator(CurArray); + return iterator(CurArray, CurArray+CurArraySize); } inline iterator end() const { - return iterator(CurArray+CurArraySize); + return iterator(CurArray+CurArraySize, CurArray+CurArraySize); } // Allow assignment from any smallptrset with the same element type even if it diff --git a/contrib/llvm/include/llvm/ADT/SmallSet.h b/contrib/llvm/include/llvm/ADT/SmallSet.h index cd117f5..5dfe924 100644 --- a/contrib/llvm/include/llvm/ADT/SmallSet.h +++ b/contrib/llvm/include/llvm/ADT/SmallSet.h @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_SMALLSET_H #define LLVM_ADT_SMALLSET_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include <set> namespace llvm { @@ -55,6 +55,7 @@ public: } /// insert - Insert an element into the set if it isn't already there. + /// Returns true if the element is inserted (it was not in the set before). bool insert(const T &V) { if (!isSmall()) return Set.insert(V).second; diff --git a/contrib/llvm/include/llvm/ADT/SmallString.h b/contrib/llvm/include/llvm/ADT/SmallString.h index 8da99d1..2cfb5b9 100644 --- a/contrib/llvm/include/llvm/ADT/SmallString.h +++ b/contrib/llvm/include/llvm/ADT/SmallString.h @@ -77,7 +77,7 @@ public: void append(in_iter S, in_iter E) { SmallVectorImpl<char>::append(S, E); } - + void append(size_t NumInputs, char Elt) { SmallVectorImpl<char>::append(NumInputs, Elt); } diff --git a/contrib/llvm/include/llvm/ADT/SmallVector.h b/contrib/llvm/include/llvm/ADT/SmallVector.h index 6e0fd94..7ba0a71 100644 --- a/contrib/llvm/include/llvm/ADT/SmallVector.h +++ b/contrib/llvm/include/llvm/ADT/SmallVector.h @@ -16,6 +16,7 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/type_traits.h" #include <algorithm> #include <cassert> @@ -145,16 +146,20 @@ public: } reference front() { + assert(!empty()); return begin()[0]; } const_reference front() const { + assert(!empty()); return begin()[0]; } reference back() { + assert(!empty()); return end()[-1]; } const_reference back() const { + assert(!empty()); return end()[-1]; } }; @@ -178,7 +183,7 @@ protected: /// std::move, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) *Dest = ::std::move(*I); return Dest; @@ -193,7 +198,7 @@ protected: /// std::move_backward, but not all stdlibs actually provide that. template<typename It1, typename It2> static It2 move_backward(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES while (I != E) *--Dest = ::std::move(*--E); return Dest; @@ -206,7 +211,7 @@ protected: /// memory starting with "Dest", constructing elements as needed. template<typename It1, typename It2> static void uninitialized_move(It1 I, It1 E, It2 Dest) { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES for (; I != E; ++I, ++Dest) ::new ((void*) &*Dest) T(::std::move(*I)); #else @@ -239,7 +244,7 @@ public: goto Retry; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES void push_back(T &&Elt) { if (this->EndX < this->CapacityX) { Retry: @@ -263,7 +268,8 @@ template <typename T, bool isPodLike> void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { size_t CurCapacity = this->capacity(); size_t CurSize = this->size(); - size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero. + // Always grow, even from zero. + size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2)); if (NewCapacity < MinSize) NewCapacity = MinSize; T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T))); @@ -365,7 +371,7 @@ template <typename T> class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> { typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass; - SmallVectorImpl(const SmallVectorImpl&); // DISABLED. + SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION; public: typedef typename SuperClass::iterator iterator; typedef typename SuperClass::size_type size_type; @@ -422,7 +428,7 @@ public: } T pop_back_val() { -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES T Result = ::std::move(this->back()); #else T Result = this->back(); @@ -495,7 +501,7 @@ public: return(N); } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES iterator insert(iterator I, T &&Elt) { if (I == this->end()) { // Important special case for empty vector. this->push_back(::std::move(Elt)); @@ -667,7 +673,7 @@ public: SmallVectorImpl &operator=(const SmallVectorImpl &RHS); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallVectorImpl &operator=(SmallVectorImpl &&RHS); #endif @@ -787,7 +793,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>:: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES template <typename T> SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { // Avoid self-assignment. @@ -898,7 +904,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS)); diff --git a/contrib/llvm/include/llvm/ADT/SparseMultiSet.h b/contrib/llvm/include/llvm/ADT/SparseMultiSet.h new file mode 100644 index 0000000..7f2a6f7 --- /dev/null +++ b/contrib/llvm/include/llvm/ADT/SparseMultiSet.h @@ -0,0 +1,526 @@ +//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the SparseMultiSet class, which adds multiset behavior to +// the SparseSet. +// +// A sparse multiset holds a small number of objects identified by integer keys +// from a moderately sized universe. The sparse multiset uses more memory than +// other containers in order to provide faster operations. Any key can map to +// multiple values. A SparseMultiSetNode class is provided, which serves as a +// convenient base class for the contents of a SparseMultiSet. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_SPARSEMULTISET_H +#define LLVM_ADT_SPARSEMULTISET_H + +#include "llvm/ADT/SparseSet.h" + +namespace llvm { + +/// Fast multiset implementation for objects that can be identified by small +/// unsigned keys. +/// +/// SparseMultiSet allocates memory proportional to the size of the key +/// universe, so it is not recommended for building composite data structures. +/// It is useful for algorithms that require a single set with fast operations. +/// +/// Compared to DenseSet and DenseMap, SparseMultiSet provides constant-time +/// fast clear() as fast as a vector. The find(), insert(), and erase() +/// operations are all constant time, and typically faster than a hash table. +/// The iteration order doesn't depend on numerical key values, it only depends +/// on the order of insert() and erase() operations. Iteration order is the +/// insertion order. Iteration is only provided over elements of equivalent +/// keys, but iterators are bidirectional. +/// +/// Compared to BitVector, SparseMultiSet<unsigned> uses 8x-40x more memory, but +/// offers constant-time clear() and size() operations as well as fast iteration +/// independent on the size of the universe. +/// +/// SparseMultiSet contains a dense vector holding all the objects and a sparse +/// array holding indexes into the dense vector. Most of the memory is used by +/// the sparse array which is the size of the key universe. The SparseT template +/// parameter provides a space/speed tradeoff for sets holding many elements. +/// +/// When SparseT is uint32_t, find() only touches up to 3 cache lines, but the +/// sparse array uses 4 x Universe bytes. +/// +/// When SparseT is uint8_t (the default), find() touches up to 3+[N/256] cache +/// lines, but the sparse array is 4x smaller. N is the number of elements in +/// the set. +/// +/// For sets that may grow to thousands of elements, SparseT should be set to +/// uint16_t or uint32_t. +/// +/// Multiset behavior is provided by providing doubly linked lists for values +/// that are inlined in the dense vector. SparseMultiSet is a good choice when +/// one desires a growable number of entries per key, as it will retain the +/// SparseSet algorithmic properties despite being growable. Thus, it is often a +/// better choice than a SparseSet of growable containers or a vector of +/// vectors. SparseMultiSet also keeps iterators valid after erasure (provided +/// the iterators don't point to the element erased), allowing for more +/// intuitive and fast removal. +/// +/// @tparam ValueT The type of objects in the set. +/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT. +/// @tparam SparseT An unsigned integer type. See above. +/// +template<typename ValueT, + typename KeyFunctorT = llvm::identity<unsigned>, + typename SparseT = uint8_t> +class SparseMultiSet { + /// The actual data that's stored, as a doubly-linked list implemented via + /// indices into the DenseVector. The doubly linked list is implemented + /// circular in Prev indices, and INVALID-terminated in Next indices. This + /// provides efficient access to list tails. These nodes can also be + /// tombstones, in which case they are actually nodes in a single-linked + /// freelist of recyclable slots. + struct SMSNode { + static const unsigned INVALID = ~0U; + + ValueT Data; + unsigned Prev; + unsigned Next; + + SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { } + + /// List tails have invalid Nexts. + bool isTail() const { + return Next == INVALID; + } + + /// Whether this node is a tombstone node, and thus is in our freelist. + bool isTombstone() const { + return Prev == INVALID; + } + + /// Since the list is circular in Prev, all non-tombstone nodes have a valid + /// Prev. + bool isValid() const { return Prev != INVALID; } + }; + + typedef typename KeyFunctorT::argument_type KeyT; + typedef SmallVector<SMSNode, 8> DenseT; + DenseT Dense; + SparseT *Sparse; + unsigned Universe; + KeyFunctorT KeyIndexOf; + SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf; + + /// We have a built-in recycler for reusing tombstone slots. This recycler + /// puts a singly-linked free list into tombstone slots, allowing us quick + /// erasure, iterator preservation, and dense size. + unsigned FreelistIdx; + unsigned NumFree; + + unsigned sparseIndex(const ValueT &Val) const { + assert(ValIndexOf(Val) < Universe && + "Invalid key in set. Did object mutate?"); + return ValIndexOf(Val); + } + unsigned sparseIndex(const SMSNode &N) const { return sparseIndex(N.Data); } + + // Disable copy construction and assignment. + // This data structure is not meant to be used that way. + SparseMultiSet(const SparseMultiSet&) LLVM_DELETED_FUNCTION; + SparseMultiSet &operator=(const SparseMultiSet&) LLVM_DELETED_FUNCTION; + + /// Whether the given entry is the head of the list. List heads's previous + /// pointers are to the tail of the list, allowing for efficient access to the + /// list tail. D must be a valid entry node. + bool isHead(const SMSNode &D) const { + assert(D.isValid() && "Invalid node for head"); + return Dense[D.Prev].isTail(); + } + + /// Whether the given entry is a singleton entry, i.e. the only entry with + /// that key. + bool isSingleton(const SMSNode &N) const { + assert(N.isValid() && "Invalid node for singleton"); + // Is N its own predecessor? + return &Dense[N.Prev] == &N; + } + + /// Add in the given SMSNode. Uses a free entry in our freelist if + /// available. Returns the index of the added node. + unsigned addValue(const ValueT& V, unsigned Prev, unsigned Next) { + if (NumFree == 0) { + Dense.push_back(SMSNode(V, Prev, Next)); + return Dense.size() - 1; + } + + // Peel off a free slot + unsigned Idx = FreelistIdx; + unsigned NextFree = Dense[Idx].Next; + assert(Dense[Idx].isTombstone() && "Non-tombstone free?"); + + Dense[Idx] = SMSNode(V, Prev, Next); + FreelistIdx = NextFree; + --NumFree; + return Idx; + } + + /// Make the current index a new tombstone. Pushes it onto the freelist. + void makeTombstone(unsigned Idx) { + Dense[Idx].Prev = SMSNode::INVALID; + Dense[Idx].Next = FreelistIdx; + FreelistIdx = Idx; + ++NumFree; + } + +public: + typedef ValueT value_type; + typedef ValueT &reference; + typedef const ValueT &const_reference; + typedef ValueT *pointer; + typedef const ValueT *const_pointer; + + SparseMultiSet() + : Sparse(0), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) { } + + ~SparseMultiSet() { free(Sparse); } + + /// Set the universe size which determines the largest key the set can hold. + /// The universe must be sized before any elements can be added. + /// + /// @param U Universe size. All object keys must be less than U. + /// + void setUniverse(unsigned U) { + // It's not hard to resize the universe on a non-empty set, but it doesn't + // seem like a likely use case, so we can add that code when we need it. + assert(empty() && "Can only resize universe on an empty map"); + // Hysteresis prevents needless reallocations. + if (U >= Universe/4 && U <= Universe) + return; + free(Sparse); + // The Sparse array doesn't actually need to be initialized, so malloc + // would be enough here, but that will cause tools like valgrind to + // complain about branching on uninitialized data. + Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT))); + Universe = U; + } + + /// Our iterators are iterators over the collection of objects that share a + /// key. + template<typename SMSPtrTy> + class iterator_base : public std::iterator<std::bidirectional_iterator_tag, + ValueT> { + friend class SparseMultiSet; + SMSPtrTy SMS; + unsigned Idx; + unsigned SparseIdx; + + iterator_base(SMSPtrTy P, unsigned I, unsigned SI) + : SMS(P), Idx(I), SparseIdx(SI) { } + + /// Whether our iterator has fallen outside our dense vector. + bool isEnd() const { + if (Idx == SMSNode::INVALID) + return true; + + assert(Idx < SMS->Dense.size() && "Out of range, non-INVALID Idx?"); + return false; + } + + /// Whether our iterator is properly keyed, i.e. the SparseIdx is valid + bool isKeyed() const { return SparseIdx < SMS->Universe; } + + unsigned Prev() const { return SMS->Dense[Idx].Prev; } + unsigned Next() const { return SMS->Dense[Idx].Next; } + + void setPrev(unsigned P) { SMS->Dense[Idx].Prev = P; } + void setNext(unsigned N) { SMS->Dense[Idx].Next = N; } + + public: + typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super; + typedef typename super::value_type value_type; + typedef typename super::difference_type difference_type; + typedef typename super::pointer pointer; + typedef typename super::reference reference; + + iterator_base(const iterator_base &RHS) + : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { } + + const iterator_base &operator=(const iterator_base &RHS) { + SMS = RHS.SMS; + Idx = RHS.Idx; + SparseIdx = RHS.SparseIdx; + return *this; + } + + reference operator*() const { + assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx && + "Dereferencing iterator of invalid key or index"); + + return SMS->Dense[Idx].Data; + } + pointer operator->() const { return &operator*(); } + + /// Comparison operators + bool operator==(const iterator_base &RHS) const { + // end compares equal + if (SMS == RHS.SMS && Idx == RHS.Idx) { + assert((isEnd() || SparseIdx == RHS.SparseIdx) && + "Same dense entry, but different keys?"); + return true; + } + + return false; + } + + bool operator!=(const iterator_base &RHS) const { + return !operator==(RHS); + } + + /// Increment and decrement operators + iterator_base &operator--() { // predecrement - Back up + assert(isKeyed() && "Decrementing an invalid iterator"); + assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) && + "Decrementing head of list"); + + // If we're at the end, then issue a new find() + if (isEnd()) + Idx = SMS->findIndex(SparseIdx).Prev(); + else + Idx = Prev(); + + return *this; + } + iterator_base &operator++() { // preincrement - Advance + assert(!isEnd() && isKeyed() && "Incrementing an invalid/end iterator"); + Idx = Next(); + return *this; + } + iterator_base operator--(int) { // postdecrement + iterator_base I(*this); + --*this; + return I; + } + iterator_base operator++(int) { // postincrement + iterator_base I(*this); + ++*this; + return I; + } + }; + typedef iterator_base<SparseMultiSet *> iterator; + typedef iterator_base<const SparseMultiSet *> const_iterator; + + // Convenience types + typedef std::pair<iterator, iterator> RangePair; + + /// Returns an iterator past this container. Note that such an iterator cannot + /// be decremented, but will compare equal to other end iterators. + iterator end() { return iterator(this, SMSNode::INVALID, SMSNode::INVALID); } + const_iterator end() const { + return const_iterator(this, SMSNode::INVALID, SMSNode::INVALID); + } + + /// Returns true if the set is empty. + /// + /// This is not the same as BitVector::empty(). + /// + bool empty() const { return size() == 0; } + + /// Returns the number of elements in the set. + /// + /// This is not the same as BitVector::size() which returns the size of the + /// universe. + /// + unsigned size() const { + assert(NumFree <= Dense.size() && "Out-of-bounds free entries"); + return Dense.size() - NumFree; + } + + /// Clears the set. This is a very fast constant time operation. + /// + void clear() { + // Sparse does not need to be cleared, see find(). + Dense.clear(); + NumFree = 0; + FreelistIdx = SMSNode::INVALID; + } + + /// Find an element by its index. + /// + /// @param Idx A valid index to find. + /// @returns An iterator to the element identified by key, or end(). + /// + iterator findIndex(unsigned Idx) { + assert(Idx < Universe && "Key out of range"); + assert(std::numeric_limits<SparseT>::is_integer && + !std::numeric_limits<SparseT>::is_signed && + "SparseT must be an unsigned integer type"); + const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u; + for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) { + const unsigned FoundIdx = sparseIndex(Dense[i]); + // Check that we're pointing at the correct entry and that it is the head + // of a valid list. + if (Idx == FoundIdx && Dense[i].isValid() && isHead(Dense[i])) + return iterator(this, i, Idx); + // Stride is 0 when SparseT >= unsigned. We don't need to loop. + if (!Stride) + break; + } + return end(); + } + + /// Find an element by its key. + /// + /// @param Key A valid key to find. + /// @returns An iterator to the element identified by key, or end(). + /// + iterator find(const KeyT &Key) { + return findIndex(KeyIndexOf(Key)); + } + + const_iterator find(const KeyT &Key) const { + iterator I = const_cast<SparseMultiSet*>(this)->findIndex(KeyIndexOf(Key)); + return const_iterator(I.SMS, I.Idx, KeyIndexOf(Key)); + } + + /// Returns the number of elements identified by Key. This will be linear in + /// the number of elements of that key. + unsigned count(const KeyT &Key) const { + unsigned Ret = 0; + for (const_iterator It = find(Key); It != end(); ++It) + ++Ret; + + return Ret; + } + + /// Returns true if this set contains an element identified by Key. + bool contains(const KeyT &Key) const { + return find(Key) != end(); + } + + /// Return the head and tail of the subset's list, otherwise returns end(). + iterator getHead(const KeyT &Key) { return find(Key); } + iterator getTail(const KeyT &Key) { + iterator I = find(Key); + if (I != end()) + I = iterator(this, I.Prev(), KeyIndexOf(Key)); + return I; + } + + /// The bounds of the range of items sharing Key K. First member is the head + /// of the list, and the second member is a decrementable end iterator for + /// that key. + RangePair equal_range(const KeyT &K) { + iterator B = find(K); + iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx); + return make_pair(B, E); + } + + /// Insert a new element at the tail of the subset list. Returns an iterator + /// to the newly added entry. + iterator insert(const ValueT &Val) { + unsigned Idx = sparseIndex(Val); + iterator I = findIndex(Idx); + + unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID); + + if (I == end()) { + // Make a singleton list + Sparse[Idx] = NodeIdx; + Dense[NodeIdx].Prev = NodeIdx; + return iterator(this, NodeIdx, Idx); + } + + // Stick it at the end. + unsigned HeadIdx = I.Idx; + unsigned TailIdx = I.Prev(); + Dense[TailIdx].Next = NodeIdx; + Dense[HeadIdx].Prev = NodeIdx; + Dense[NodeIdx].Prev = TailIdx; + + return iterator(this, NodeIdx, Idx); + } + + /// Erases an existing element identified by a valid iterator. + /// + /// This invalidates iterators pointing at the same entry, but erase() returns + /// an iterator pointing to the next element in the subset's list. This makes + /// it possible to erase selected elements while iterating over the subset: + /// + /// tie(I, E) = Set.equal_range(Key); + /// while (I != E) + /// if (test(*I)) + /// I = Set.erase(I); + /// else + /// ++I; + /// + /// Note that if the last element in the subset list is erased, this will + /// return an end iterator which can be decremented to get the new tail (if it + /// exists): + /// + /// tie(B, I) = Set.equal_range(Key); + /// for (bool isBegin = B == I; !isBegin; /* empty */) { + /// isBegin = (--I) == B; + /// if (test(I)) + /// break; + /// I = erase(I); + /// } + iterator erase(iterator I) { + assert(I.isKeyed() && !I.isEnd() && !Dense[I.Idx].isTombstone() && + "erasing invalid/end/tombstone iterator"); + + // First, unlink the node from its list. Then swap the node out with the + // dense vector's last entry + iterator NextI = unlink(Dense[I.Idx]); + + // Put in a tombstone. + makeTombstone(I.Idx); + + return NextI; + } + + /// Erase all elements with the given key. This invalidates all + /// iterators of that key. + void eraseAll(const KeyT &K) { + for (iterator I = find(K); I != end(); /* empty */) + I = erase(I); + } + +private: + /// Unlink the node from its list. Returns the next node in the list. + iterator unlink(const SMSNode &N) { + if (isSingleton(N)) { + // Singleton is already unlinked + assert(N.Next == SMSNode::INVALID && "Singleton has next?"); + return iterator(this, SMSNode::INVALID, ValIndexOf(N.Data)); + } + + if (isHead(N)) { + // If we're the head, then update the sparse array and our next. + Sparse[sparseIndex(N)] = N.Next; + Dense[N.Next].Prev = N.Prev; + return iterator(this, N.Next, ValIndexOf(N.Data)); + } + + if (N.isTail()) { + // If we're the tail, then update our head and our previous. + findIndex(sparseIndex(N)).setPrev(N.Prev); + Dense[N.Prev].Next = N.Next; + + // Give back an end iterator that can be decremented + iterator I(this, N.Prev, ValIndexOf(N.Data)); + return ++I; + } + + // Otherwise, just drop us + Dense[N.Next].Prev = N.Prev; + Dense[N.Prev].Next = N.Next; + return iterator(this, N.Next, ValIndexOf(N.Data)); + } +}; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/ADT/SparseSet.h b/contrib/llvm/include/llvm/ADT/SparseSet.h index 063c675..267a340 100644 --- a/contrib/llvm/include/llvm/ADT/SparseSet.h +++ b/contrib/llvm/include/llvm/ADT/SparseSet.h @@ -20,8 +20,8 @@ #ifndef LLVM_ADT_SPARSESET_H #define LLVM_ADT_SPARSESET_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include <limits> diff --git a/contrib/llvm/include/llvm/ADT/Statistic.h b/contrib/llvm/include/llvm/ADT/Statistic.h index b54d10b..26aac7b 100644 --- a/contrib/llvm/include/llvm/ADT/Statistic.h +++ b/contrib/llvm/include/llvm/ADT/Statistic.h @@ -51,7 +51,9 @@ public: // Allow use of this class as the value itself. operator unsigned() const { return Value; } - const Statistic &operator=(unsigned Val) { + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) + const Statistic &operator=(unsigned Val) { Value = Val; return init(); } @@ -106,6 +108,46 @@ public: return init(); } +#else // Statistics are disabled in release builds. + + const Statistic &operator=(unsigned Val) { + return *this; + } + + const Statistic &operator++() { + return *this; + } + + unsigned operator++(int) { + return 0; + } + + const Statistic &operator--() { + return *this; + } + + unsigned operator--(int) { + return 0; + } + + const Statistic &operator+=(const unsigned &V) { + return *this; + } + + const Statistic &operator-=(const unsigned &V) { + return *this; + } + + const Statistic &operator*=(const unsigned &V) { + return *this; + } + + const Statistic &operator/=(const unsigned &V) { + return *this; + } + +#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) + protected: Statistic &init() { bool tmp = Initialized; diff --git a/contrib/llvm/include/llvm/ADT/StringExtras.h b/contrib/llvm/include/llvm/ADT/StringExtras.h index bf27c43..d2887c5 100644 --- a/contrib/llvm/include/llvm/ADT/StringExtras.h +++ b/contrib/llvm/include/llvm/ADT/StringExtras.h @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { template<typename T> class SmallVectorImpl; @@ -27,6 +27,17 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) { return X < 10 ? '0' + X : HexChar + X - 10; } +/// Interpret the given character \p C as a hexadecimal digit and return its +/// value. +/// +/// If \p C is not a valid hex digit, -1U is returned. +static inline unsigned hexDigitValue(char C) { + if (C >= '0' && C <= '9') return C-'0'; + if (C >= 'a' && C <= 'f') return C-'a'+10U; + if (C >= 'A' && C <= 'F') return C-'A'+10U; + return -1U; +} + /// utohex_buffer - Emit the specified number into the buffer specified by /// BufferEnd, returning a pointer to the start of the string. This can be used /// like this: (note that the buffer must be large enough to handle any number): diff --git a/contrib/llvm/include/llvm/ADT/StringMap.h b/contrib/llvm/include/llvm/ADT/StringMap.h index b4497a2..d01437b 100644 --- a/contrib/llvm/include/llvm/ADT/StringMap.h +++ b/contrib/llvm/include/llvm/ADT/StringMap.h @@ -53,7 +53,7 @@ public: class StringMapImpl { protected: // Array of NumBuckets pointers to entries, null pointers are holes. - // TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed + // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed // by an array of the actual hash values as unsigned integers. StringMapEntryBase **TheTable; unsigned NumBuckets; @@ -171,7 +171,6 @@ public: return Create(KeyStart, KeyEnd, Allocator, 0); } - /// Create - Create a StringMapEntry with normal malloc/free. template<typename InitType> static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd, @@ -204,7 +203,6 @@ public: return *reinterpret_cast<StringMapEntry*>(Ptr); } - /// Destroy - Destroy this StringMapEntry, releasing memory back to the /// specified allocator. template<typename AllocatorTy> @@ -239,6 +237,10 @@ public: explicit StringMap(AllocatorTy A) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} + StringMap(unsigned InitialSize, AllocatorTy A) + : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))), + Allocator(A) {} + StringMap(const StringMap &RHS) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { assert(RHS.empty() && @@ -290,7 +292,7 @@ public: return const_iterator(TheTable+Bucket, true); } - /// lookup - Return the entry for the specified key, or a default + /// lookup - Return the entry for the specified key, or a default /// constructed value if no such entry exists. ValueTy lookup(StringRef Key) const { const_iterator it = find(Key); @@ -336,8 +338,8 @@ public: StringMapEntryBase *&Bucket = TheTable[I]; if (Bucket && Bucket != getTombstoneVal()) { static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator); - Bucket = 0; } + Bucket = 0; } NumItems = 0; @@ -427,7 +429,7 @@ public: return Ptr != RHS.Ptr; } - inline StringMapConstIterator& operator++() { // Preincrement + inline StringMapConstIterator& operator++() { // Preincrement ++Ptr; AdvancePastEmptyBuckets(); return *this; diff --git a/contrib/llvm/include/llvm/ADT/StringRef.h b/contrib/llvm/include/llvm/ADT/StringRef.h index 292bde0..224855e 100644 --- a/contrib/llvm/include/llvm/ADT/StringRef.h +++ b/contrib/llvm/include/llvm/ADT/StringRef.h @@ -11,7 +11,6 @@ #define LLVM_ADT_STRINGREF_H #include "llvm/Support/type_traits.h" - #include <algorithm> #include <cassert> #include <cstring> @@ -58,14 +57,14 @@ namespace llvm { // integer works around this bug. static size_t min(size_t a, size_t b) { return a < b ? a : b; } static size_t max(size_t a, size_t b) { return a > b ? a : b; } - + // Workaround memcmp issue with null pointers (undefined behavior) // by providing a specialized version static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { if (Length == 0) { return 0; } return ::memcmp(Lhs,Rhs,Length); } - + public: /// @name Constructors /// @{ @@ -388,7 +387,7 @@ namespace llvm { Start = min(Start, Length); return StringRef(Data + Start, min(N, Length - Start)); } - + /// Return a StringRef equal to 'this' but with the first \p N elements /// dropped. StringRef drop_front(unsigned N = 1) const { @@ -536,7 +535,7 @@ namespace llvm { return LHS.compare(RHS) != -1; } - inline std::string &operator+=(std::string &buffer, llvm::StringRef string) { + inline std::string &operator+=(std::string &buffer, StringRef string) { return buffer.append(string.data(), string.size()); } diff --git a/contrib/llvm/include/llvm/ADT/StringSet.h b/contrib/llvm/include/llvm/ADT/StringSet.h index b69a964..7bea577 100644 --- a/contrib/llvm/include/llvm/ADT/StringSet.h +++ b/contrib/llvm/include/llvm/ADT/StringSet.h @@ -18,23 +18,25 @@ namespace llvm { - /// StringSet - A wrapper for StringMap that provides set-like - /// functionality. Only insert() and count() methods are used by my - /// code. + /// StringSet - A wrapper for StringMap that provides set-like functionality. template <class AllocatorTy = llvm::MallocAllocator> class StringSet : public llvm::StringMap<char, AllocatorTy> { typedef llvm::StringMap<char, AllocatorTy> base; public: - bool insert(StringRef InLang) { - assert(!InLang.empty()); - const char *KeyStart = InLang.data(); - const char *KeyEnd = KeyStart + InLang.size(); - llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>:: - Create(KeyStart, KeyEnd, base::getAllocator(), '+'); - if (!base::insert(Entry)) { - Entry->Destroy(base::getAllocator()); + + /// insert - Insert the specified key into the set. If the key already + /// exists in the set, return false and ignore the request, otherwise insert + /// it and return true. + bool insert(StringRef Key) { + // Get or create the map entry for the key; if it doesn't exist the value + // type will be default constructed which we use to detect insert. + // + // We use '+' as the sentinel value in the map. + assert(!Key.empty()); + StringMapEntry<char> &Entry = this->GetOrCreateValue(Key); + if (Entry.getValue() == '+') return false; - } + Entry.setValue('+'); return true; } }; diff --git a/contrib/llvm/include/llvm/ADT/TinyPtrVector.h b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h index d3d33b8..cc0e7b6 100644 --- a/contrib/llvm/include/llvm/ADT/TinyPtrVector.h +++ b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h @@ -70,7 +70,7 @@ public: return *this; } -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { RHS.Val = (EltTy)0; } diff --git a/contrib/llvm/include/llvm/ADT/Triple.h b/contrib/llvm/include/llvm/ADT/Triple.h index 408d70c..8fac222 100644 --- a/contrib/llvm/include/llvm/ADT/Triple.h +++ b/contrib/llvm/include/llvm/ADT/Triple.h @@ -44,7 +44,7 @@ public: UnknownArch, arm, // ARM; arm, armv.*, xscale - cellspu, // CellSPU: spu, cellspu + aarch64, // AArch64: aarch64 hexagon, // Hexagon: hexagon mips, // MIPS: mips, mipsallegrex mipsel, // MIPSEL: mipsel, mipsallegrexel @@ -101,8 +101,8 @@ public: Haiku, Minix, RTEMS, - NativeClient, - CNK, // BG/P Compute-Node Kernel + NaCl, // Native Client + CNK, // BG/P Compute-Node Kernel Bitrig, AIX }; @@ -112,6 +112,7 @@ public: GNU, GNUEABI, GNUEABIHF, + GNUX32, EABI, MachO, Android, @@ -296,9 +297,14 @@ public: return getOS() == Triple::Darwin || getOS() == Triple::MacOSX; } + /// Is this an iOS triple. + bool isiOS() const { + return getOS() == Triple::IOS; + } + /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). bool isOSDarwin() const { - return isMacOSX() || getOS() == Triple::IOS; + return isMacOSX() || isiOS(); } /// \brief Tests for either Cygwin or MinGW OS @@ -311,6 +317,11 @@ public: return getOS() == Triple::Win32 || isOSCygMing(); } + /// \brief Tests whether the OS is NaCl (Native Client) + bool isOSNaCl() const { + return getOS() == Triple::NaCl; + } + /// \brief Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return !isOSDarwin() && !isOSWindows(); diff --git a/contrib/llvm/include/llvm/ADT/ValueMap.h b/contrib/llvm/include/llvm/ADT/ValueMap.h index d23fccf..b4fed7a 100644 --- a/contrib/llvm/include/llvm/ADT/ValueMap.h +++ b/contrib/llvm/include/llvm/ADT/ValueMap.h @@ -27,10 +27,9 @@ #define LLVM_ADT_VALUEMAP_H #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Mutex.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/type_traits.h" -#include "llvm/Support/Mutex.h" - #include <iterator> namespace llvm { diff --git a/contrib/llvm/include/llvm/ADT/VariadicFunction.h b/contrib/llvm/include/llvm/ADT/VariadicFunction.h index a7f83a6..0497aa7 100644 --- a/contrib/llvm/include/llvm/ADT/VariadicFunction.h +++ b/contrib/llvm/include/llvm/ADT/VariadicFunction.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_VARIADIC_FUNCTION_H -#define LLVM_ADT_VARIADIC_FUNCTION_H +#ifndef LLVM_ADT_VARIADICFUNCTION_H +#define LLVM_ADT_VARIADICFUNCTION_H #include "llvm/ADT/ArrayRef.h" @@ -328,4 +328,4 @@ struct VariadicFunction3 { } // end namespace llvm -#endif // LLVM_ADT_VARIADIC_FUNCTION_H +#endif // LLVM_ADT_VARIADICFUNCTION_H diff --git a/contrib/llvm/include/llvm/ADT/ilist.h b/contrib/llvm/include/llvm/ADT/ilist.h index 7f5cd17..71dab2e 100644 --- a/contrib/llvm/include/llvm/ADT/ilist.h +++ b/contrib/llvm/include/llvm/ADT/ilist.h @@ -234,17 +234,17 @@ public: pointer getNodePtrUnchecked() const { return NodePtr; } }; -// do not implement. this is to catch errors when people try to use -// them as random access iterators +// These are to catch errors when people try to use them as random access +// iterators. template<typename T> -void operator-(int, ilist_iterator<T>); +void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION; template<typename T> -void operator-(ilist_iterator<T>,int); +void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION; template<typename T> -void operator+(int, ilist_iterator<T>); +void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION; template<typename T> -void operator+(ilist_iterator<T>,int); +void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION; // operator!=/operator== - Allow mixed comparisons without dereferencing // the iterator, which could very likely be pointing to end(). @@ -274,12 +274,12 @@ template<typename From> struct simplify_type; template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > { typedef NodeTy* SimpleType; - static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { + static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) { return &*Node; } }; template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { - typedef NodeTy* SimpleType; + typedef /*const*/ NodeTy* SimpleType; static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) { return &*Node; @@ -465,6 +465,17 @@ public: return where; } + /// Remove all nodes from the list like clear(), but do not call + /// removeNodeFromList() or deleteNode(). + /// + /// This should only be used immediately before freeing nodes in bulk to + /// avoid traversing the list and bringing all the nodes into cache. + void clearAndLeakNodesUnsafely() { + if (Head) { + Head = getTail(); + this->setPrev(Head, Head); + } + } private: // transfer - The heart of the splice function. Move linked list nodes from @@ -472,6 +483,10 @@ private: // void transfer(iterator position, iplist &L2, iterator first, iterator last) { assert(first != last && "Should be checked by callers"); + // Position cannot be contained in the range to be transferred. + // Check for the most common mistake. + assert(position != first && + "Insertion point can't be one of the transferred nodes"); if (position != last) { // Note: we have to be careful about the case when we move the first node diff --git a/contrib/llvm/include/llvm/ADT/ilist_node.h b/contrib/llvm/include/llvm/ADT/ilist_node.h index f008003..0361244 100644 --- a/contrib/llvm/include/llvm/ADT/ilist_node.h +++ b/contrib/llvm/include/llvm/ADT/ilist_node.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_ILIST_NODE_H -#define LLVM_ADT_ILIST_NODE_H +#ifndef LLVM_ADT_ILISTNODE_H +#define LLVM_ADT_ILISTNODE_H namespace llvm { diff --git a/contrib/llvm/include/llvm/AddressingMode.h b/contrib/llvm/include/llvm/AddressingMode.h deleted file mode 100644 index 70b3c05..0000000 --- a/contrib/llvm/include/llvm/AddressingMode.h +++ /dev/null @@ -1,41 +0,0 @@ -//===--------- llvm/AddressingMode.h - Addressing Mode -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// This file contains addressing mode data structures which are shared -// between LSR and a number of places in the codegen. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADDRESSING_MODE_H -#define LLVM_ADDRESSING_MODE_H - -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -class GlobalValue; - -/// AddrMode - This represents an addressing mode of: -/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg -/// If BaseGV is null, there is no BaseGV. -/// If BaseOffs is zero, there is no base offset. -/// If HasBaseReg is false, there is no base register. -/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with -/// no scale. -/// -struct AddrMode { - GlobalValue *BaseGV; - int64_t BaseOffs; - bool HasBaseReg; - int64_t Scale; - AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h index be274af..d703f21 100644 --- a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -34,11 +34,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H -#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H +#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H +#define LLVM_ANALYSIS_ALIASANALYSIS_H -#include "llvm/Support/CallSite.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/CallSite.h" namespace llvm { @@ -373,7 +373,7 @@ public: return getModRefInfo(I, Location(P, Size)); } - /// getModRefInfo (for call sites) - Return whether information about whether + /// getModRefInfo (for call sites) - Return information about whether /// a particular call site modifies or reads the specified memory location. virtual ModRefResult getModRefInfo(ImmutableCallSite CS, const Location &Loc); @@ -384,7 +384,7 @@ public: return getModRefInfo(CS, Location(P, Size)); } - /// getModRefInfo (for calls) - Return whether information about whether + /// getModRefInfo (for calls) - Return information about whether /// a particular call modifies or reads the specified memory location. ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) { return getModRefInfo(ImmutableCallSite(C), Loc); @@ -395,7 +395,7 @@ public: return getModRefInfo(C, Location(P, Size)); } - /// getModRefInfo (for invokes) - Return whether information about whether + /// getModRefInfo (for invokes) - Return information about whether /// a particular invoke modifies or reads the specified memory location. ModRefResult getModRefInfo(const InvokeInst *I, const Location &Loc) { @@ -408,7 +408,7 @@ public: return getModRefInfo(I, Location(P, Size)); } - /// getModRefInfo (for loads) - Return whether information about whether + /// getModRefInfo (for loads) - Return information about whether /// a particular load modifies or reads the specified memory location. ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc); @@ -417,7 +417,7 @@ public: return getModRefInfo(L, Location(P, Size)); } - /// getModRefInfo (for stores) - Return whether information about whether + /// getModRefInfo (for stores) - Return information about whether /// a particular store modifies or reads the specified memory location. ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc); @@ -426,7 +426,7 @@ public: return getModRefInfo(S, Location(P, Size)); } - /// getModRefInfo (for fences) - Return whether information about whether + /// getModRefInfo (for fences) - Return information about whether /// a particular store modifies or reads the specified memory location. ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) { // Conservatively correct. (We could possibly be a bit smarter if @@ -439,7 +439,7 @@ public: return getModRefInfo(S, Location(P, Size)); } - /// getModRefInfo (for cmpxchges) - Return whether information about whether + /// getModRefInfo (for cmpxchges) - Return information about whether /// a particular cmpxchg modifies or reads the specified memory location. ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc); @@ -449,7 +449,7 @@ public: return getModRefInfo(CX, Location(P, Size)); } - /// getModRefInfo (for atomicrmws) - Return whether information about whether + /// getModRefInfo (for atomicrmws) - Return information about whether /// a particular atomicrmw modifies or reads the specified memory location. ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc); @@ -459,7 +459,7 @@ public: return getModRefInfo(RMW, Location(P, Size)); } - /// getModRefInfo (for va_args) - Return whether information about whether + /// getModRefInfo (for va_args) - Return information about whether /// a particular va_arg modifies or reads the specified memory location. ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); @@ -587,17 +587,12 @@ bool isNoAliasCall(const Value *V); /// isIdentifiedObject - Return true if this pointer refers to a distinct and /// identifiable object. This returns true for: /// Global Variables and Functions (but not Global Aliases) -/// Allocas and Mallocs +/// Allocas /// ByVal and NoAlias Arguments -/// NoAlias returns +/// NoAlias returns (e.g. calls to malloc) /// bool isIdentifiedObject(const Value *V); -/// isKnownNonNull - Return true if this pointer couldn't possibly be null by -/// its definition. This returns true for allocas, non-extern-weak globals and -/// byval arguments. -bool isKnownNonNull(const Value *V); - } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h index 1e606c8..da00707 100644 --- a/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h +++ b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h @@ -17,11 +17,10 @@ #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H #define LLVM_ANALYSIS_ALIASSETTRACKER_H -#include "llvm/Support/CallSite.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Support/ValueHandle.h" #include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h index 5168ab7..b3e2d18 100644 --- a/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h +++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h @@ -14,17 +14,17 @@ #ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H #define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H -#include "llvm/BasicBlock.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include <vector> #include <string> +#include <vector> namespace llvm { @@ -271,7 +271,7 @@ class BlockFrequencyImpl { BlockT *EntryBlock = fn->begin(); - copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT)); + std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT)); unsigned RPOidx = 0; for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) { diff --git a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h index c0567da..6c23f7c 100644 --- a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h @@ -14,10 +14,10 @@ #ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H -#include "llvm/InitializePasses.h" -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/CFGPrinter.h b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h index 4704a92..fa596c3 100644 --- a/contrib/llvm/include/llvm/Analysis/CFGPrinter.h +++ b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h @@ -15,10 +15,10 @@ #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" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" #include "llvm/Support/CFG.h" #include "llvm/Support/GraphWriter.h" diff --git a/contrib/llvm/include/llvm/Analysis/CallGraph.h b/contrib/llvm/include/llvm/Analysis/CallGraph.h index 6a9ed31..591484d 100644 --- a/contrib/llvm/include/llvm/Analysis/CallGraph.h +++ b/contrib/llvm/include/llvm/Analysis/CallGraph.h @@ -51,13 +51,13 @@ #ifndef LLVM_ANALYSIS_CALLGRAPH_H #define LLVM_ANALYSIS_CALLGRAPH_H -#include "llvm/Function.h" -#include "llvm/Pass.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/Function.h" +#include "llvm/Pass.h" #include "llvm/Support/CallSite.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/IncludeFile.h" +#include "llvm/Support/ValueHandle.h" #include <map> namespace llvm { diff --git a/contrib/llvm/include/llvm/CallGraphSCCPass.h b/contrib/llvm/include/llvm/Analysis/CallGraphSCCPass.h index 7154aa3..e609dac 100644 --- a/contrib/llvm/include/llvm/CallGraphSCCPass.h +++ b/contrib/llvm/include/llvm/Analysis/CallGraphSCCPass.h @@ -18,11 +18,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CALL_GRAPH_SCC_PASS_H -#define LLVM_CALL_GRAPH_SCC_PASS_H +#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H +#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H -#include "llvm/Pass.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Pass.h" namespace llvm { @@ -39,6 +39,9 @@ public: /// corresponding to a CallGraph. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + /// doInitialization - This method is called before the SCC's of the program /// has been processed, allowing the pass to do initialization as necessary. virtual bool doInitialization(CallGraph &CG) { diff --git a/contrib/llvm/include/llvm/Analysis/CallPrinter.h b/contrib/llvm/include/llvm/Analysis/CallPrinter.h new file mode 100644 index 0000000..5f5d160 --- /dev/null +++ b/contrib/llvm/include/llvm/Analysis/CallPrinter.h @@ -0,0 +1,27 @@ +//===-- CallPrinter.h - Call graph printer external interface ----*- 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 external functions that can be called to explicitly +// instantiate the call graph printer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_CALLPRINTER_H +#define LLVM_ANALYSIS_CALLPRINTER_H + +namespace llvm { + + class ModulePass; + + ModulePass *createCallGraphViewerPass(); + ModulePass *createCallGraphPrinterPass(); + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Analysis/CaptureTracking.h b/contrib/llvm/include/llvm/Analysis/CaptureTracking.h index 2889269..8edabfe 100644 --- a/contrib/llvm/include/llvm/Analysis/CaptureTracking.h +++ b/contrib/llvm/include/llvm/Analysis/CaptureTracking.h @@ -14,12 +14,11 @@ #ifndef LLVM_ANALYSIS_CAPTURETRACKING_H #define LLVM_ANALYSIS_CAPTURETRACKING_H -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Support/CallSite.h" - namespace llvm { + + class Value; + class Use; + /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can /// be expensive, so consider caching the results. The boolean ReturnCaptures diff --git a/contrib/llvm/include/llvm/Analysis/CodeMetrics.h b/contrib/llvm/include/llvm/Analysis/CodeMetrics.h index 4398faa..086934d 100644 --- a/contrib/llvm/include/llvm/Analysis/CodeMetrics.h +++ b/contrib/llvm/include/llvm/Analysis/CodeMetrics.h @@ -19,77 +19,75 @@ #include "llvm/Support/CallSite.h" namespace llvm { - class BasicBlock; - class Function; - class Instruction; - class DataLayout; - class Value; +class BasicBlock; +class Function; +class Instruction; +class DataLayout; +class TargetTransformInfo; +class Value; + +/// \brief Check whether a call will lower to something small. +/// +/// This tests checks whether this callsite will lower to something +/// significantly cheaper than a traditional call, often a single +/// instruction. Note that if isInstructionFree(CS.getInstruction()) would +/// return true, so will this function. +bool callIsSmall(ImmutableCallSite CS); + +/// \brief Utility to calculate the size and a few similar metrics for a set +/// of basic blocks. +struct CodeMetrics { + /// \brief True if this function contains a call to setjmp or other functions + /// with attribute "returns twice" without having the attribute itself. + bool exposesReturnsTwice; + + /// \brief True if this function calls itself. + bool isRecursive; + + /// \brief True if this function cannot be duplicated. + /// + /// True if this function contains one or more indirect branches, or it contains + /// one or more 'noduplicate' instructions. + bool notDuplicatable; + + /// \brief True if this function calls alloca (in the C sense). + bool usesDynamicAlloca; + + /// \brief Number of instructions in the analyzed blocks. + unsigned NumInsts; - /// \brief Check whether an instruction is likely to be "free" when lowered. - bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0); + /// \brief Number of analyzed blocks. + unsigned NumBlocks; - /// \brief Check whether a call will lower to something small. + /// \brief Keeps track of basic block code size estimates. + DenseMap<const BasicBlock *, unsigned> NumBBInsts; + + /// \brief Keep track of the number of calls to 'big' functions. + unsigned NumCalls; + + /// \brief The number of calls to internal functions with a single caller. /// - /// This tests checks whether this callsite will lower to something - /// significantly cheaper than a traditional call, often a single - /// instruction. Note that if isInstructionFree(CS.getInstruction()) would - /// return true, so will this function. - bool callIsSmall(ImmutableCallSite CS); - - /// \brief Utility to calculate the size and a few similar metrics for a set - /// of basic blocks. - struct CodeMetrics { - /// \brief True if this function contains a call to setjmp or other functions - /// with attribute "returns twice" without having the attribute itself. - bool exposesReturnsTwice; - - /// \brief True if this function calls itself. - bool isRecursive; - - /// \brief True if this function contains one or more indirect branches. - bool containsIndirectBr; - - /// \brief True if this function calls alloca (in the C sense). - bool usesDynamicAlloca; - - /// \brief Number of instructions in the analyzed blocks. - unsigned NumInsts; - - /// \brief Number of analyzed blocks. - unsigned NumBlocks; - - /// \brief Keeps track of basic block code size estimates. - DenseMap<const BasicBlock *, unsigned> NumBBInsts; - - /// \brief Keep track of the number of calls to 'big' functions. - unsigned NumCalls; - - /// \brief The number of calls to internal functions with a single caller. - /// - /// These are likely targets for future inlining, likely exposed by - /// interleaved devirtualization. - unsigned NumInlineCandidates; - - /// \brief How many instructions produce vector values. - /// - /// The inliner is more aggressive with inlining vector kernels. - unsigned NumVectorInsts; - - /// \brief How many 'ret' instructions the blocks contain. - unsigned NumRets; - - CodeMetrics() : exposesReturnsTwice(false), isRecursive(false), - containsIndirectBr(false), usesDynamicAlloca(false), - NumInsts(0), NumBlocks(0), NumCalls(0), - NumInlineCandidates(0), NumVectorInsts(0), - NumRets(0) {} - - /// \brief Add information about a block to the current state. - void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0); - - /// \brief Add information about a function to the current state. - void analyzeFunction(Function *F, const DataLayout *TD = 0); - }; + /// These are likely targets for future inlining, likely exposed by + /// interleaved devirtualization. + unsigned NumInlineCandidates; + + /// \brief How many instructions produce vector values. + /// + /// The inliner is more aggressive with inlining vector kernels. + unsigned NumVectorInsts; + + /// \brief How many 'ret' instructions the blocks contain. + unsigned NumRets; + + CodeMetrics() + : exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false), + usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0), + NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {} + + /// \brief Add information about a block to the current state. + void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI); +}; + } #endif diff --git a/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h b/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h index b701b8f..0fc1c2d 100644 --- a/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -11,27 +11,25 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H -#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H +#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H +#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H -#include "llvm/Pass.h" #include "llvm/Analysis/CFGPrinter.h" +#include "llvm/Pass.h" namespace llvm { -template <class Analysis, bool Simple> -struct DOTGraphTraitsViewer : public FunctionPass { - std::string Name; - DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) { - Name = GraphName; - } +template <class Analysis, bool Simple> +class DOTGraphTraitsViewer : public FunctionPass { +public: + DOTGraphTraitsViewer(StringRef GraphName, char &ID) + : FunctionPass(ID), Name(GraphName) {} virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Title, GraphName; - Graph = &getAnalysis<Analysis>(); - GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); - Title = GraphName + " for '" + F.getName().str() + "' function"; + Analysis *Graph = &getAnalysis<Analysis>(); + std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); + std::string Title = GraphName + " for '" + F.getName().str() + "' function"; + ViewGraph(Graph, Name, Simple, Title); return false; @@ -41,36 +39,92 @@ struct DOTGraphTraitsViewer : public FunctionPass { AU.setPreservesAll(); AU.addRequired<Analysis>(); } + +private: + std::string Name; }; template <class Analysis, bool Simple> -struct DOTGraphTraitsPrinter : public FunctionPass { +class DOTGraphTraitsPrinter : public FunctionPass { +public: + DOTGraphTraitsPrinter(StringRef GraphName, char &ID) + : FunctionPass(ID), Name(GraphName) {} + + virtual bool runOnFunction(Function &F) { + Analysis *Graph = &getAnalysis<Analysis>(); + std::string Filename = Name + "." + F.getName().str() + ".dot"; + std::string ErrorInfo; + + errs() << "Writing '" << Filename << "'..."; + raw_fd_ostream File(Filename.c_str(), ErrorInfo); + std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); + std::string Title = GraphName + " for '" + F.getName().str() + "' function"; + + if (ErrorInfo.empty()) + WriteGraph(File, Graph, Simple, Title); + else + errs() << " error opening file for writing!"; + errs() << "\n"; + + return false; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<Analysis>(); + } + +private: std::string Name; +}; + +template <class Analysis, bool Simple> +class DOTGraphTraitsModuleViewer : public ModulePass { +public: + DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) + : ModulePass(ID), Name(GraphName) {} - DOTGraphTraitsPrinter(std::string GraphName, char &ID) - : FunctionPass(ID) { - Name = GraphName; + virtual bool runOnModule(Module &M) { + Analysis *Graph = &getAnalysis<Analysis>(); + std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph); + + ViewGraph(Graph, Name, Simple, Title); + + return false; } - virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Filename = Name + "." + F.getName().str() + ".dot"; - errs() << "Writing '" << Filename << "'..."; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<Analysis>(); + } +private: + std::string Name; +}; + +template <class Analysis, bool Simple> +class DOTGraphTraitsModulePrinter : public ModulePass { +public: + DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) + : ModulePass(ID), Name(GraphName) {} + + virtual bool runOnModule(Module &M) { + Analysis *Graph = &getAnalysis<Analysis>(); + std::string Filename = Name + ".dot"; std::string ErrorInfo; - raw_fd_ostream File(Filename.c_str(), ErrorInfo); - Graph = &getAnalysis<Analysis>(); - std::string Title, GraphName; - GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); - Title = GraphName + " for '" + F.getName().str() + "' function"; + errs() << "Writing '" << Filename << "'..."; + + raw_fd_ostream File(Filename.c_str(), ErrorInfo); + std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph); if (ErrorInfo.empty()) WriteGraph(File, Graph, Simple, Title); else errs() << " error opening file for writing!"; errs() << "\n"; + return false; } @@ -78,6 +132,11 @@ struct DOTGraphTraitsPrinter : public FunctionPass { AU.setPreservesAll(); AU.addRequired<Analysis>(); } + +private: + std::string Name; }; -} + +} // end namespace llvm + #endif diff --git a/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h index b4327ee..a78ac59 100644 --- a/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h @@ -18,6 +18,16 @@ // of memory references in a function, returning either NULL, for no dependence, // or a more-or-less detailed description of the dependence between them. // +// This pass exists to support the DependenceGraph pass. There are two separate +// passes because there's a useful separation of concerns. A dependence exists +// if two conditions are met: +// +// 1) Two instructions reference the same memory location, and +// 2) There is a flow of control leading from one instruction to the other. +// +// DependenceAnalysis attacks the first condition; DependenceGraph will attack +// the second (it's not yet ready). +// // Please note that this is work in progress and the interface is subject to // change. // @@ -30,9 +40,9 @@ #ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H -#include "llvm/Instructions.h" -#include "llvm/Pass.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/IR/Instructions.h" +#include "llvm/Pass.h" namespace llvm { class AliasAnalysis; @@ -53,8 +63,8 @@ namespace llvm { /// input dependences are unordered. class Dependence { public: - Dependence(const Instruction *Source, - const Instruction *Destination) : + Dependence(Instruction *Source, + Instruction *Destination) : Src(Source), Dst(Destination) {} virtual ~Dependence() {} @@ -82,11 +92,11 @@ namespace llvm { /// getSrc - Returns the source instruction for this dependence. /// - const Instruction *getSrc() const { return Src; } + Instruction *getSrc() const { return Src; } /// getDst - Returns the destination instruction for this dependence. /// - const Instruction *getDst() const { return Dst; } + Instruction *getDst() const { return Dst; } /// isInput - Returns true if this is an input dependence. /// @@ -158,14 +168,14 @@ namespace llvm { /// void dump(raw_ostream &OS) const; private: - const Instruction *Src, *Dst; + Instruction *Src, *Dst; friend class DependenceAnalysis; }; /// FullDependence - This class represents a dependence between two memory /// references in a function. It contains detailed information about the - /// dependence (direction vectors, etc) and is used when the compiler is + /// dependence (direction vectors, etc.) and is used when the compiler is /// able to accurately analyze the interaction of the references; that is, /// it is not a confused dependence (see Dependence). In most cases /// (for output, flow, and anti dependences), the dependence implies an @@ -173,12 +183,12 @@ namespace llvm { /// input dependences are unordered. class FullDependence : public Dependence { public: - FullDependence(const Instruction *Src, - const Instruction *Dst, + FullDependence(Instruction *Src, + Instruction *Dst, bool LoopIndependent, unsigned Levels); ~FullDependence() { - delete DV; + delete[] DV; } /// isLoopIndependent - Returns true if this is a loop-independent @@ -234,8 +244,8 @@ namespace llvm { /// DependenceAnalysis - This class is the main dependence-analysis driver. /// class DependenceAnalysis : public FunctionPass { - void operator=(const DependenceAnalysis &); // do not implement - DependenceAnalysis(const DependenceAnalysis &); // do not implement + void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION; + DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION; public: /// depends - Tests for a dependence between the Src and Dst instructions. /// Returns NULL if no dependence; otherwise, returns a Dependence (or a @@ -243,11 +253,11 @@ namespace llvm { /// The flag PossiblyLoopIndependent should be set by the caller /// if it appears that control flow can reach from Src to Dst /// without traversing a loop back edge. - Dependence *depends(const Instruction *Src, - const Instruction *Dst, + Dependence *depends(Instruction *Src, + Instruction *Dst, bool PossiblyLoopIndependent); - /// getSplitIteration - Give a dependence that's splitable at some + /// getSplitIteration - Give a dependence that's splittable at some /// particular level, return the iteration that should be used to split /// the loop. /// diff --git a/contrib/llvm/include/llvm/Analysis/DominatorInternals.h b/contrib/llvm/include/llvm/Analysis/DominatorInternals.h index 0c29236..c0f95cb 100644 --- a/contrib/llvm/include/llvm/Analysis/DominatorInternals.h +++ b/contrib/llvm/include/llvm/Analysis/DominatorInternals.h @@ -10,8 +10,8 @@ #ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H #define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H -#include "llvm/Analysis/Dominators.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/Dominators.h" //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/include/llvm/Analysis/Dominators.h b/contrib/llvm/include/llvm/Analysis/Dominators.h index 8940971..81c04bb 100644 --- a/contrib/llvm/include/llvm/Analysis/Dominators.h +++ b/contrib/llvm/include/llvm/Analysis/Dominators.h @@ -15,13 +15,13 @@ #ifndef LLVM_ANALYSIS_DOMINATORS_H #define LLVM_ANALYSIS_DOMINATORS_H -#include "llvm/Pass.h" -#include "llvm/Function.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Function.h" +#include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -101,18 +101,18 @@ public: Children.clear(); } - bool compare(DomTreeNodeBase<NodeT> *Other) { + bool compare(const DomTreeNodeBase<NodeT> *Other) const { if (getNumChildren() != Other->getNumChildren()) return true; - SmallPtrSet<NodeT *, 4> OtherChildren; - for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) { - NodeT *Nd = (*I)->getBlock(); + SmallPtrSet<const NodeT *, 4> OtherChildren; + for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) { + const NodeT *Nd = (*I)->getBlock(); OtherChildren.insert(Nd); } - for (iterator I = begin(), E = end(); I != E; ++I) { - NodeT *N = (*I)->getBlock(); + for (const_iterator I = begin(), E = end(); I != E; ++I) { + const NodeT *N = (*I)->getBlock(); if (OtherChildren.count(N) == 0) return true; } @@ -663,8 +663,7 @@ public: // Initialize the roots list for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), E = TraitsTy::nodes_end(&F); I != E; ++I) { - if (std::distance(TraitsTy::child_begin(I), - TraitsTy::child_end(I)) == 0) + if (TraitsTy::child_begin(I) == TraitsTy::child_end(I)) addRoot(I); // Prepopulate maps so that we don't get iterator invalidation issues later. diff --git a/contrib/llvm/include/llvm/Analysis/IVUsers.h b/contrib/llvm/include/llvm/Analysis/IVUsers.h index 9b98013..c982801 100644 --- a/contrib/llvm/include/llvm/Analysis/IVUsers.h +++ b/contrib/llvm/include/llvm/Analysis/IVUsers.h @@ -24,7 +24,6 @@ namespace llvm { class DominatorTree; class Instruction; class Value; -class IVUsers; class ScalarEvolution; class SCEV; class IVUsers; diff --git a/contrib/llvm/include/llvm/Analysis/InlineCost.h b/contrib/llvm/include/llvm/Analysis/InlineCost.h index a075db3..bc7924e 100644 --- a/contrib/llvm/include/llvm/Analysis/InlineCost.h +++ b/contrib/llvm/include/llvm/Analysis/InlineCost.h @@ -14,122 +14,130 @@ #ifndef LLVM_ANALYSIS_INLINECOST_H #define LLVM_ANALYSIS_INLINECOST_H -#include "llvm/Function.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/ValueMap.h" #include "llvm/Analysis/CodeMetrics.h" +#include "llvm/Analysis/CallGraphSCCPass.h" #include <cassert> #include <climits> -#include <vector> namespace llvm { +class CallSite; +class DataLayout; +class Function; +class TargetTransformInfo; + +namespace InlineConstants { + // Various magic constants used to adjust heuristics. + const int InstrCost = 5; + const int IndirectCallThreshold = 100; + const int CallPenalty = 25; + const int LastCallToStaticBonus = -15000; + const int ColdccPenalty = 2000; + const int NoreturnPenalty = 10000; + /// Do not inline functions which allocate this many bytes on the stack + /// when the caller is recursive. + const unsigned TotalAllocaSizeRecursiveCaller = 1024; +} + +/// \brief Represents 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 likelihood of the function being inlined. +/// +/// Objects of this type also provide the adjusted threshold for inlining +/// based on the information available for a particular callsite. They can be +/// directly tested to determine if inlining should occur given the cost and +/// threshold for this cost metric. +class InlineCost { + enum SentinelValues { + AlwaysInlineCost = INT_MIN, + NeverInlineCost = INT_MAX + }; + + /// \brief The estimated cost of inlining this callsite. + const int Cost; + + /// \brief The adjusted threshold against which this cost was computed. + const int Threshold; + + // Trivial constructor, interesting logic in the factory functions below. + InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {} + +public: + static InlineCost get(int Cost, int Threshold) { + assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); + assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); + return InlineCost(Cost, Threshold); + } + static InlineCost getAlways() { + return InlineCost(AlwaysInlineCost, 0); + } + static InlineCost getNever() { + return InlineCost(NeverInlineCost, 0); + } - class CallSite; - class DataLayout; - - namespace InlineConstants { - // Various magic constants used to adjust heuristics. - const int InstrCost = 5; - const int IndirectCallThreshold = 100; - const int CallPenalty = 25; - const int LastCallToStaticBonus = -15000; - const int ColdccPenalty = 2000; - const int NoreturnPenalty = 10000; - /// Do not inline functions which allocate this many bytes on the stack - /// when the caller is recursive. - const unsigned TotalAllocaSizeRecursiveCaller = 1024; + /// \brief Test whether the inline cost is low enough for inlining. + operator bool() const { + return Cost < Threshold; } - /// \brief Represents the cost of inlining a function. + bool isAlways() const { return Cost == AlwaysInlineCost; } + bool isNever() const { return Cost == NeverInlineCost; } + bool isVariable() const { return !isAlways() && !isNever(); } + + /// \brief Get the inline cost estimate. + /// It is an error to call this on an "always" or "never" InlineCost. + int getCost() const { + assert(isVariable() && "Invalid access of InlineCost"); + return Cost; + } + + /// \brief Get the cost delta from the threshold for inlining. + /// Only valid if the cost is of the variable kind. Returns a negative + /// value if the cost is too high to inline. + int getCostDelta() const { return Threshold - getCost(); } +}; + +/// \brief Cost analyzer used by inliner. +class InlineCostAnalysis : public CallGraphSCCPass { + const DataLayout *TD; + const TargetTransformInfo *TTI; + +public: + static char ID; + + InlineCostAnalysis(); + ~InlineCostAnalysis(); + + // Pass interface implementation. + void getAnalysisUsage(AnalysisUsage &AU) const; + bool runOnSCC(CallGraphSCC &SCC); + + /// \brief Get an InlineCost object representing the cost of inlining this + /// callsite. /// - /// This supports special values for functions which should "always" or - /// "never" be inlined. Otherwise, the cost represents a unitless amount; - /// smaller values increase the likelihood of the function being inlined. + /// Note that threshold is passed into this function. Only costs below the + /// threshold are computed with any accuracy. The threshold can be used to + /// bound the computation necessary to determine whether the cost is + /// sufficiently low to warrant inlining. /// - /// Objects of this type also provide the adjusted threshold for inlining - /// based on the information available for a particular callsite. They can be - /// directly tested to determine if inlining should occur given the cost and - /// threshold for this cost metric. - class InlineCost { - enum SentinelValues { - AlwaysInlineCost = INT_MIN, - NeverInlineCost = INT_MAX - }; - - /// \brief The estimated cost of inlining this callsite. - const int Cost; - - /// \brief The adjusted threshold against which this cost was computed. - const int Threshold; - - // Trivial constructor, interesting logic in the factory functions below. - InlineCost(int Cost, int Threshold) - : Cost(Cost), Threshold(Threshold) {} - - public: - static InlineCost get(int Cost, int Threshold) { - assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); - assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); - return InlineCost(Cost, Threshold); - } - static InlineCost getAlways() { - return InlineCost(AlwaysInlineCost, 0); - } - static InlineCost getNever() { - return InlineCost(NeverInlineCost, 0); - } - - /// \brief Test whether the inline cost is low enough for inlining. - operator bool() const { - return Cost < Threshold; - } - - bool isAlways() const { return Cost == AlwaysInlineCost; } - bool isNever() const { return Cost == NeverInlineCost; } - bool isVariable() const { return !isAlways() && !isNever(); } - - /// \brief Get the inline cost estimate. - /// It is an error to call this on an "always" or "never" InlineCost. - int getCost() const { - assert(isVariable() && "Invalid access of InlineCost"); - return Cost; - } - - /// \brief Get the cost delta from the threshold for inlining. - /// Only valid if the cost is of the variable kind. Returns a negative - /// value if the cost is too high to inline. - int getCostDelta() const { return Threshold - getCost(); } - }; + /// Also note that calling this function *dynamically* computes the cost of + /// inlining the callsite. It is an expensive, heavyweight call. + InlineCost getInlineCost(CallSite CS, int Threshold); + + /// \brief Get an InlineCost with the callee explicitly specified. + /// This allows you to calculate the cost of inlining a function via a + /// pointer. This behaves exactly as the version with no explicit callee + /// parameter in all other respects. + // + // Note: This is used by out-of-tree passes, please do not remove without + // adding a replacement API. + InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); + + /// \brief Minimal filter to detect invalid constructs for inlining. + bool isInlineViable(Function &Callee); +}; - /// InlineCostAnalyzer - Cost analyzer used by inliner. - class InlineCostAnalyzer { - // DataLayout if available, or null. - const DataLayout *TD; - - public: - InlineCostAnalyzer(): TD(0) {} - - void setDataLayout(const DataLayout *TData) { TD = TData; } - - /// \brief Get an InlineCost object representing the cost of inlining this - /// callsite. - /// - /// Note that threshold is passed into this function. Only costs below the - /// threshold are computed with any accuracy. The threshold can be used to - /// bound the computation necessary to determine whether the cost is - /// sufficiently low to warrant inlining. - InlineCost getInlineCost(CallSite CS, int Threshold); - /// getCalledFunction - The heuristic used to determine if we should inline - /// the function call or not. The callee is explicitly specified, to allow - /// you to calculate the cost of inlining a function via a pointer. This - /// behaves exactly as the version with no explicit callee parameter in all - /// other respects. - // - // Note: This is used by out-of-tree passes, please do not remove without - // adding a replacement API. - InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); - }; } #endif diff --git a/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h index e561e37..d760a4c 100644 --- a/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -14,17 +14,33 @@ // ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction // then it dominates the original instruction. // +// These routines implicitly resolve undef uses. The easiest way to be safe when +// using these routines to obtain simplified values for existing instructions is +// to always replace all uses of the instructions with the resulting simplified +// values. This will prevent other code from seeing the same undef uses and +// resolving them to different values. +// +// These routines are designed to tolerate moderately incomplete IR, such as +// instructions that are not connected to basic blocks yet. However, they do +// require that all the IR that they encounter be valid. In particular, they +// require that all non-constant values be defined in the same function, and the +// same call context of that function (and not split between caller and callee +// contexts of a directly recursive call, for example). +// //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H +#include "llvm/IR/User.h" + namespace llvm { template<typename T> class ArrayRef; class DominatorTree; class Instruction; class DataLayout; + class FastMathFlags; class TargetLibraryInfo; class Type; class Value; @@ -43,6 +59,28 @@ namespace llvm { const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); + /// Given operands for an FAdd, see if we can fold the result. If not, this + /// returns null. + Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + + /// Given operands for an FSub, see if we can fold the result. If not, this + /// returns null. + Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, + const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + + /// Given operands for an FMul, see if we can fold the result. If not, this + /// returns null. + Value *SimplifyFMulInst(Value *LHS, Value *RHS, + FastMathFlags FMF, + const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + /// SimplifyMulInst - Given operands for a Mul, see if we can /// fold the result. If not, this returns null. Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, @@ -57,7 +95,7 @@ namespace llvm { /// SimplifyUDivInst - Given operands for a UDiv, see if we can /// fold the result. If not, this returns null. - Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, + Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); @@ -69,7 +107,7 @@ namespace llvm { /// 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 DataLayout *TD = 0, + Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); @@ -88,7 +126,7 @@ namespace llvm { /// 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, - const DataLayout *TD = 0, + const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); @@ -127,14 +165,14 @@ namespace llvm { /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout *TD = 0, + const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout *TD = 0, + const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); @@ -178,10 +216,28 @@ namespace llvm { /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// fold the result. If not, this returns null. Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const DataLayout *TD = 0, + const DataLayout *TD = 0, const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); + /// \brief Given a function and iterators over arguments, see if we can fold + /// the result. + /// + /// If this call could not be simplified returns null. + Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, + User::op_iterator ArgEnd, const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + + /// \brief Given a function and set of arguments, see if we can fold the + /// result. + /// + /// If this call could not be simplified returns null. + Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, + const DataLayout *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + /// SimplifyInstruction - See if we can compute a simplified version of this /// instruction. If not, this returns null. Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0, diff --git a/contrib/llvm/include/llvm/Analysis/Interval.h b/contrib/llvm/include/llvm/Analysis/Interval.h index ca8ad73..5ce1260 100644 --- a/contrib/llvm/include/llvm/Analysis/Interval.h +++ b/contrib/llvm/include/llvm/Analysis/Interval.h @@ -17,8 +17,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INTERVAL_H -#define LLVM_INTERVAL_H +#ifndef LLVM_ANALYSIS_INTERVAL_H +#define LLVM_ANALYSIS_INTERVAL_H #include "llvm/ADT/GraphTraits.h" #include <vector> diff --git a/contrib/llvm/include/llvm/Analysis/IntervalIterator.h b/contrib/llvm/include/llvm/Analysis/IntervalIterator.h index 0968c74..22067c4 100644 --- a/contrib/llvm/include/llvm/Analysis/IntervalIterator.h +++ b/contrib/llvm/include/llvm/Analysis/IntervalIterator.h @@ -30,11 +30,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INTERVAL_ITERATOR_H -#define LLVM_INTERVAL_ITERATOR_H +#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H +#define LLVM_ANALYSIS_INTERVALITERATOR_H #include "llvm/Analysis/IntervalPartition.h" -#include "llvm/Function.h" +#include "llvm/IR/Function.h" #include "llvm/Support/CFG.h" #include <algorithm> #include <set> @@ -157,7 +157,7 @@ public: private: // ProcessInterval - This method is used during the construction of the // interval graph. It walks through the source graph, recursively creating - // an interval per invokation until the entire graph is covered. This uses + // an interval per invocation until the entire graph is covered. This uses // the ProcessNode method to add all of the nodes to the interval. // // This method is templated because it may operate on two different source diff --git a/contrib/llvm/include/llvm/Analysis/IntervalPartition.h b/contrib/llvm/include/llvm/Analysis/IntervalPartition.h index bce84be..8cade58 100644 --- a/contrib/llvm/include/llvm/Analysis/IntervalPartition.h +++ b/contrib/llvm/include/llvm/Analysis/IntervalPartition.h @@ -20,8 +20,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INTERVAL_PARTITION_H -#define LLVM_INTERVAL_PARTITION_H +#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H +#define LLVM_ANALYSIS_INTERVALPARTITION_H #include "llvm/Analysis/Interval.h" #include "llvm/Pass.h" diff --git a/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h index 243234b..c01b210 100644 --- a/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LIBCALL_AA_H -#define LLVM_ANALYSIS_LIBCALL_AA_H +#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H +#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Pass.h" diff --git a/contrib/llvm/include/llvm/Analysis/Loads.h b/contrib/llvm/include/llvm/Analysis/Loads.h index afc90c2..ebcb762 100644 --- a/contrib/llvm/include/llvm/Analysis/Loads.h +++ b/contrib/llvm/include/llvm/Analysis/Loads.h @@ -14,7 +14,7 @@ #ifndef LLVM_ANALYSIS_LOADS_H #define LLVM_ANALYSIS_LOADS_H -#include "llvm/BasicBlock.h" +#include "llvm/IR/BasicBlock.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfo.h b/contrib/llvm/include/llvm/Analysis/LoopInfo.h index c5d7b01..783e347 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopInfo.h +++ b/contrib/llvm/include/llvm/Analysis/LoopInfo.h @@ -27,21 +27,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LOOP_INFO_H -#define LLVM_ANALYSIS_LOOP_INFO_H +#ifndef LLVM_ANALYSIS_LOOPINFO_H +#define LLVM_ANALYSIS_LOOPINFO_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/Dominators.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Pass.h" #include <algorithm> -#include <map> namespace llvm { @@ -56,6 +51,7 @@ class DominatorTree; class LoopInfo; class Loop; class PHINode; +class raw_ostream; template<class N, class M> class LoopInfoBase; template<class N, class M> class LoopBase; @@ -151,10 +147,10 @@ public: /// block that is outside of the current loop. /// bool isLoopExiting(const BlockT *BB) const { - typedef GraphTraits<BlockT*> BlockTraits; + typedef GraphTraits<const BlockT*> BlockTraits; for (typename BlockTraits::ChildIteratorType SI = - BlockTraits::child_begin(const_cast<BlockT*>(BB)), - SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++SI) { + BlockTraits::child_begin(BB), + SE = BlockTraits::child_end(BB); SI != SE; ++SI) { if (!contains(*SI)) return true; } @@ -169,8 +165,8 @@ public: typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; for (typename InvBlockTraits::ChildIteratorType I = - InvBlockTraits::child_begin(const_cast<BlockT*>(H)), - E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I) + InvBlockTraits::child_begin(H), + E = InvBlockTraits::child_end(H); I != E; ++I) if (contains(*I)) ++NumBackEdges; @@ -381,6 +377,20 @@ public: /// isSafeToClone - Return true if the loop body is safe to clone in practice. bool isSafeToClone() const; + /// Returns true if the loop is annotated parallel. + /// + /// A parallel loop can be assumed to not contain any dependencies between + /// iterations by the compiler. That is, any loop-carried dependency checking + /// can be skipped completely when parallelizing the loop on the target + /// machine. Thus, if the parallel loop information originates from the + /// programmer, e.g. via the OpenMP parallel for pragma, it is the + /// programmer's responsibility to ensure there are no loop-carried + /// dependencies. The final execution order of the instructions across + /// iterations is not guaranteed, thus, the end result might or might not + /// implement actual concurrent execution of instructions across multiple + /// iterations. + bool isAnnotatedParallel() const; + /// hasDedicatedExits - Return true if no exit block for the loop /// has a predecessor that is outside the loop. bool hasDedicatedExits() const; diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h index 3bb96f9..5485f3c 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h +++ b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h @@ -12,11 +12,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H -#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H +#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H +#define LLVM_ANALYSIS_LOOPINFOIMPL_H -#include "llvm/Analysis/LoopInfo.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Analysis/LoopInfo.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/LoopIterator.h b/contrib/llvm/include/llvm/Analysis/LoopIterator.h index 68f25f7..e3dd963 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopIterator.h +++ b/contrib/llvm/include/llvm/Analysis/LoopIterator.h @@ -21,10 +21,9 @@ // reachable from the loop header. //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H -#define LLVM_ANALYSIS_LOOP_ITERATOR_H +#ifndef LLVM_ANALYSIS_LOOPITERATOR_H +#define LLVM_ANALYSIS_LOOPITERATOR_H -#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/Analysis/LoopInfo.h" diff --git a/contrib/llvm/include/llvm/Analysis/LoopPass.h b/contrib/llvm/include/llvm/Analysis/LoopPass.h index e6ed9bc..5767c19 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopPass.h +++ b/contrib/llvm/include/llvm/Analysis/LoopPass.h @@ -12,13 +12,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LOOP_PASS_H -#define LLVM_LOOP_PASS_H +#ifndef LLVM_ANALYSIS_LOOPPASS_H +#define LLVM_ANALYSIS_LOOPPASS_H #include "llvm/Analysis/LoopInfo.h" #include "llvm/Pass.h" #include "llvm/PassManagers.h" -#include "llvm/Function.h" #include <deque> namespace llvm { @@ -39,6 +38,9 @@ public: // whatever action is necessary for the specified Loop. virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + // Initialization and finalization hooks. virtual bool doInitialization(Loop *L, LPPassManager &LPM) { return false; diff --git a/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h index a842898..63262eb 100644 --- a/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -15,12 +15,12 @@ #ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H #define LLVM_ANALYSIS_MEMORYBUILTINS_H -#include "llvm/IRBuilder.h" -#include "llvm/Operator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Operator.h" +#include "llvm/InstVisitor.h" #include "llvm/Support/DataTypes.h" -#include "llvm/Support/InstVisitor.h" #include "llvm/Support/TargetFolder.h" #include "llvm/Support/ValueHandle.h" @@ -138,12 +138,22 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { // /// \brief Compute the size of the object pointed by Ptr. Returns true and the -/// object size in Size if successful, and false otherwise. +/// object size in Size if successful, and false otherwise. In this context, by +/// object we mean the region of memory starting at Ptr to the end of the +/// underlying object pointed to by Ptr. /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas, /// byval arguments, and global variables. bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD, const TargetLibraryInfo *TLI, bool RoundToAlign = false); +/// \brief Compute the size of the underlying object pointed by Ptr. Returns +/// true and the object size in Size if successful, and false otherwise. +/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas, +/// byval arguments, and global variables. +bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size, + const DataLayout *TD, const TargetLibraryInfo *TLI, + bool RoundToAlign = false); + typedef std::pair<APInt, APInt> SizeOffsetType; @@ -153,12 +163,14 @@ typedef std::pair<APInt, APInt> SizeOffsetType; class ObjectSizeOffsetVisitor : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> { + typedef DenseMap<const Value*, SizeOffsetType> CacheMapTy; + const DataLayout *TD; const TargetLibraryInfo *TLI; bool RoundToAlign; unsigned IntTyBits; APInt Zero; - SmallPtrSet<Instruction *, 8> SeenInsts; + CacheMapTy CacheMap; APInt align(APInt Size, uint64_t Align); @@ -191,6 +203,7 @@ public: SizeOffsetType visitExtractElementInst(ExtractElementInst &I); SizeOffsetType visitExtractValueInst(ExtractValueInst &I); SizeOffsetType visitGEPOperator(GEPOperator &GEP); + SizeOffsetType visitGlobalAlias(GlobalAlias &GA); SizeOffsetType visitGlobalVariable(GlobalVariable &GV); SizeOffsetType visitIntToPtrInst(IntToPtrInst&); SizeOffsetType visitLoadInst(LoadInst &I); diff --git a/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h index a715eae..47afd1b 100644 --- a/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -11,17 +11,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H -#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H +#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H +#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H -#include "llvm/BasicBlock.h" -#include "llvm/Pass.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/Pass.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { class Function; @@ -34,14 +34,14 @@ namespace llvm { class PredIteratorCache; class DominatorTree; class PHITransAddr; - + /// MemDepResult - A memory dependence query can return one of three different /// answers, described below. class MemDepResult { enum DepType { /// Invalid - Clients of MemDep never see this. Invalid = 0, - + /// Clobber - This is a dependence on the specified instruction which /// clobbers the desired value. The pointer member of the MemDepResult /// pair holds the instruction that clobbers the memory. For example, @@ -72,7 +72,7 @@ namespace llvm { /// and no intervening clobbers. No validation is done that the /// operands to the calls are the same. Def, - + /// Other - This marker indicates that the query has no known dependency /// in the specified block. More detailed state info is encoded in the /// upper part of the pair (i.e. the Instruction*) @@ -99,7 +99,7 @@ namespace llvm { explicit MemDepResult(PairTy V) : Value(V) {} public: MemDepResult() : Value(0, Invalid) {} - + /// get methods: These are static ctor methods for creating various /// MemDepResult kinds. static MemDepResult getDef(Instruction *Inst) { @@ -130,7 +130,7 @@ namespace llvm { /// isDef - Return true if this MemDepResult represents a query that is /// an instruction definition dependency. bool isDef() const { return Value.getInt() == Def; } - + /// isNonLocal - Return true if this MemDepResult represents a query that /// is transparent to the start of the block, but where a non-local hasn't /// been done. @@ -145,7 +145,7 @@ namespace llvm { return Value.getInt() == Other && Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal); } - + /// isUnknown - Return true if this MemDepResult represents a query which /// cannot and/or will not be computed. bool isUnknown() const { @@ -159,7 +159,7 @@ namespace llvm { if (Value.getInt() == Other) return NULL; return Value.getPointer(); } - + bool operator==(const MemDepResult &M) const { return Value == M.Value; } bool operator!=(const MemDepResult &M) const { return Value != M.Value; } bool operator<(const MemDepResult &M) const { return Value < M.Value; } @@ -175,11 +175,11 @@ namespace llvm { /// In a default-constructed MemDepResult object, the type will be Dirty /// and the instruction pointer will be null. /// - + /// isDirty - Return true if this is a MemDepResult in its dirty/invalid. /// state. bool isDirty() const { return Value.getInt() == Invalid; } - + static MemDepResult getDirty(Instruction *Inst) { return MemDepResult(PairTy(Inst, Invalid)); } @@ -199,16 +199,16 @@ namespace llvm { // BB is the sort key, it can't be changed. BasicBlock *getBB() const { return BB; } - + void setResult(const MemDepResult &R) { Result = R; } const MemDepResult &getResult() const { return Result; } - + bool operator<(const NonLocalDepEntry &RHS) const { return BB < RHS.BB; } }; - + /// NonLocalDepResult - This is a result from a NonLocal dependence query. /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the /// (potentially phi translated) address that was live in the block. @@ -218,17 +218,17 @@ namespace llvm { public: NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address) : Entry(bb, result), Address(address) {} - + // BB is the sort key, it can't be changed. BasicBlock *getBB() const { return Entry.getBB(); } - + void setResult(const MemDepResult &R, Value *Addr) { Entry.setResult(R); Address = Addr; } - + const MemDepResult &getResult() const { return Entry.getResult(); } - + /// getAddress - Return the address of this pointer in this block. This can /// be different than the address queried for the non-local result because /// of phi translation. This returns null if the address was not available @@ -238,7 +238,7 @@ namespace llvm { /// The address is always null for a non-local 'call' dependence. Value *getAddress() const { return Address; } }; - + /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, @@ -297,30 +297,30 @@ namespace llvm { CachedNonLocalPointerInfo NonLocalPointerDeps; // A map from instructions to their non-local pointer dependencies. - typedef DenseMap<Instruction*, + typedef DenseMap<Instruction*, SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy; ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps; - + /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and /// the bool indicates whether we have any dirty bits in the set. typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo; - + // A map from instructions to their non-local dependencies. typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType; - + NonLocalDepMapType NonLocalDeps; - + // A reverse mapping from dependencies to the dependees. This is // used when removing instructions to keep the cache coherent. typedef DenseMap<Instruction*, SmallPtrSet<Instruction*, 4> > ReverseDepMapType; ReverseDepMapType ReverseLocalDeps; - + // A reverse mapping from dependencies to the non-local dependees. ReverseDepMapType ReverseNonLocalDeps; - + /// Current AA implementation, just a cache. AliasAnalysis *AA; DataLayout *TD; @@ -333,15 +333,15 @@ namespace llvm { /// Pass Implementation stuff. This doesn't do any analysis eagerly. bool runOnFunction(Function &); - + /// Clean up memory in between runs void releaseMemory(); - + /// getAnalysisUsage - Does not modify anything. It uses Value Numbering /// and Alias Analysis. /// virtual void getAnalysisUsage(AnalysisUsage &AU) const; - + /// getDependency - Return the instruction on which a memory operation /// depends. See the class comment for more details. It is illegal to call /// this on non-memory instructions. @@ -360,8 +360,8 @@ namespace llvm { /// removed. Clients must copy this data if they want it around longer than /// that. const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS); - - + + /// getNonLocalPointerDependency - Perform a full dependency query for an /// access to the specified (non-volatile) memory location, returning the /// set of instructions that either define or clobber the value. @@ -374,7 +374,7 @@ namespace llvm { /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); - + /// invalidateCachedPointerInfo - This method is used to invalidate cached /// information about the specified pointer, because it may be too /// conservative in memdep. This is an optional call that can be used when @@ -387,20 +387,23 @@ namespace llvm { /// This needs to be done when the CFG changes, e.g., due to splitting /// critical edges. void invalidateCachedPredecessors(); - + /// getPointerDependencyFrom - Return the instruction on which a memory /// location depends. If isLoad is true, this routine ignores may-aliases /// with read-only operations. If isLoad is false, this routine ignores - /// may-aliases with reads from read-only locations. + /// may-aliases with reads from read-only locations. If possible, pass + /// the query instruction as well; this function may take advantage of + /// the metadata annotated to the query instruction to refine the result. /// /// Note that this is an uncached query, and thus may be inefficient. /// MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc, - bool isLoad, + bool isLoad, BasicBlock::iterator ScanIt, - BasicBlock *BB); - - + BasicBlock *BB, + Instruction *QueryInst = 0); + + /// 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 @@ -413,7 +416,7 @@ namespace llvm { unsigned MemLocSize, const LoadInst *LI, const DataLayout &TD); - + private: MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, @@ -430,11 +433,11 @@ namespace llvm { unsigned NumSortedEntries); void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P); - + /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - + }; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/Analysis/PHITransAddr.h b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h index 5a77fce..d7a3dd8 100644 --- a/contrib/llvm/include/llvm/Analysis/PHITransAddr.h +++ b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h @@ -14,8 +14,8 @@ #ifndef LLVM_ANALYSIS_PHITRANSADDR_H #define LLVM_ANALYSIS_PHITRANSADDR_H -#include "llvm/Instruction.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Instruction.h" namespace llvm { class DominatorTree; diff --git a/contrib/llvm/include/llvm/Analysis/Passes.h b/contrib/llvm/include/llvm/Analysis/Passes.h index 27726f4..ae11713 100644 --- a/contrib/llvm/include/llvm/Analysis/Passes.h +++ b/contrib/llvm/include/llvm/Analysis/Passes.h @@ -198,9 +198,6 @@ namespace llvm { // analyze. FunctionPass *createInstCountPass(); - // print debug info intrinsics in human readable form - FunctionPass *createDbgInfoPrinterPass(); - //===--------------------------------------------------------------------===// // // createRegionInfoPass - This pass finds all single entry single exit regions diff --git a/contrib/llvm/include/llvm/Analysis/PathNumbering.h b/contrib/llvm/include/llvm/Analysis/PathNumbering.h index 7025e28..400a37d 100644 --- a/contrib/llvm/include/llvm/Analysis/PathNumbering.h +++ b/contrib/llvm/include/llvm/Analysis/PathNumbering.h @@ -23,14 +23,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_PATH_NUMBERING_H -#define LLVM_PATH_NUMBERING_H +#ifndef LLVM_ANALYSIS_PATHNUMBERING_H +#define LLVM_ANALYSIS_PATHNUMBERING_H -#include "llvm/BasicBlock.h" -#include "llvm/Instructions.h" +#include "llvm/Analysis/ProfileInfoTypes.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" -#include "llvm/Analysis/ProfileInfoTypes.h" #include <map> #include <stack> #include <vector> diff --git a/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h b/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h index cef6d2d..4fce16e 100644 --- a/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h +++ b/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_PATHPROFILEINFO_H -#define LLVM_PATHPROFILEINFO_H +#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H +#define LLVM_ANALYSIS_PATHPROFILEINFO_H -#include "llvm/BasicBlock.h" #include "llvm/Analysis/PathNumbering.h" +#include "llvm/IR/BasicBlock.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/PostDominators.h b/contrib/llvm/include/llvm/Analysis/PostDominators.h index 0eddb91..d082297 100644 --- a/contrib/llvm/include/llvm/Analysis/PostDominators.h +++ b/contrib/llvm/include/llvm/Analysis/PostDominators.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H -#define LLVM_ANALYSIS_POST_DOMINATORS_H +#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H +#define LLVM_ANALYSIS_POSTDOMINATORS_H #include "llvm/Analysis/Dominators.h" diff --git a/contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h b/contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h index 9efbafc..90097f7 100644 --- a/contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h +++ b/contrib/llvm/include/llvm/Analysis/ProfileDataLoader.h @@ -16,6 +16,7 @@ #ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H #define LLVM_ANALYSIS_PROFILEDATALOADER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" diff --git a/contrib/llvm/include/llvm/Analysis/ProfileInfo.h b/contrib/llvm/include/llvm/Analysis/ProfileInfo.h index 6c2e273..5d17fa1 100644 --- a/contrib/llvm/include/llvm/Analysis/ProfileInfo.h +++ b/contrib/llvm/include/llvm/Analysis/ProfileInfo.h @@ -26,9 +26,9 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <cassert> -#include <string> #include <map> #include <set> +#include <string> namespace llvm { class Pass; diff --git a/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h b/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h index dcf3b38..e0f49f3 100644 --- a/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h +++ b/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h @@ -16,9 +16,9 @@ #ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H #define LLVM_ANALYSIS_PROFILEINFOLOADER_H -#include <vector> #include <string> #include <utility> +#include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h b/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h new file mode 100644 index 0000000..1802fe8 --- /dev/null +++ b/contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h @@ -0,0 +1,285 @@ +//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides a collection of visitors which walk the (instruction) +/// uses of a pointer. These visitors all provide the same essential behavior +/// as an InstVisitor with similar template-based flexibility and +/// implementation strategies. +/// +/// These can be used, for example, to quickly analyze the uses of an alloca, +/// global variable, or function argument. +/// +/// FIXME: Provide a variant which doesn't track offsets and is cheaper. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H +#define LLVM_ANALYSIS_PTRUSEVISITOR_H + +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/InstVisitor.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { + +namespace detail { +/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor. +/// +/// See \c PtrUseVisitor for the public interface and detailed comments about +/// usage. This class is just a helper base class which is not templated and +/// contains all common code to be shared between different instantiations of +/// PtrUseVisitor. +class PtrUseVisitorBase { +public: + /// \brief This class provides information about the result of a visit. + /// + /// After walking all the users (recursively) of a pointer, the basic + /// infrastructure records some commonly useful information such as escape + /// analysis and whether the visit completed or aborted early. + class PtrInfo { + public: + PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {} + + /// \brief Reset the pointer info, clearing all state. + void reset() { + AbortedInfo.setPointer(0); + AbortedInfo.setInt(false); + EscapedInfo.setPointer(0); + EscapedInfo.setInt(false); + } + + /// \brief Did we abort the visit early? + bool isAborted() const { return AbortedInfo.getInt(); } + + /// \brief Is the pointer escaped at some point? + bool isEscaped() const { return EscapedInfo.getInt(); } + + /// \brief Get the instruction causing the visit to abort. + /// \returns a pointer to the instruction causing the abort if one is + /// available; otherwise returns null. + Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); } + + /// \brief Get the instruction causing the pointer to escape. + /// \returns a pointer to the instruction which escapes the pointer if one + /// is available; otherwise returns null. + Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); } + + /// \brief Mark the visit as aborted. Intended for use in a void return. + /// \param I The instruction which caused the visit to abort, if available. + void setAborted(Instruction *I = 0) { + AbortedInfo.setInt(true); + AbortedInfo.setPointer(I); + } + + /// \brief Mark the pointer as escaped. Intended for use in a void return. + /// \param I The instruction which escapes the pointer, if available. + void setEscaped(Instruction *I = 0) { + EscapedInfo.setInt(true); + EscapedInfo.setPointer(I); + } + + /// \brief Mark the pointer as escaped, and the visit as aborted. Intended + /// for use in a void return. + /// \param I The instruction which both escapes the pointer and aborts the + /// visit, if available. + void setEscapedAndAborted(Instruction *I = 0) { + setEscaped(I); + setAborted(I); + } + + private: + PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo; + }; + +protected: + const DataLayout &DL; + + /// \name Visitation infrastructure + /// @{ + + /// \brief The info collected about the pointer being visited thus far. + PtrInfo PI; + + /// \brief A struct of the data needed to visit a particular use. + /// + /// This is used to maintain a worklist fo to-visit uses. This is used to + /// make the visit be iterative rather than recursive. + struct UseToVisit { + typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair; + UseAndIsOffsetKnownPair UseAndIsOffsetKnown; + APInt Offset; + }; + + /// \brief The worklist of to-visit uses. + SmallVector<UseToVisit, 8> Worklist; + + /// \brief A set of visited uses to break cycles in unreachable code. + SmallPtrSet<Use *, 8> VisitedUses; + + /// @} + + + /// \name Per-visit state + /// This state is reset for each instruction visited. + /// @{ + + /// \brief The use currently being visited. + Use *U; + + /// \brief True if we have a known constant offset for the use currently + /// being visited. + bool IsOffsetKnown; + + /// \brief The constant offset of the use if that is known. + APInt Offset; + + /// @} + + + /// Note that the constructor is protected because this class must be a base + /// class, we can't create instances directly of this class. + PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} + + /// \brief Enqueue the users of this instruction in the visit worklist. + /// + /// This will visit the users with the same offset of the current visit + /// (including an unknown offset if that is the current state). + void enqueueUsers(Instruction &I); + + /// \brief Walk the operands of a GEP and adjust the offset as appropriate. + /// + /// This routine does the heavy lifting of the pointer walk by computing + /// offsets and looking through GEPs. + bool adjustOffsetForGEP(GetElementPtrInst &GEPI); +}; +} // end namespace detail + +/// \brief A base class for visitors over the uses of a pointer value. +/// +/// Once constructed, a user can call \c visit on a pointer value, and this +/// will walk its uses and visit each instruction using an InstVisitor. It also +/// provides visit methods which will recurse through any pointer-to-pointer +/// transformations such as GEPs and bitcasts. +/// +/// During the visit, the current Use* being visited is available to the +/// subclass, as well as the current offset from the original base pointer if +/// known. +/// +/// The recursive visit of uses is accomplished with a worklist, so the only +/// ordering guarantee is that an instruction is visited before any uses of it +/// are visited. Note that this does *not* mean before any of its users are +/// visited! This is because users can be visited multiple times due to +/// multiple, different uses of pointers derived from the same base. +/// +/// A particular Use will only be visited once, but a User may be visited +/// multiple times, once per Use. This visits may notably have different +/// offsets. +/// +/// All visit methods on the underlying InstVisitor return a boolean. This +/// return short-circuits the visit, stopping it immediately. +/// +/// FIXME: Generalize this for all values rather than just instructions. +template <typename DerivedT> +class PtrUseVisitor : protected InstVisitor<DerivedT>, + public detail::PtrUseVisitorBase { + friend class InstVisitor<DerivedT>; + typedef InstVisitor<DerivedT> Base; + +public: + PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {} + + /// \brief Recursively visit the uses of the given pointer. + /// \returns An info struct about the pointer. See \c PtrInfo for details. + PtrInfo visitPtr(Instruction &I) { + // This must be a pointer type. Get an integer type suitable to hold + // offsets on this pointer. + // FIXME: Support a vector of pointers. + assert(I.getType()->isPointerTy()); + IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType())); + IsOffsetKnown = true; + Offset = APInt(IntPtrTy->getBitWidth(), 0); + PI.reset(); + + // Enqueue the uses of this pointer. + enqueueUsers(I); + + // Visit all the uses off the worklist until it is empty. + while (!Worklist.empty()) { + UseToVisit ToVisit = Worklist.pop_back_val(); + U = ToVisit.UseAndIsOffsetKnown.getPointer(); + IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt(); + if (IsOffsetKnown) + Offset = llvm_move(ToVisit.Offset); + + Instruction *I = cast<Instruction>(U->getUser()); + static_cast<DerivedT*>(this)->visit(I); + if (PI.isAborted()) + break; + } + return PI; + } + +protected: + void visitStoreInst(StoreInst &SI) { + if (SI.getValueOperand() == U->get()) + PI.setEscaped(&SI); + } + + void visitBitCastInst(BitCastInst &BC) { + enqueueUsers(BC); + } + + void visitPtrToIntInst(PtrToIntInst &I) { + PI.setEscaped(&I); + } + + void visitGetElementPtrInst(GetElementPtrInst &GEPI) { + if (GEPI.use_empty()) + return; + + // If we can't walk the GEP, clear the offset. + if (!adjustOffsetForGEP(GEPI)) { + IsOffsetKnown = false; + Offset = APInt(); + } + + // Enqueue the users now that the offset has been adjusted. + enqueueUsers(GEPI); + } + + // No-op intrinsics which we know don't escape the pointer to to logic in + // some other function. + void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {} + void visitMemIntrinsic(MemIntrinsic &I) {} + void visitIntrinsicInst(IntrinsicInst &II) { + switch (II.getIntrinsicID()) { + default: + return Base::visitIntrinsicInst(II); + + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + return; // No-op intrinsics. + } + } + + // Generically, arguments to calls and invokes escape the pointer to some + // other function. Mark that. + void visitCallSite(CallSite CS) { + PI.setEscaped(CS.getInstruction()); + Base::visitCallSite(CS); + } +}; + +} + +#endif diff --git a/contrib/llvm/include/llvm/Analysis/RegionInfo.h b/contrib/llvm/include/llvm/Analysis/RegionInfo.h index 48d7ee6..69cc293 100644 --- a/contrib/llvm/include/llvm/Analysis/RegionInfo.h +++ b/contrib/llvm/include/llvm/Analysis/RegionInfo.h @@ -24,8 +24,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_REGION_INFO_H -#define LLVM_ANALYSIS_REGION_INFO_H +#ifndef LLVM_ANALYSIS_REGIONINFO_H +#define LLVM_ANALYSIS_REGIONINFO_H #include "llvm/ADT/PointerIntPair.h" #include "llvm/Analysis/DominanceFrontier.h" diff --git a/contrib/llvm/include/llvm/Analysis/RegionIterator.h b/contrib/llvm/include/llvm/Analysis/RegionIterator.h index 7adc71c..8fd4263 100644 --- a/contrib/llvm/include/llvm/Analysis/RegionIterator.h +++ b/contrib/llvm/include/llvm/Analysis/RegionIterator.h @@ -8,12 +8,12 @@ //===----------------------------------------------------------------------===// // This file defines the iterators to iterate over the elements of a Region. //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H -#define LLVM_ANALYSIS_REGION_ITERATOR_H +#ifndef LLVM_ANALYSIS_REGIONITERATOR_H +#define LLVM_ANALYSIS_REGIONITERATOR_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/include/llvm/Analysis/RegionPass.h b/contrib/llvm/include/llvm/Analysis/RegionPass.h index 68f1201..0690ac5 100644 --- a/contrib/llvm/include/llvm/Analysis/RegionPass.h +++ b/contrib/llvm/include/llvm/Analysis/RegionPass.h @@ -13,15 +13,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_REGION_PASS_H -#define LLVM_REGION_PASS_H +#ifndef LLVM_ANALYSIS_REGIONPASS_H +#define LLVM_ANALYSIS_REGIONPASS_H #include "llvm/Analysis/RegionInfo.h" - +#include "llvm/IR/Function.h" #include "llvm/Pass.h" #include "llvm/PassManagers.h" -#include "llvm/Function.h" - #include <deque> namespace llvm { @@ -59,6 +57,9 @@ public: /// @return The pass to print the LLVM IR in the region. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; + virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; } virtual bool doFinalization() { return false; } //@} diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h index 235adca0..306549f 100644 --- a/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -21,16 +21,16 @@ #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H #define LLVM_ANALYSIS_SCALAREVOLUTION_H +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Operator.h" #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" #include "llvm/Support/ConstantRange.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/ValueHandle.h" #include <map> namespace llvm { @@ -338,6 +338,10 @@ namespace llvm { /// getMax - Get the max backedge taken count for the loop. const SCEV *getMax(ScalarEvolution *SE) const; + /// Return true if any backedge taken count expressions refer to the given + /// subexpression. + bool hasOperand(const SCEV *S, ScalarEvolution *SE) const; + /// clear - Invalidate this result and free associated memory. void clear(); }; @@ -831,7 +835,7 @@ namespace llvm { /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with /// predicate Pred. Return true iff any changes were made. If the - /// operands are provably equal or inequal, LHS and RHS are set to + /// operands are provably equal or unequal, LHS and RHS are set to /// the same value and Pred is set to either ICMP_EQ or ICMP_NE. /// bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h index 3f8f149..00779fc 100644 --- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -11,18 +11,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H -#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H +#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H +#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H -#include "llvm/IRBuilder.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionNormalization.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/Support/TargetFolder.h" #include "llvm/Support/ValueHandle.h" #include <set> namespace llvm { - class TargetLowering; + class TargetTransformInfo; /// Return true if the given expression is safe to expand in the sense that /// all materialized values are safe to speculate. @@ -40,8 +40,10 @@ namespace llvm { // New instructions receive a name to identifies them with the current pass. const char* IVName; - std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > + // InsertedExpressions caches Values for reuse, so must track RAUW. + std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> > InsertedExpressions; + // InsertedValues only flags inserted instructions so needs no RAUW. std::set<AssertingVH<Value> > InsertedValues; std::set<AssertingVH<Value> > InsertedPostIncValues; @@ -129,7 +131,7 @@ namespace llvm { /// representative. Return the number of phis eliminated. unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, SmallVectorImpl<WeakVH> &DeadInsts, - const TargetLowering *TLI = NULL); + const TargetTransformInfo *TTI = NULL); /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h index 54db7d6..eac9113 100644 --- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H -#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H +#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H +#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H -#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -548,6 +548,151 @@ namespace llvm { SCEVTraversal<SV> T(Visitor); T.visitAll(Root); } + + /// The SCEVRewriter takes a scalar evolution expression and copies all its + /// components. The result after a rewrite is an identical SCEV. + struct SCEVRewriter + : public SCEVVisitor<SCEVRewriter, const SCEV*> { + public: + SCEVRewriter(ScalarEvolution &S) : SE(S) {} + + virtual ~SCEVRewriter() {} + + virtual const SCEV *visitConstant(const SCEVConstant *Constant) { + return Constant; + } + + virtual const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) { + const SCEV *Operand = visit(Expr->getOperand()); + return SE.getTruncateExpr(Operand, Expr->getType()); + } + + virtual const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { + const SCEV *Operand = visit(Expr->getOperand()); + return SE.getZeroExtendExpr(Operand, Expr->getType()); + } + + virtual const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { + const SCEV *Operand = visit(Expr->getOperand()); + return SE.getSignExtendExpr(Operand, Expr->getType()); + } + + virtual const SCEV *visitAddExpr(const SCEVAddExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + return SE.getAddExpr(Operands); + } + + virtual const SCEV *visitMulExpr(const SCEVMulExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + return SE.getMulExpr(Operands); + } + + virtual const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) { + return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS())); + } + + virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + return SE.getAddRecExpr(Operands, Expr->getLoop(), + Expr->getNoWrapFlags()); + } + + virtual const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + return SE.getSMaxExpr(Operands); + } + + virtual const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + return SE.getUMaxExpr(Operands); + } + + virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) { + return Expr; + } + + virtual const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { + return Expr; + } + + protected: + ScalarEvolution &SE; + }; + + typedef DenseMap<const Value*, Value*> ValueToValueMap; + + /// The SCEVParameterRewriter takes a scalar evolution expression and updates + /// the SCEVUnknown components following the Map (Value -> Value). + struct SCEVParameterRewriter: public SCEVRewriter { + public: + static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE, + ValueToValueMap &Map) { + SCEVParameterRewriter Rewriter(SE, Map); + return Rewriter.visit(Scev); + } + SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M) + : SCEVRewriter(S), Map(M) {} + + virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) { + Value *V = Expr->getValue(); + if (Map.count(V)) + return SE.getUnknown(Map[V]); + return Expr; + } + + private: + ValueToValueMap ⤅ + }; + + typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT; + + /// The SCEVApplyRewriter takes a scalar evolution expression and applies + /// the Map (Loop -> SCEV) to all AddRecExprs. + struct SCEVApplyRewriter: public SCEVRewriter { + public: + static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map, + ScalarEvolution &SE) { + SCEVApplyRewriter Rewriter(SE, Map); + return Rewriter.visit(Scev); + } + SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M) + : SCEVRewriter(S), Map(M) {} + + virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { + SmallVector<const SCEV *, 2> Operands; + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) + Operands.push_back(visit(Expr->getOperand(i))); + + const Loop *L = Expr->getLoop(); + const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags()); + + if (0 == Map.count(L)) + return Res; + + const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res; + return Rec->evaluateAtIteration(Map[L], SE); + } + + private: + LoopToScevMapT ⤅ + }; + +/// Applies the Map (Loop -> SCEV) to the given Scev. +static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map, + ScalarEvolution &SE) { + return SCEVApplyRewriter::rewrite(Scev, Map, SE); +} + } #endif diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h index 342e5937..7c6423a 100644 --- a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h +++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h @@ -33,8 +33,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H -#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H +#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H +#define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H #include "llvm/ADT/SmallPtrSet.h" diff --git a/contrib/llvm/include/llvm/Analysis/SparsePropagation.h b/contrib/llvm/include/llvm/Analysis/SparsePropagation.h index b758eca..76c8ccf 100644 --- a/contrib/llvm/include/llvm/Analysis/SparsePropagation.h +++ b/contrib/llvm/include/llvm/Analysis/SparsePropagation.h @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_SPARSE_PROPAGATION_H -#define LLVM_ANALYSIS_SPARSE_PROPAGATION_H +#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H +#define LLVM_ANALYSIS_SPARSEPROPAGATION_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" -#include <vector> #include <set> +#include <vector> namespace llvm { class Value; @@ -203,4 +203,4 @@ private: } // end namespace llvm -#endif // LLVM_ANALYSIS_SPARSE_PROPAGATION_H +#endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h new file mode 100644 index 0000000..a9d6725 --- /dev/null +++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -0,0 +1,349 @@ +//===- llvm/Analysis/TargetTransformInfo.h ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass exposes codegen information to IR-level passes. Every +// transformation that uses codegen information is broken into three parts: +// 1. The IR-level analysis pass. +// 2. The IR-level transformation interface which provides the needed +// information. +// 3. Codegen-level implementation which uses target-specific hooks. +// +// This file defines #2, which is the interface that IR-level transformations +// use for querying the codegen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H +#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H + +#include "llvm/IR/Intrinsics.h" +#include "llvm/Pass.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class GlobalValue; +class Type; +class User; +class Value; + +/// TargetTransformInfo - This pass provides access to the codegen +/// interfaces that are needed for IR-level transformations. +class TargetTransformInfo { +protected: + /// \brief The TTI instance one level down the stack. + /// + /// This is used to implement the default behavior all of the methods which + /// is to delegate up through the stack of TTIs until one can answer the + /// query. + TargetTransformInfo *PrevTTI; + + /// \brief The top of the stack of TTI analyses available. + /// + /// This is a convenience routine maintained as TTI analyses become available + /// that complements the PrevTTI delegation chain. When one part of an + /// analysis pass wants to query another part of the analysis pass it can use + /// this to start back at the top of the stack. + TargetTransformInfo *TopTTI; + + /// All pass subclasses must in their initializePass routine call + /// pushTTIStack with themselves to update the pointers tracking the previous + /// TTI instance in the analysis group's stack, and the top of the analysis + /// group's stack. + void pushTTIStack(Pass *P); + + /// All pass subclasses must in their finalizePass routine call popTTIStack + /// to update the pointers tracking the previous TTI instance in the analysis + /// group's stack, and the top of the analysis group's stack. + void popTTIStack(); + + /// All pass subclasses must call TargetTransformInfo::getAnalysisUsage. + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + +public: + /// This class is intended to be subclassed by real implementations. + virtual ~TargetTransformInfo() = 0; + + /// \name Generic Target Information + /// @{ + + /// \brief Underlying constants for 'cost' values in this interface. + /// + /// Many APIs in this interface return a cost. This enum defines the + /// fundamental values that should be used to interpret (and produce) those + /// costs. The costs are returned as an unsigned rather than a member of this + /// enumeration because it is expected that the cost of one IR instruction + /// may have a multiplicative factor to it or otherwise won't fit directly + /// into the enum. Moreover, it is common to sum or average costs which works + /// better as simple integral values. Thus this enum only provides constants. + /// + /// Note that these costs should usually reflect the intersection of code-size + /// cost and execution cost. A free instruction is typically one that folds + /// into another instruction. For example, reg-to-reg moves can often be + /// skipped by renaming the registers in the CPU, but they still are encoded + /// and thus wouldn't be considered 'free' here. + enum TargetCostConstants { + TCC_Free = 0, ///< Expected to fold away in lowering. + TCC_Basic = 1, ///< The cost of a typical 'add' instruction. + TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86. + }; + + /// \brief Estimate the cost of a specific operation when lowered. + /// + /// Note that this is designed to work on an arbitrary synthetic opcode, and + /// thus work for hypothetical queries before an instruction has even been + /// formed. However, this does *not* work for GEPs, and must not be called + /// for a GEP instruction. Instead, use the dedicated getGEPCost interface as + /// analyzing a GEP's cost required more information. + /// + /// Typically only the result type is required, and the operand type can be + /// omitted. However, if the opcode is one of the cast instructions, the + /// operand type is required. + /// + /// The returned cost is defined in terms of \c TargetCostConstants, see its + /// comments for a detailed explanation of the cost values. + virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, + Type *OpTy = 0) const; + + /// \brief Estimate the cost of a GEP operation when lowered. + /// + /// The contract for this function is the same as \c getOperationCost except + /// that it supports an interface that provides extra information specific to + /// the GEP operation. + virtual unsigned getGEPCost(const Value *Ptr, + ArrayRef<const Value *> Operands) const; + + /// \brief Estimate the cost of a function call when lowered. + /// + /// The contract for this is the same as \c getOperationCost except that it + /// supports an interface that provides extra information specific to call + /// instructions. + /// + /// This is the most basic query for estimating call cost: it only knows the + /// function type and (potentially) the number of arguments at the call site. + /// The latter is only interesting for varargs function types. + virtual unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const; + + /// \brief Estimate the cost of calling a specific function when lowered. + /// + /// This overload adds the ability to reason about the particular function + /// being called in the event it is a library call with special lowering. + virtual unsigned getCallCost(const Function *F, int NumArgs = -1) const; + + /// \brief Estimate the cost of calling a specific function when lowered. + /// + /// This overload allows specifying a set of candidate argument values. + virtual unsigned getCallCost(const Function *F, + ArrayRef<const Value *> Arguments) const; + + /// \brief Estimate the cost of an intrinsic when lowered. + /// + /// Mirrors the \c getCallCost method but uses an intrinsic identifier. + virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<Type *> ParamTys) const; + + /// \brief Estimate the cost of an intrinsic when lowered. + /// + /// Mirrors the \c getCallCost method but uses an intrinsic identifier. + virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<const Value *> Arguments) const; + + /// \brief Estimate the cost of a given IR user when lowered. + /// + /// This can estimate the cost of either a ConstantExpr or Instruction when + /// lowered. It has two primary advantages over the \c getOperationCost and + /// \c getGEPCost above, and one significant disadvantage: it can only be + /// used when the IR construct has already been formed. + /// + /// The advantages are that it can inspect the SSA use graph to reason more + /// accurately about the cost. For example, all-constant-GEPs can often be + /// folded into a load or other instruction, but if they are used in some + /// other context they may not be folded. This routine can distinguish such + /// cases. + /// + /// The returned cost is defined in terms of \c TargetCostConstants, see its + /// comments for a detailed explanation of the cost values. + virtual unsigned getUserCost(const User *U) const; + + /// \brief Test whether calls to a function lower to actual program function + /// calls. + /// + /// The idea is to test whether the program is likely to require a 'call' + /// instruction or equivalent in order to call the given function. + /// + /// FIXME: It's not clear that this is a good or useful query API. Client's + /// should probably move to simpler cost metrics using the above. + /// Alternatively, we could split the cost interface into distinct code-size + /// and execution-speed costs. This would allow modelling the core of this + /// query more accurately as the a call is a single small instruction, but + /// incurs significant execution cost. + virtual bool isLoweredToCall(const Function *F) const; + + /// @} + + /// \name Scalar Target Information + /// @{ + + /// \brief Flags indicating the kind of support for population count. + /// + /// Compared to the SW implementation, HW support is supposed to + /// significantly boost the performance when the population is dense, and it + /// may or may not degrade performance if the population is sparse. A HW + /// support is considered as "Fast" if it can outperform, or is on a par + /// with, SW implementation when the population is sparse; otherwise, it is + /// considered as "Slow". + enum PopcntSupportKind { + PSK_Software, + PSK_SlowHardware, + PSK_FastHardware + }; + + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t Imm) const; + + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(int64_t Imm) const; + + /// isLegalAddressingMode - Return true if the addressing mode represented by + /// AM is legal for this target, for a load/store of the specified type. + /// The type may be VoidTy, in which case only return true if the addressing + /// mode is legal for a load/store of any legal type. + /// TODO: Handle pre/postinc as well. + virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, + int64_t BaseOffset, bool HasBaseReg, + int64_t Scale) const; + + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; + + /// Is this type legal. + virtual bool isTypeLegal(Type *Ty) const; + + /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes + virtual unsigned getJumpBufAlignment() const; + + /// getJumpBufSize - returns the target's jmp_buf size in bytes. + virtual unsigned getJumpBufSize() const; + + /// shouldBuildLookupTables - Return true if switches should be turned into + /// lookup tables for the target. + virtual bool shouldBuildLookupTables() const; + + /// getPopcntSupport - Return hardware support for population count. + virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; + + /// getIntImmCost - Return the expected cost of materializing the given + /// integer immediate of the specified type. + virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const; + + /// @} + + /// \name Vector Target Information + /// @{ + + /// \brief The various kinds of shuffle patterns for vector queries. + enum ShuffleKind { + SK_Broadcast, ///< Broadcast element 0 to all other elements. + SK_Reverse, ///< Reverse the order of the vector. + SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset. + SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset. + }; + + /// \brief Additonal information about an operand's possible values. + enum OperandValueKind { + OK_AnyValue, // Operand can have any value. + OK_UniformValue, // Operand is uniform (splat of a value). + OK_UniformConstantValue // Operand is uniform constant. + }; + + /// \return The number of scalar or vector registers that the target has. + /// If 'Vectors' is true, it returns the number of vector registers. If it is + /// set to false, it returns the number of scalar registers. + virtual unsigned getNumberOfRegisters(bool Vector) const; + + /// \return The width of the largest scalar or vector register type. + virtual unsigned getRegisterBitWidth(bool Vector) const; + + /// \return The maximum unroll factor that the vectorizer should try to + /// perform for this target. This number depends on the level of parallelism + /// and the number of execution units in the CPU. + virtual unsigned getMaximumUnrollFactor() const; + + /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc. + virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, + OperandValueKind Opd1Info = OK_AnyValue, + OperandValueKind Opd2Info = OK_AnyValue) const; + + /// \return The cost of a shuffle instruction of kind Kind and of type Tp. + /// The index and subtype parameters are used by the subvector insertion and + /// extraction shuffle kinds. + virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0, + Type *SubTp = 0) const; + + /// \return The expected cost of cast instructions, such as bitcast, trunc, + /// zext, etc. + virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const; + + /// \return The expected cost of control-flow related instructions such as + /// Phi, Ret, Br. + virtual unsigned getCFInstrCost(unsigned Opcode) const; + + /// \returns The expected cost of compare and select instructions. + virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy = 0) const; + + /// \return The expected cost of vector Insert and Extract. + /// Use -1 to indicate that there is no information on the index value. + virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index = -1) const; + + /// \return The cost of Load and Store instructions. + virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const; + + /// \returns The cost of Intrinsic instructions. + virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Type *> Tys) const; + + /// \returns The number of pieces into which the provided type must be + /// split during legalization. Zero is returned when the answer is unknown. + virtual unsigned getNumberOfParts(Type *Tp) const; + + /// \returns The cost of the address computation. For most targets this can be + /// merged into the instruction indexing mode. Some targets might want to + /// distinguish between address computation for memory operations on vector + /// types and scalar types. Such targets should override this function. + virtual unsigned getAddressComputationCost(Type *Ty) const; + + /// @} + + /// Analysis group identification. + static char ID; +}; + +/// \brief Create the base case instance of a pass in the TTI analysis group. +/// +/// This class provides the base case for the stack of TTI analyzes. It doesn't +/// delegate to anything and uses the STTI and VTTI objects passed in to +/// satisfy the queries. +ImmutablePass *createNoTargetTransformInfoPass(); + +} // End llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/Analysis/Trace.h b/contrib/llvm/include/llvm/Analysis/Trace.h index 99651e1..bedd654 100644 --- a/contrib/llvm/include/llvm/Analysis/Trace.h +++ b/contrib/llvm/include/llvm/Analysis/Trace.h @@ -18,8 +18,8 @@ #ifndef LLVM_ANALYSIS_TRACE_H #define LLVM_ANALYSIS_TRACE_H -#include <vector> #include <cassert> +#include <vector> namespace llvm { class BasicBlock; @@ -116,4 +116,4 @@ public: } // end namespace llvm -#endif // TRACE_H +#endif // LLVM_ANALYSIS_TRACE_H diff --git a/contrib/llvm/include/llvm/Analysis/ValueTracking.h b/contrib/llvm/include/llvm/Analysis/ValueTracking.h index a857524..3775ec9 100644 --- a/contrib/llvm/include/llvm/Analysis/ValueTracking.h +++ b/contrib/llvm/include/llvm/Analysis/ValueTracking.h @@ -45,13 +45,12 @@ namespace llvm { void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, const DataLayout *TD = 0, unsigned Depth = 0); - /// isPowerOfTwo - Return true if the given value is known to have exactly one - /// bit set when defined. For vectors return true if every element is known to - /// be a power of two when defined. Supports values with integer or pointer - /// type and vectors of integers. If 'OrZero' is set then returns true if the - /// given value is either a power of two or zero. - bool isPowerOfTwo(Value *V, const DataLayout *TD = 0, bool OrZero = false, - unsigned Depth = 0); + /// isKnownToBeAPowerOfTwo - Return true if the given value is known to have + /// exactly one bit set when defined. For vectors return true if every + /// element is known to be a power of two when defined. Supports values with + /// integer or pointer type and vectors of integers. If 'OrZero' is set then + /// returns true if the given value is either a power of two or zero. + bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0); /// isKnownNonZero - Return true if the given value is known to be non-zero /// when defined. For vectors return true if every element is known to be @@ -118,10 +117,10 @@ namespace llvm { /// it can be expressed as a base pointer plus a constant offset. Return the /// base and offset to the caller. Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, - const DataLayout &TD); + const DataLayout *TD); static inline const Value * GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset, - const DataLayout &TD) { + const DataLayout *TD) { return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD); } @@ -184,6 +183,11 @@ namespace llvm { bool isSafeToSpeculativelyExecute(const Value *V, const DataLayout *TD = 0); + /// isKnownNonNull - Return true if this pointer couldn't possibly be null by + /// its definition. This returns true for allocas, non-extern-weak globals + /// and byval arguments. + bool isKnownNonNull(const Value *V); + } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Argument.h b/contrib/llvm/include/llvm/Argument.h deleted file mode 100644 index b1c2218..0000000 --- a/contrib/llvm/include/llvm/Argument.h +++ /dev/null @@ -1,91 +0,0 @@ -//===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the Argument class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ARGUMENT_H -#define LLVM_ARGUMENT_H - -#include "llvm/Value.h" -#include "llvm/Attributes.h" -#include "llvm/ADT/ilist_node.h" -#include "llvm/ADT/Twine.h" - -namespace llvm { - -template<typename ValueSubClass, typename ItemParentClass> - class SymbolTableListTraits; - -/// A class to represent an incoming formal argument to a Function. An argument -/// is a very simple Value. It is essentially a named (optional) type. When used -/// in the body of a function, it represents the value of the actual argument -/// the function was called with. -/// @brief LLVM Argument representation -class Argument : public Value, public ilist_node<Argument> { - virtual void anchor(); - Function *Parent; - - friend class SymbolTableListTraits<Argument, Function>; - void setParent(Function *parent); - -public: - /// Argument ctor - If Function argument is specified, this argument is - /// inserted at the end of the argument list for the function. - /// - explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0); - - inline const Function *getParent() const { return Parent; } - inline Function *getParent() { return Parent; } - - /// getArgNo - Return the index of this formal argument in its containing - /// function. For example in "void foo(int a, float b)" a is 0 and b is 1. - unsigned getArgNo() const; - - /// hasByValAttr - Return true if this argument has the byval attribute on it - /// in its containing function. - bool hasByValAttr() const; - - /// getParamAlignment - If this is a byval argument, return its alignment. - unsigned getParamAlignment() const; - - /// hasNestAttr - Return true if this argument has the nest attribute on - /// it in its containing function. - bool hasNestAttr() const; - - /// hasNoAliasAttr - Return true if this argument has the noalias attribute on - /// it in its containing function. - bool hasNoAliasAttr() const; - - /// hasNoCaptureAttr - Return true if this argument has the nocapture - /// attribute on it in its containing function. - bool hasNoCaptureAttr() const; - - /// hasStructRetAttr - Return true if this argument has the sret attribute on - /// it in its containing function. - bool hasStructRetAttr() const; - - /// addAttr - Add a Attribute to an argument - void addAttr(Attributes); - - /// removeAttr - Remove a Attribute from an argument - void removeAttr(Attributes); - - /// classof - Methods for support type inquiry through isa, cast, and - /// dyn_cast: - /// - static inline bool classof(const Value *V) { - return V->getValueID() == ArgumentVal; - } -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/Assembly/PrintModulePass.h b/contrib/llvm/include/llvm/Assembly/PrintModulePass.h index 239fbcc..02b9bd9 100644 --- a/contrib/llvm/include/llvm/Assembly/PrintModulePass.h +++ b/contrib/llvm/include/llvm/Assembly/PrintModulePass.h @@ -23,6 +23,7 @@ namespace llvm { class FunctionPass; class ModulePass; + class BasicBlockPass; class raw_ostream; /// createPrintModulePass - Create and return a pass that writes the @@ -37,6 +38,11 @@ namespace llvm { raw_ostream *OS, bool DeleteStream=false); + /// createPrintBasicBlockPass - Create and return a pass that writes the + /// BB to the specified raw_ostream. + BasicBlockPass *createPrintBasicBlockPass(raw_ostream *OS, + bool DeleteStream=false, + const std::string &Banner = ""); } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Attributes.h b/contrib/llvm/include/llvm/Attributes.h deleted file mode 100644 index a9c2d74..0000000 --- a/contrib/llvm/include/llvm/Attributes.h +++ /dev/null @@ -1,431 +0,0 @@ -//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the simple types necessary to represent the -// attributes associated with functions and their calls. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ATTRIBUTES_H -#define LLVM_ATTRIBUTES_H - -#include "llvm/Support/MathExtras.h" -#include "llvm/ADT/ArrayRef.h" -#include <cassert> -#include <string> - -namespace llvm { - -class AttrBuilder; -class AttributesImpl; -class LLVMContext; -class Type; - -/// Attributes - A bitset of attributes. -class Attributes { -public: - /// Function parameters and results can have attributes to indicate how they - /// should be treated by optimizations and code generation. This enumeration - /// lists the attributes that can be associated with parameters, function - /// results or the function itself. - /// - /// Note that uwtable is about the ABI or the user mandating an entry in the - /// unwind table. The nounwind attribute is about an exception passing by the - /// function. - /// - /// In a theoretical system that uses tables for profiling and sjlj for - /// exceptions, they would be fully independent. In a normal system that uses - /// tables for both, the semantics are: - /// - /// nil = Needs an entry because an exception might pass by. - /// nounwind = No need for an entry - /// uwtable = Needs an entry because the ABI says so and because - /// an exception might pass by. - /// uwtable + nounwind = Needs an entry because the ABI says so. - - enum AttrVal { - // IR-Level Attributes - None, ///< No attributes have been set - AddressSafety, ///< Address safety checking is on. - Alignment, ///< Alignment of parameter (5 bits) - ///< stored as log2 of alignment with +1 bias - ///< 0 means unaligned different from align 1 - AlwaysInline, ///< inline=always - ByVal, ///< Pass structure by value - InlineHint, ///< Source said inlining was desirable - InReg, ///< Force argument to be passed in register - MinSize, ///< Function must be optimized for size first - Naked, ///< Naked function - Nest, ///< Nested function static chain - NoAlias, ///< Considered to not alias after call - NoCapture, ///< Function creates no aliases of pointer - NoImplicitFloat, ///< Disable implicit floating point insts - NoInline, ///< inline=never - NonLazyBind, ///< Function is called early and/or - ///< often, so lazy binding isn't worthwhile - NoRedZone, ///< Disable redzone - NoReturn, ///< Mark the function as not returning - NoUnwind, ///< Function doesn't unwind stack - OptimizeForSize, ///< opt_size - ReadNone, ///< Function does not access memory - ReadOnly, ///< Function only reads from memory - ReturnsTwice, ///< Function can return twice - SExt, ///< Sign extended before/after call - StackAlignment, ///< Alignment of stack for function (3 bits) - ///< stored as log2 of alignment with +1 bias 0 - ///< means unaligned (different from - ///< alignstack={1)) - StackProtect, ///< Stack protection. - StackProtectReq, ///< Stack protection required. - StructRet, ///< Hidden pointer to structure to return - UWTable, ///< Function must be in a unwind table - ZExt ///< Zero extended before/after call - }; -private: - AttributesImpl *Attrs; - Attributes(AttributesImpl *A) : Attrs(A) {} -public: - Attributes() : Attrs(0) {} - Attributes(const Attributes &A) : Attrs(A.Attrs) {} - Attributes &operator=(const Attributes &A) { - Attrs = A.Attrs; - return *this; - } - - /// get - Return a uniquified Attributes object. This takes the uniquified - /// value from the Builder and wraps it in the Attributes class. - static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals); - static Attributes get(LLVMContext &Context, AttrBuilder &B); - - /// @brief Return true if the attribute is present. - bool hasAttribute(AttrVal Val) const; - - /// @brief Return true if attributes exist - bool hasAttributes() const; - - /// @brief Return true if the attributes are a non-null intersection. - bool hasAttributes(const Attributes &A) const; - - /// @brief Returns the alignment field of an attribute as a byte alignment - /// value. - unsigned getAlignment() const; - - /// @brief Returns the stack alignment field of an attribute as a byte - /// alignment value. - unsigned getStackAlignment() const; - - /// @brief Parameter attributes that do not apply to vararg call arguments. - bool hasIncompatibleWithVarArgsAttrs() const { - return hasAttribute(Attributes::StructRet); - } - - /// @brief Attributes that only apply to function parameters. - bool hasParameterOnlyAttrs() const { - return hasAttribute(Attributes::ByVal) || - hasAttribute(Attributes::Nest) || - hasAttribute(Attributes::StructRet) || - hasAttribute(Attributes::NoCapture); - } - - /// @brief Attributes that may be applied to the function itself. These cannot - /// be used on return values or function parameters. - bool hasFunctionOnlyAttrs() const { - return hasAttribute(Attributes::NoReturn) || - hasAttribute(Attributes::NoUnwind) || - hasAttribute(Attributes::ReadNone) || - hasAttribute(Attributes::ReadOnly) || - hasAttribute(Attributes::NoInline) || - hasAttribute(Attributes::AlwaysInline) || - hasAttribute(Attributes::OptimizeForSize) || - hasAttribute(Attributes::StackProtect) || - hasAttribute(Attributes::StackProtectReq) || - hasAttribute(Attributes::NoRedZone) || - hasAttribute(Attributes::NoImplicitFloat) || - hasAttribute(Attributes::Naked) || - hasAttribute(Attributes::InlineHint) || - hasAttribute(Attributes::StackAlignment) || - hasAttribute(Attributes::UWTable) || - hasAttribute(Attributes::NonLazyBind) || - hasAttribute(Attributes::ReturnsTwice) || - hasAttribute(Attributes::AddressSafety) || - hasAttribute(Attributes::MinSize); - } - - bool operator==(const Attributes &A) const { - return Attrs == A.Attrs; - } - bool operator!=(const Attributes &A) const { - return Attrs != A.Attrs; - } - - uint64_t Raw() const; - - /// @brief Which attributes cannot be applied to a type. - static Attributes typeIncompatible(Type *Ty); - - /// encodeLLVMAttributesForBitcode - This returns an integer containing an - /// encoding of all the LLVM attributes found in the given attribute bitset. - /// Any change to this encoding is a breaking change to bitcode compatibility. - static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs); - - /// decodeLLVMAttributesForBitcode - This returns an attribute bitset - /// containing the LLVM attributes that have been decoded from the given - /// integer. This function must stay in sync with - /// 'encodeLLVMAttributesForBitcode'. - static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C, - uint64_t EncodedAttrs); - - /// getAsString - The set of Attributes set in Attributes is converted to a - /// string of equivalent mnemonics. This is, presumably, for writing out the - /// mnemonics for the assembly writer. - /// @brief Convert attribute bits to text - std::string getAsString() const; -}; - -//===----------------------------------------------------------------------===// -/// AttrBuilder - This class is used in conjunction with the Attributes::get -/// method to create an Attributes object. The object itself is uniquified. The -/// Builder's value, however, is not. So this can be used as a quick way to test -/// for equality, presence of attributes, etc. -class AttrBuilder { - uint64_t Bits; -public: - AttrBuilder() : Bits(0) {} - explicit AttrBuilder(uint64_t B) : Bits(B) {} - AttrBuilder(const Attributes &A) : Bits(A.Raw()) {} - AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {} - - void clear() { Bits = 0; } - - /// addAttribute - Add an attribute to the builder. - AttrBuilder &addAttribute(Attributes::AttrVal Val); - - /// removeAttribute - Remove an attribute from the builder. - AttrBuilder &removeAttribute(Attributes::AttrVal Val); - - /// addAttribute - Add the attributes from A to the builder. - AttrBuilder &addAttributes(const Attributes &A); - - /// removeAttribute - Remove the attributes from A from the builder. - AttrBuilder &removeAttributes(const Attributes &A); - - /// hasAttribute - Return true if the builder has the specified attribute. - bool hasAttribute(Attributes::AttrVal A) const; - - /// hasAttributes - Return true if the builder has IR-level attributes. - bool hasAttributes() const; - - /// hasAttributes - Return true if the builder has any attribute that's in the - /// specified attribute. - bool hasAttributes(const Attributes &A) const; - - /// hasAlignmentAttr - Return true if the builder has an alignment attribute. - bool hasAlignmentAttr() const; - - /// getAlignment - Retrieve the alignment attribute, if it exists. - uint64_t getAlignment() const; - - /// getStackAlignment - Retrieve the stack alignment attribute, if it exists. - uint64_t getStackAlignment() const; - - /// addAlignmentAttr - This turns an int alignment (which must be a power of - /// 2) into the form used internally in Attributes. - AttrBuilder &addAlignmentAttr(unsigned Align); - - /// addStackAlignmentAttr - This turns an int stack alignment (which must be a - /// power of 2) into the form used internally in Attributes. - AttrBuilder &addStackAlignmentAttr(unsigned Align); - - /// addRawValue - Add the raw value to the internal representation. - /// N.B. This should be used ONLY for decoding LLVM bitcode! - AttrBuilder &addRawValue(uint64_t Val); - - /// @brief Remove attributes that are used on functions only. - void removeFunctionOnlyAttrs() { - removeAttribute(Attributes::NoReturn) - .removeAttribute(Attributes::NoUnwind) - .removeAttribute(Attributes::ReadNone) - .removeAttribute(Attributes::ReadOnly) - .removeAttribute(Attributes::NoInline) - .removeAttribute(Attributes::AlwaysInline) - .removeAttribute(Attributes::OptimizeForSize) - .removeAttribute(Attributes::StackProtect) - .removeAttribute(Attributes::StackProtectReq) - .removeAttribute(Attributes::NoRedZone) - .removeAttribute(Attributes::NoImplicitFloat) - .removeAttribute(Attributes::Naked) - .removeAttribute(Attributes::InlineHint) - .removeAttribute(Attributes::StackAlignment) - .removeAttribute(Attributes::UWTable) - .removeAttribute(Attributes::NonLazyBind) - .removeAttribute(Attributes::ReturnsTwice) - .removeAttribute(Attributes::AddressSafety) - .removeAttribute(Attributes::MinSize); - } - - uint64_t Raw() const { return Bits; } - - bool operator==(const AttrBuilder &B) { - return Bits == B.Bits; - } - bool operator!=(const AttrBuilder &B) { - return Bits != B.Bits; - } -}; - -//===----------------------------------------------------------------------===// -// AttributeWithIndex -//===----------------------------------------------------------------------===// - -/// AttributeWithIndex - This is just a pair of values to associate a set of -/// attributes with an index. -struct AttributeWithIndex { - Attributes Attrs; ///< The attributes that are set, or'd together. - unsigned Index; ///< Index of the parameter for which the attributes apply. - ///< Index 0 is used for return value attributes. - ///< Index ~0U is used for function attributes. - - static AttributeWithIndex get(LLVMContext &C, unsigned Idx, - ArrayRef<Attributes::AttrVal> Attrs) { - return get(Idx, Attributes::get(C, Attrs)); - } - static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { - AttributeWithIndex P; - P.Index = Idx; - P.Attrs = Attrs; - return P; - } -}; - -//===----------------------------------------------------------------------===// -// AttrListPtr Smart Pointer -//===----------------------------------------------------------------------===// - -class AttributeListImpl; - -/// AttrListPtr - This class manages the ref count for the opaque -/// AttributeListImpl object and provides accessors for it. -class AttrListPtr { -public: - enum AttrIndex { - ReturnIndex = 0U, - FunctionIndex = ~0U - }; -private: - /// @brief The attributes that we are managing. This can be null to represent - /// the empty attributes list. - AttributeListImpl *AttrList; - - /// @brief The attributes for the specified index are returned. Attributes - /// for the result are denoted with Idx = 0. - Attributes getAttributes(unsigned Idx) const; - - explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {} -public: - AttrListPtr() : AttrList(0) {} - AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {} - const AttrListPtr &operator=(const AttrListPtr &RHS); - - //===--------------------------------------------------------------------===// - // Attribute List Construction and Mutation - //===--------------------------------------------------------------------===// - - /// get - Return a Attributes list with the specified parameters in it. - static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs); - - /// addAttr - Add the specified attribute at the specified index to this - /// attribute list. Since attribute lists are immutable, this - /// returns the new list. - AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; - - /// removeAttr - Remove the specified attribute at the specified index from - /// this attribute list. Since attribute lists are immutable, this - /// returns the new list. - AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; - - //===--------------------------------------------------------------------===// - // Attribute List Accessors - //===--------------------------------------------------------------------===// - /// getParamAttributes - The attributes for the specified index are - /// returned. - Attributes getParamAttributes(unsigned Idx) const { - return getAttributes(Idx); - } - - /// getRetAttributes - The attributes for the ret value are - /// returned. - Attributes getRetAttributes() const { - return getAttributes(ReturnIndex); - } - - /// getFnAttributes - The function attributes are returned. - Attributes getFnAttributes() const { - return getAttributes(FunctionIndex); - } - - /// paramHasAttr - Return true if the specified parameter index has the - /// specified attribute set. - bool paramHasAttr(unsigned Idx, Attributes Attr) const { - return getAttributes(Idx).hasAttributes(Attr); - } - - /// getParamAlignment - Return the alignment for the specified function - /// parameter. - unsigned getParamAlignment(unsigned Idx) const { - return getAttributes(Idx).getAlignment(); - } - - /// hasAttrSomewhere - Return true if the specified attribute is set for at - /// least one parameter or for the return value. - bool hasAttrSomewhere(Attributes::AttrVal Attr) const; - - unsigned getNumAttrs() const; - Attributes &getAttributesAtIndex(unsigned i) const; - - /// operator==/!= - Provide equality predicates. - bool operator==(const AttrListPtr &RHS) const - { return AttrList == RHS.AttrList; } - bool operator!=(const AttrListPtr &RHS) const - { return AttrList != RHS.AttrList; } - - //===--------------------------------------------------------------------===// - // Attribute List Introspection - //===--------------------------------------------------------------------===// - - /// getRawPointer - Return a raw pointer that uniquely identifies this - /// attribute list. - void *getRawPointer() const { - return AttrList; - } - - // Attributes are stored as a dense set of slots, where there is one - // slot for each argument that has an attribute. This allows walking over the - // dense set instead of walking the sparse list of attributes. - - /// isEmpty - Return true if there are no attributes. - /// - bool isEmpty() const { - return AttrList == 0; - } - - /// getNumSlots - Return the number of slots used in this attribute list. - /// This is the number of arguments that have an attribute set on them - /// (including the function itself). - unsigned getNumSlots() const; - - /// getSlot - Return the AttributeWithIndex at the specified slot. This - /// holds a index number plus a set of attributes. - const AttributeWithIndex &getSlot(unsigned Slot) const; - - void dump() const; -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/Bitcode/Archive.h b/contrib/llvm/include/llvm/Bitcode/Archive.h index 4fd4b5d..7b30c7e 100644 --- a/contrib/llvm/include/llvm/Bitcode/Archive.h +++ b/contrib/llvm/include/llvm/Bitcode/Archive.h @@ -50,10 +50,10 @@ class ArchiveMember : public ilist_node<ArchiveMember> { SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table - BitcodeFlag = 8, ///< Member is bitcode - HasPathFlag = 16, ///< Member has a full or partial path + BitcodeFlag = 8, ///< Member is bitcode + HasPathFlag = 16, ///< Member has a full or partial path HasLongFilenameFlag = 32, ///< Member uses the long filename syntax - StringTableFlag = 64 ///< Member is an ar(1) format string table + StringTableFlag = 64 ///< Member is an ar(1) format string table }; /// @} diff --git a/contrib/llvm/include/llvm/Bitcode/BitCodes.h b/contrib/llvm/include/llvm/Bitcode/BitCodes.h index 28e1ab1..b510daf 100644 --- a/contrib/llvm/include/llvm/Bitcode/BitCodes.h +++ b/contrib/llvm/include/llvm/Bitcode/BitCodes.h @@ -26,8 +26,8 @@ namespace llvm { namespace bitc { enum StandardWidths { - BlockIDWidth = 8, // We use VBR-8 for block IDs. - CodeLenWidth = 4, // Codelen are VBR-4. + BlockIDWidth = 8, // We use VBR-8 for block IDs. + CodeLenWidth = 4, // Codelen are VBR-4. BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 16GB per block. }; @@ -69,10 +69,11 @@ namespace bitc { enum BlockInfoCodes { // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd // block, instead of the BlockInfo block. - - BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] - BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name] - BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: [id, name] + + BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] + BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name] + BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: + // [id, name] }; } // End bitc namespace @@ -99,7 +100,7 @@ public: explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0) : Val(Data), IsLiteral(false), Enc(E) {} - bool isLiteral() const { return IsLiteral; } + bool isLiteral() const { return IsLiteral; } bool isEncoding() const { return !IsLiteral; } // Accessors for literals. @@ -138,18 +139,18 @@ public: if (C >= 'a' && C <= 'z') return C-'a'; if (C >= 'A' && C <= 'Z') return C-'A'+26; if (C >= '0' && C <= '9') return C-'0'+26+26; - if (C == '.') return 62; - if (C == '_') return 63; + if (C == '.') return 62; + if (C == '_') return 63; llvm_unreachable("Not a value Char6 character!"); } static char DecodeChar6(unsigned V) { assert((V & ~63) == 0 && "Not a Char6 encoded character!"); - if (V < 26) return V+'a'; - if (V < 26+26) return V-26+'A'; + if (V < 26) return V+'a'; + if (V < 26+26) return V-26+'A'; if (V < 26+26+10) return V-26-26+'0'; - if (V == 62) return '.'; - if (V == 63) return '_'; + if (V == 62) return '.'; + if (V == 63) return '_'; llvm_unreachable("Not a value Char6 character!"); } diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h index 840f57e..f313973 100644 --- a/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h +++ b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef BITSTREAM_READER_H -#define BITSTREAM_READER_H +#ifndef LLVM_BITCODE_BITSTREAMREADER_H +#define LLVM_BITCODE_BITSTREAMREADER_H #include "llvm/ADT/OwningPtr.h" #include "llvm/Bitcode/BitCodes.h" @@ -27,6 +27,11 @@ namespace llvm { class Deserializer; +/// BitstreamReader - This class is used to read from an LLVM bitcode stream, +/// maintaining information that is global to decoding the entire file. While +/// a file is being read, multiple cursors can be independently advanced or +/// skipped around within the file. These are represented by the +/// BitstreamCursor class. class BitstreamReader { public: /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. @@ -35,12 +40,12 @@ public: unsigned BlockID; std::vector<BitCodeAbbrev*> Abbrevs; std::string Name; - + std::vector<std::pair<unsigned, std::string> > RecordNames; }; private: OwningPtr<StreamableMemoryObject> BitcodeBytes; - + std::vector<BlockInfo> BlockInfoRecords; /// IgnoreBlockInfoNames - This is set to true if we don't care about the @@ -86,7 +91,7 @@ public: /// name information. void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } - + //===--------------------------------------------------------------------===// // Block Manipulation //===--------------------------------------------------------------------===// @@ -95,7 +100,7 @@ public: /// block info block for this Bitstream. We only process it for the first /// cursor that walks over it. bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } - + /// getBlockInfo - If there is block info for the specified ID, return it, /// otherwise return null. const BlockInfo *getBlockInfo(unsigned BlockID) const { @@ -119,113 +124,114 @@ public: BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } +}; + + +/// BitstreamEntry - When advancing through a bitstream cursor, each advance can +/// discover a few different kinds of entries: +/// Error - Malformed bitcode was found. +/// EndBlock - We've reached the end of the current block, (or the end of the +/// file, which is treated like a series of EndBlock records. +/// SubBlock - This is the start of a new subblock of a specific ID. +/// Record - This is a record with a specific AbbrevID. +/// +struct BitstreamEntry { + enum { + Error, + EndBlock, + SubBlock, + Record + } Kind; + + unsigned ID; + static BitstreamEntry getError() { + BitstreamEntry E; E.Kind = Error; return E; + } + static BitstreamEntry getEndBlock() { + BitstreamEntry E; E.Kind = EndBlock; return E; + } + static BitstreamEntry getSubBlock(unsigned ID) { + BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; + } + static BitstreamEntry getRecord(unsigned AbbrevID) { + BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; + } }; +/// BitstreamCursor - This represents a position within a bitcode file. There +/// may be multiple independent cursors reading within one bitstream, each +/// maintaining their own local state. +/// +/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not +/// be passed by value. class BitstreamCursor { friend class Deserializer; BitstreamReader *BitStream; size_t NextChar; - - /// CurWord - This is the current data we have pulled from the stream but have - /// not returned to the client. - uint32_t CurWord; - + + + /// CurWord/word_t - This is the current data we have pulled from the stream + /// but have not returned to the client. This is specifically and + /// intentionally defined to follow the word size of the host machine for + /// efficiency. We use word_t in places that are aware of this to make it + /// perfectly explicit what is going on. + typedef uint32_t word_t; + word_t CurWord; + /// BitsInCurWord - This is the number of bits in CurWord that are valid. This - /// is always from [0...31] inclusive. + /// is always from [0...31/63] inclusive (depending on word size). unsigned BitsInCurWord; - + // CurCodeSize - This is the declared size of code values used for the current // block, in bits. unsigned CurCodeSize; - + /// CurAbbrevs - Abbrevs installed at in this block. std::vector<BitCodeAbbrev*> CurAbbrevs; - + struct Block { unsigned PrevCodeSize; std::vector<BitCodeAbbrev*> PrevAbbrevs; explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} }; - + /// BlockScope - This tracks the codesize of parent blocks. SmallVector<Block, 8> BlockScope; - + + public: BitstreamCursor() : BitStream(0), NextChar(0) { } BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { operator=(RHS); } - + explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { NextChar = 0; CurWord = 0; BitsInCurWord = 0; CurCodeSize = 2; } - + void init(BitstreamReader &R) { freeState(); - + BitStream = &R; NextChar = 0; CurWord = 0; BitsInCurWord = 0; CurCodeSize = 2; } - + ~BitstreamCursor() { freeState(); } - - void operator=(const BitstreamCursor &RHS) { - freeState(); - - BitStream = RHS.BitStream; - NextChar = RHS.NextChar; - CurWord = RHS.CurWord; - BitsInCurWord = RHS.BitsInCurWord; - CurCodeSize = RHS.CurCodeSize; - - // Copy abbreviations, and bump ref counts. - CurAbbrevs = RHS.CurAbbrevs; - for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); - i != e; ++i) - CurAbbrevs[i]->addRef(); - - // Copy block scope and bump ref counts. - BlockScope = RHS.BlockScope; - for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); - S != e; ++S) { - std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; - for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size()); - i != e; ++i) - Abbrevs[i]->addRef(); - } - } - - void freeState() { - // Free all the Abbrevs. - for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); - i != e; ++i) - CurAbbrevs[i]->dropRef(); - CurAbbrevs.clear(); - - // Free all the Abbrevs in the block scope. - for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size()); - S != e; ++S) { - std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; - for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size()); - i != e; ++i) - Abbrevs[i]->dropRef(); - } - BlockScope.clear(); - } - - /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. - unsigned GetAbbrevIDWidth() const { return CurCodeSize; } - + + void operator=(const BitstreamCursor &RHS); + + void freeState(); + bool isEndPos(size_t pos) { return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); } @@ -236,61 +242,113 @@ public: static_cast<uint64_t>(pos - 1)); } - unsigned char getByte(size_t pos) { - uint8_t byte = -1; - BitStream->getBitcodeBytes().readByte(pos, &byte); - return byte; - } - uint32_t getWord(size_t pos) { - uint8_t buf[sizeof(uint32_t)]; - memset(buf, 0xFF, sizeof(buf)); - BitStream->getBitcodeBytes().readBytes(pos, - sizeof(buf), - buf, - NULL); + uint8_t buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + BitStream->getBitcodeBytes().readBytes(pos, sizeof(buf), buf, NULL); return *reinterpret_cast<support::ulittle32_t *>(buf); } bool AtEndOfStream() { - return isEndPos(NextChar) && BitsInCurWord == 0; + return BitsInCurWord == 0 && isEndPos(NextChar); } - + + /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. + unsigned getAbbrevIDWidth() const { return CurCodeSize; } + /// GetCurrentBitNo - Return the bit # of the bit we are reading. uint64_t GetCurrentBitNo() const { return NextChar*CHAR_BIT - BitsInCurWord; } - + BitstreamReader *getBitStreamReader() { return BitStream; } const BitstreamReader *getBitStreamReader() const { return BitStream; } - - + + /// Flags that modify the behavior of advance(). + enum { + /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does + /// not automatically pop the block scope when the end of a block is + /// reached. + AF_DontPopBlockAtEnd = 1, + + /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are + /// returned just like normal records. + AF_DontAutoprocessAbbrevs = 2 + }; + + /// advance - Advance the current bitstream, returning the next entry in the + /// stream. + BitstreamEntry advance(unsigned Flags = 0) { + while (1) { + unsigned Code = ReadCode(); + if (Code == bitc::END_BLOCK) { + // Pop the end of the block unless Flags tells us not to. + if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) + return BitstreamEntry::getError(); + return BitstreamEntry::getEndBlock(); + } + + if (Code == bitc::ENTER_SUBBLOCK) + return BitstreamEntry::getSubBlock(ReadSubBlockID()); + + if (Code == bitc::DEFINE_ABBREV && + !(Flags & AF_DontAutoprocessAbbrevs)) { + // We read and accumulate abbrev's, the client can't do anything with + // them anyway. + ReadAbbrevRecord(); + continue; + } + + return BitstreamEntry::getRecord(Code); + } + } + + /// advanceSkippingSubblocks - This is a convenience function for clients that + /// don't expect any subblocks. This just skips over them automatically. + BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { + while (1) { + // If we found a normal entry, return it. + BitstreamEntry Entry = advance(Flags); + if (Entry.Kind != BitstreamEntry::SubBlock) + return Entry; + + // If we found a sub-block, just skip over it and check the next entry. + if (SkipBlock()) + return BitstreamEntry::getError(); + } + } + /// JumpToBit - Reset the stream to the specified bit number. void JumpToBit(uint64_t BitNo) { - uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; - uintptr_t WordBitNo = uintptr_t(BitNo) & 31; + uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); + unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); assert(canSkipToPos(ByteNo) && "Invalid location"); - + // Move the cursor to the right word. NextChar = ByteNo; BitsInCurWord = 0; CurWord = 0; - + // Skip over any bits that are already consumed. - if (WordBitNo) - Read(static_cast<unsigned>(WordBitNo)); + if (WordBitNo) { + if (sizeof(word_t) > 4) + Read64(WordBitNo); + else + Read(WordBitNo); + } } - - + + uint32_t Read(unsigned NumBits) { - assert(NumBits <= 32 && "Cannot return more than 32 bits!"); + assert(NumBits && NumBits <= 32 && + "Cannot return zero or more than 32 bits!"); + // If the field is fully contained by CurWord, return it quickly. if (BitsInCurWord >= NumBits) { - uint32_t R = CurWord & ((1U << NumBits)-1); + uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits)); CurWord >>= NumBits; BitsInCurWord -= NumBits; return R; @@ -303,24 +361,37 @@ public: return 0; } - unsigned R = CurWord; + uint32_t R = uint32_t(CurWord); // Read the next word from the stream. - CurWord = getWord(NextChar); - NextChar += 4; + uint8_t Array[sizeof(word_t)] = {0}; + + BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), + Array, NULL); + + // Handle big-endian byte-swapping if necessary. + support::detail::packed_endian_specific_integral + <word_t, support::little, support::unaligned> EndianValue; + memcpy(&EndianValue, Array, sizeof(Array)); + + CurWord = EndianValue; + + NextChar += sizeof(word_t); // Extract NumBits-BitsInCurWord from what we just read. unsigned BitsLeft = NumBits-BitsInCurWord; - // Be careful here, BitsLeft is in the range [1..32] inclusive. - R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; + // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive. + R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft))) + << BitsInCurWord); - // BitsLeft bits have just been used up from CurWord. - if (BitsLeft != 32) + // BitsLeft bits have just been used up from CurWord. BitsLeft is in the + // range [1..32]/[1..64] so be careful how we shift. + if (BitsLeft != sizeof(word_t)*8) CurWord >>= BitsLeft; else CurWord = 0; - BitsInCurWord = 32-BitsLeft; + BitsInCurWord = sizeof(word_t)*8-BitsLeft; return R; } @@ -369,10 +440,21 @@ public: } } - void SkipToWord() { +private: + void SkipToFourByteBoundary() { + // If word_t is 64-bits and if we've read less than 32 bits, just dump + // the bits we have up to the next 32-bit boundary. + if (sizeof(word_t) > 4 && + BitsInCurWord >= 32) { + CurWord >>= BitsInCurWord-32; + BitsInCurWord = 32; + return; + } + BitsInCurWord = 0; CurWord = 0; } +public: unsigned ReadCode() { return Read(CurCodeSize); @@ -395,62 +477,37 @@ public: // Read and ignore the codelen value. Since we are skipping this block, we // don't care what code widths are used inside of it. ReadVBR(bitc::CodeLenWidth); - SkipToWord(); - unsigned NumWords = Read(bitc::BlockSizeWidth); + SkipToFourByteBoundary(); + unsigned NumFourBytes = Read(bitc::BlockSizeWidth); // Check that the block wasn't partially defined, and that the offset isn't // bogus. - size_t SkipTo = NextChar + NumWords*4; - if (AtEndOfStream() || !canSkipToPos(SkipTo)) + size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; + if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) return true; - NextChar = SkipTo; + JumpToBit(SkipTo); return false; } /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter /// the block, and return true if the block has an error. - bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { - // Save the current block's state on BlockScope. - BlockScope.push_back(Block(CurCodeSize)); - BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); - - // Add the abbrevs specific to this block to the CurAbbrevs list. - if (const BitstreamReader::BlockInfo *Info = - BitStream->getBlockInfo(BlockID)) { - for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); - i != e; ++i) { - CurAbbrevs.push_back(Info->Abbrevs[i]); - CurAbbrevs.back()->addRef(); - } - } - - // Get the codesize of this block. - CurCodeSize = ReadVBR(bitc::CodeLenWidth); - SkipToWord(); - unsigned NumWords = Read(bitc::BlockSizeWidth); - if (NumWordsP) *NumWordsP = NumWords; - - // Validate that this block is sane. - if (CurCodeSize == 0 || AtEndOfStream()) - return true; - - return false; - } + bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0); bool ReadBlockEnd() { if (BlockScope.empty()) return true; // Block tail: // [END_BLOCK, <align4bytes>] - SkipToWord(); + SkipToFourByteBoundary(); - PopBlockScope(); + popBlockScope(); return false; } private: - void PopBlockScope() { + + void popBlockScope() { CurCodeSize = BlockScope.back().PrevCodeSize; // Delete abbrevs from popped scope. @@ -462,207 +519,40 @@ private: BlockScope.pop_back(); } - //===--------------------------------------------------------------------===// + //===--------------------------------------------------------------------===// // Record Processing //===--------------------------------------------------------------------===// private: - void ReadAbbreviatedLiteral(const BitCodeAbbrevOp &Op, - SmallVectorImpl<uint64_t> &Vals) { - assert(Op.isLiteral() && "Not a literal"); - // If the abbrev specifies the literal value to use, use it. - Vals.push_back(Op.getLiteralValue()); - } - - void ReadAbbreviatedField(const BitCodeAbbrevOp &Op, - SmallVectorImpl<uint64_t> &Vals) { - assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); - - // Decode the value as we are commanded. - switch (Op.getEncoding()) { - default: llvm_unreachable("Unknown encoding!"); - case BitCodeAbbrevOp::Fixed: - Vals.push_back(Read((unsigned)Op.getEncodingData())); - break; - case BitCodeAbbrevOp::VBR: - Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData())); - break; - case BitCodeAbbrevOp::Char6: - Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6))); - break; - } - } + void readAbbreviatedLiteral(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals); + void readAbbreviatedField(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals); + void skipAbbreviatedField(const BitCodeAbbrevOp &Op); + public: - /// getAbbrev - Return the abbreviation for the specified AbbrevId. + /// getAbbrev - Return the abbreviation for the specified AbbrevId. const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); return CurAbbrevs[AbbrevNo]; } - - unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, - const char **BlobStart = 0, unsigned *BlobLen = 0) { - if (AbbrevID == bitc::UNABBREV_RECORD) { - unsigned Code = ReadVBR(6); - unsigned NumElts = ReadVBR(6); - for (unsigned i = 0; i != NumElts; ++i) - Vals.push_back(ReadVBR64(6)); - return Code; - } - const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); - - for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { - const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); - if (Op.isLiteral()) { - ReadAbbreviatedLiteral(Op, Vals); - } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { - // Array case. Read the number of elements as a vbr6. - unsigned NumElts = ReadVBR(6); - - // Get the element encoding. - assert(i+2 == e && "array op not second to last?"); - const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); - - // Read all the elements. - for (; NumElts; --NumElts) - ReadAbbreviatedField(EltEnc, Vals); - } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { - // Blob case. Read the number of bytes as a vbr6. - unsigned NumElts = ReadVBR(6); - SkipToWord(); // 32-bit alignment - - // Figure out where the end of this blob will be including tail padding. - size_t NewEnd = NextChar+((NumElts+3)&~3); - - // If this would read off the end of the bitcode file, just set the - // record to empty and return. - if (!canSkipToPos(NewEnd)) { - Vals.append(NumElts, 0); - NextChar = BitStream->getBitcodeBytes().getExtent(); - break; - } - - // Otherwise, read the number of bytes. If we can return a reference to - // the data, do so to avoid copying it. - if (BlobStart) { - *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer( - NextChar, NumElts); - *BlobLen = NumElts; - } else { - for (; NumElts; ++NextChar, --NumElts) - Vals.push_back(getByte(NextChar)); - } - // Skip over tail padding. - NextChar = NewEnd; - } else { - ReadAbbreviatedField(Op, Vals); - } - } - - unsigned Code = (unsigned)Vals[0]; - Vals.erase(Vals.begin()); - return Code; - } + /// skipRecord - Read the current record and discard it. + void skipRecord(unsigned AbbrevID); - unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, - const char *&BlobStart, unsigned &BlobLen) { - return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen); - } + unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, + StringRef *Blob = 0); - //===--------------------------------------------------------------------===// // Abbrev Processing //===--------------------------------------------------------------------===// + void ReadAbbrevRecord(); - void ReadAbbrevRecord() { - BitCodeAbbrev *Abbv = new BitCodeAbbrev(); - unsigned NumOpInfo = ReadVBR(5); - for (unsigned i = 0; i != NumOpInfo; ++i) { - bool IsLiteral = Read(1) ? true : false; - if (IsLiteral) { - Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); - continue; - } - - BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); - if (BitCodeAbbrevOp::hasEncodingData(E)) - Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5))); - else - Abbv->Add(BitCodeAbbrevOp(E)); - } - CurAbbrevs.push_back(Abbv); - } - -public: - - bool ReadBlockInfoBlock() { - // If this is the second stream to get to the block info block, skip it. - if (BitStream->hasBlockInfoRecords()) - return SkipBlock(); - - if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; - - SmallVector<uint64_t, 64> Record; - BitstreamReader::BlockInfo *CurBlockInfo = 0; - - // Read all the records for this module. - while (1) { - unsigned Code = ReadCode(); - if (Code == bitc::END_BLOCK) - return ReadBlockEnd(); - if (Code == bitc::ENTER_SUBBLOCK) { - ReadSubBlockID(); - if (SkipBlock()) return true; - continue; - } - - // Read abbrev records, associate them with CurBID. - if (Code == bitc::DEFINE_ABBREV) { - if (!CurBlockInfo) return true; - ReadAbbrevRecord(); - - // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the - // appropriate BlockInfo. - BitCodeAbbrev *Abbv = CurAbbrevs.back(); - CurAbbrevs.pop_back(); - CurBlockInfo->Abbrevs.push_back(Abbv); - continue; - } - - // Read a record. - Record.clear(); - switch (ReadRecord(Code, Record)) { - default: break; // Default behavior, ignore unknown content. - case bitc::BLOCKINFO_CODE_SETBID: - if (Record.size() < 1) return true; - CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]); - break; - case bitc::BLOCKINFO_CODE_BLOCKNAME: { - if (!CurBlockInfo) return true; - if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. - std::string Name; - for (unsigned i = 0, e = Record.size(); i != e; ++i) - Name += (char)Record[i]; - CurBlockInfo->Name = Name; - break; - } - case bitc::BLOCKINFO_CODE_SETRECORDNAME: { - if (!CurBlockInfo) return true; - if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. - std::string Name; - for (unsigned i = 1, e = Record.size(); i != e; ++i) - Name += (char)Record[i]; - CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0], - Name)); - break; - } - } - } - } + bool ReadBlockInfoBlock(); }; - + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h index dea118f..a837211 100644 --- a/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h +++ b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef BITSTREAM_WRITER_H -#define BITSTREAM_WRITER_H +#ifndef LLVM_BITCODE_BITSTREAMWRITER_H +#define LLVM_BITCODE_BITSTREAMWRITER_H -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitCodes.h" #include <vector> @@ -273,7 +273,7 @@ public: private: /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev - /// record. This is a no-op, since the abbrev specifies the literal to use. + /// record. This is a no-op, since the abbrev specifies the literal to use. template<typename uintty> void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) { assert(Op.isLiteral() && "Not a literal"); @@ -282,13 +282,13 @@ private: assert(V == Op.getLiteralValue() && "Invalid abbrev for record!"); } - + /// EmitAbbreviatedField - Emit a single scalar field value with the specified /// encoding. template<typename uintty> void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) { assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!"); - + // Encode the value as we are commanded. switch (Op.getEncoding()) { default: llvm_unreachable("Unknown encoding!"); @@ -305,7 +305,7 @@ private: break; } } - + /// EmitRecordWithAbbrevImpl - This is the core implementation of the record /// emission code. If BlobData is non-null, then it specifies an array of /// data that should be emitted as part of the Blob or Array operand that is @@ -341,11 +341,11 @@ private: "Blob data and record entries specified for array!"); // Emit a vbr6 to indicate the number of elements present. EmitVBR(static_cast<uint32_t>(BlobLen), 6); - + // Emit each field. for (unsigned i = 0; i != BlobLen; ++i) EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]); - + // Know that blob data is consumed for assertion below. BlobData = 0; } else { @@ -359,7 +359,7 @@ private: } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { // If this record has blob data, emit it, otherwise we must have record // entries to encode this way. - + // Emit a vbr6 to indicate the number of elements present. if (BlobData) { EmitVBR(static_cast<uint32_t>(BlobLen), 6); @@ -368,7 +368,7 @@ private: } else { EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); } - + // Flush to a 32-bit alignment boundary. FlushToWord(); @@ -376,7 +376,7 @@ private: if (BlobData) { for (unsigned i = 0; i != BlobLen; ++i) WriteByte((unsigned char)BlobData[i]); - + // Know that blob data is consumed for assertion below. BlobData = 0; } else { @@ -399,7 +399,7 @@ private: assert(BlobData == 0 && "Blob data specified for record that doesn't use it!"); } - + public: /// EmitRecord - Emit the specified record to the stream, using an abbrev if @@ -420,10 +420,10 @@ public: // Insert the code into Vals to treat it uniformly. Vals.insert(Vals.begin(), Code); - + EmitRecordWithAbbrev(Abbrev, Vals); } - + /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation. /// Unlike EmitRecord, the code for the record should be included in Vals as /// the first entry. @@ -431,7 +431,7 @@ public: void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) { EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef()); } - + /// EmitRecordWithBlob - Emit the specified record to the stream, using an /// abbrev that includes a blob at the end. The blob data to emit is /// specified by the pointer and length specified at the end. In contrast to @@ -458,10 +458,10 @@ public: template<typename uintty> void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, const char *ArrayData, unsigned ArrayLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, + return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, ArrayLen)); } - + //===--------------------------------------------------------------------===// // Abbrev Emission //===--------------------------------------------------------------------===// diff --git a/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h index c1dc190..f9690d5 100644 --- a/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -29,18 +29,17 @@ namespace bitc { // Module sub-block id's. PARAMATTR_BLOCK_ID, + PARAMATTR_GROUP_BLOCK_ID, - UNUSED_ID1, - CONSTANTS_BLOCK_ID, FUNCTION_BLOCK_ID, - - UNUSED_ID2, - + + UNUSED_ID1, + VALUE_SYMTAB_BLOCK_ID, METADATA_BLOCK_ID, METADATA_ATTACHMENT_ID, - + TYPE_BLOCK_ID_NEW, USELIST_BLOCK_ID @@ -54,6 +53,8 @@ namespace bitc { MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] MODULE_CODE_ASM = 4, // ASM: [strchr x N] MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] + + // FIXME: Remove DEPLIB in 4.0. MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] // GLOBALVAR: [pointer type, isconst, initid, @@ -67,7 +68,7 @@ namespace bitc { // ALIAS: [alias type, aliasee val#, linkage, visibility] MODULE_CODE_ALIAS = 9, - /// MODULE_CODE_PURGEVALS: [numvals] + // MODULE_CODE_PURGEVALS: [numvals] MODULE_CODE_PURGEVALS = 10, MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N] @@ -75,7 +76,12 @@ namespace bitc { /// PARAMATTR blocks have code for defining a parameter attribute set. enum AttributeCodes { - PARAMATTR_CODE_ENTRY = 1 // ENTRY: [paramidx0, attr0, paramidx1, attr1...] + // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0 + PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0, + // paramidx1, attr1...] + PARAMATTR_CODE_ENTRY = 2, // ENTRY: [paramidx0, attrgrp0, + // paramidx1, attrgrp1, ...] + PARAMATTR_GRP_CODE_ENTRY = 3 // ENTRY: [id, attr0, att1, ...] }; /// TYPE blocks have codes for each type primitive they use. @@ -93,9 +99,9 @@ namespace bitc { TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty, // paramty x N] - + TYPE_CODE_HALF = 10, // HALF - + TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] @@ -109,7 +115,7 @@ namespace bitc { TYPE_CODE_METADATA = 16, // METADATA TYPE_CODE_X86_MMX = 17, // X86 MMX - + TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N] TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N] TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N] @@ -141,6 +147,7 @@ namespace bitc { METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]] }; + // The constants block (CONSTANTS_BLOCK_ID) describes emission for each // constant and maintains an implicit current type value. enum ConstantsCodes { @@ -234,7 +241,7 @@ namespace bitc { OBO_NO_SIGNED_WRAP = 1 }; - /// PossiblyExactOperatorOptionalFlags - Flags for serializing + /// PossiblyExactOperatorOptionalFlags - Flags for serializing /// PossiblyExactOperator's SubclassOptionalData contents. enum PossiblyExactOperatorOptionalFlags { PEO_EXACT = 0 diff --git a/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h b/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h index dd96b04..78f40ca 100644 --- a/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h +++ b/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_BITCODE_H -#define LLVM_BITCODE_H +#ifndef LLVM_BITCODE_READERWRITER_H +#define LLVM_BITCODE_READERWRITER_H #include <string> diff --git a/contrib/llvm/include/llvm/CodeGen/Analysis.h b/contrib/llvm/include/llvm/CodeGen/Analysis.h index 0b609ed..ce9ca0a 100644 --- a/contrib/llvm/include/llvm/CodeGen/Analysis.h +++ b/contrib/llvm/include/llvm/CodeGen/Analysis.h @@ -14,12 +14,12 @@ #ifndef LLVM_CODEGEN_ANALYSIS_H #define LLVM_CODEGEN_ANALYSIS_H -#include "llvm/Instructions.h" -#include "llvm/InlineAsm.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" #include "llvm/Support/CallSite.h" namespace llvm { @@ -86,11 +86,7 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred); /// between it and the return. /// /// This function only tests target-independent requirements. -bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr, - const TargetLowering &TLI); - -bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, - SDValue &Chain, const TargetLowering &TLI); +bool isInTailCallPosition(ImmutableCallSite CS, const TargetLowering &TLI); } // End llvm namespace diff --git a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h index a92b859..e0a6e3f 100644 --- a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -17,7 +17,7 @@ #define LLVM_CODEGEN_ASMPRINTER_H #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/InlineAsm.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -385,10 +385,8 @@ namespace llvm { /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. unsigned GetSizeOfEncodedValue(unsigned Encoding) const; - /// EmitReference - Emit a reference to a label with a specified encoding. - /// - void EmitReference(const MCSymbol *Sym, unsigned Encoding) const; - void EmitReference(const GlobalValue *GV, unsigned Encoding) const; + /// EmitReference - Emit reference to a ttype global with a specified encoding. + void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const; /// EmitSectionOffset - Emit the 4-byte offset of Label from the start of /// its section. This can be done with a special directive if the target diff --git a/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h index 2f76a6c..9cd2dec 100644 --- a/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h +++ b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h @@ -11,8 +11,8 @@ #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H -#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/SlotIndexes.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h index 436918b1..c035e07 100644 --- a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -16,11 +16,11 @@ #define LLVM_CODEGEN_CALLINGCONVLOWER_H #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/CallingConv.h" #include "llvm/Target/TargetCallingConv.h" -#include "llvm/CallingConv.h" namespace llvm { class TargetRegisterInfo; @@ -50,10 +50,10 @@ private: unsigned Loc; /// isMem - True if this is a memory loc, false if it is a register loc. - bool isMem : 1; + unsigned isMem : 1; /// isCustom - True if this arg/retval requires special handling. - bool isCustom : 1; + unsigned isCustom : 1; /// Information about how the value is assigned. LocInfo HTP : 6; diff --git a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h index 90ee234..9a27661 100644 --- a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h @@ -1,4 +1,4 @@ -//===-- CommandFlags.h - Register Coalescing Interface ----------*- C++ -*-===// +//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,13 +13,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H -#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H +#ifndef LLVM_CODEGEN_COMMANDFLAGS_H +#define LLVM_CODEGEN_COMMANDFLAGS_H -#include "llvm/Support/CommandLine.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetMachine.h" - #include <string> using namespace llvm; diff --git a/contrib/llvm/include/llvm/CodeGen/DAGCombine.h b/contrib/llvm/include/llvm/CodeGen/DAGCombine.h new file mode 100644 index 0000000..8b591900 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/DAGCombine.h @@ -0,0 +1,25 @@ +//===-- llvm/CodeGen/DAGCombine.h ------- SelectionDAG Nodes ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +#ifndef LLVM_CODEGEN_DAGCOMBINE_H +#define LLVM_CODEGEN_DAGCOMBINE_H + +namespace llvm { + +enum CombineLevel { + BeforeLegalizeTypes, + AfterLegalizeTypes, + AfterLegalizeVectorOps, + AfterLegalizeDAG +}; + +} // end llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h index 2d2db78..9d25fd3 100644 --- a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h +++ b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h @@ -26,8 +26,8 @@ #ifndef LLVM_CODEGEN_DFAPACKETIZER_H #define LLVM_CODEGEN_DFAPACKETIZER_H -#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include <map> namespace llvm { @@ -135,7 +135,7 @@ public: // initPacketizerState - perform initialization before packetizing // an instruction. This function is supposed to be overrided by // the target dependent packetizer. - virtual void initPacketizerState(void) { return; } + virtual void initPacketizerState() { return; } // ignorePseudoInstruction - Ignore bundling of pseudo instructions. virtual bool ignorePseudoInstruction(MachineInstr *I, diff --git a/contrib/llvm/include/llvm/CodeGen/FastISel.h b/contrib/llvm/include/llvm/CodeGen/FastISel.h index 7c24e36..705db7e 100644 --- a/contrib/llvm/include/llvm/CodeGen/FastISel.h +++ b/contrib/llvm/include/llvm/CodeGen/FastISel.h @@ -15,8 +15,8 @@ #define LLVM_CODEGEN_FASTISEL_H #include "llvm/ADT/DenseMap.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/ValueTypes.h" namespace llvm { @@ -90,6 +90,11 @@ public: /// getCurDebugLoc() - Return current debug location information. DebugLoc getCurDebugLoc() const { return DL; } + + /// LowerArguments - Do "fast" instruction selection for function arguments + /// and append machine instructions to the current block. Return true if + /// it is successful. + bool LowerArguments(); /// SelectInstruction - Do "fast" instruction selection for the given /// LLVM IR instruction, and append generated machine instructions to @@ -131,6 +136,10 @@ public: /// into the current block. void recomputeInsertPt(); + /// removeDeadCode - Remove all dead instructions between the I and E. + void removeDeadCode(MachineBasicBlock::iterator I, + MachineBasicBlock::iterator E); + struct SavePoint { MachineBasicBlock::iterator InsertPt; DebugLoc DL; @@ -156,6 +165,11 @@ protected: /// virtual bool TargetSelectInstruction(const Instruction *I) = 0; + + /// FastLowerArguments - This method is called by target-independent code to + /// do target specific argument lowering. It returns true if it was + /// successful. + virtual bool FastLowerArguments(); /// FastEmit_r - This method is called by target-independent code /// to request that an instruction with the given type and opcode @@ -395,10 +409,6 @@ private: /// hasTrivialKill - Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V) const; - - /// removeDeadCode - Remove all dead instructions between the I and E. - void removeDeadCode(MachineBasicBlock::iterator I, - MachineBasicBlock::iterator E); }; } diff --git a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h index 8cf22ec..ea6cb27 100644 --- a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -15,19 +15,15 @@ #ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H #define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/BranchProbabilityInfo.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/Support/CallSite.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" #include "llvm/Target/TargetRegisterInfo.h" #include <vector> @@ -35,6 +31,7 @@ namespace llvm { class AllocaInst; class BasicBlock; +class BranchProbabilityInfo; class CallInst; class Function; class GlobalVariable; @@ -136,7 +133,7 @@ public: return ValueMap.count(V); } - unsigned CreateReg(EVT VT); + unsigned CreateReg(MVT VT); unsigned CreateRegs(Type *Ty); diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h index 076f6f3..1070d29 100644 --- a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h +++ b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h @@ -33,9 +33,9 @@ #ifndef LLVM_CODEGEN_GCMETADATA_H #define LLVM_CODEGEN_GCMETADATA_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Pass.h" #include "llvm/Support/DebugLoc.h" namespace llvm { @@ -180,7 +180,8 @@ namespace llvm { GCModuleInfo(); ~GCModuleInfo(); - /// clear - Resets the pass. The metadata deleter pass calls this. + /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should + /// call it in doFinalization(). /// void clear(); diff --git a/contrib/llvm/include/llvm/CodeGen/GCs.h b/contrib/llvm/include/llvm/CodeGen/GCs.h index c407b61..456d2dc 100644 --- a/contrib/llvm/include/llvm/CodeGen/GCs.h +++ b/contrib/llvm/include/llvm/CodeGen/GCs.h @@ -26,6 +26,12 @@ namespace llvm { /// Creates an ocaml-compatible metadata printer. void linkOcamlGCPrinter(); + + /// Creates an erlang-compatible garbage collector. + void linkErlangGC(); + + /// Creates an erlang-compatible metadata printer. + void linkErlangGCPrinter(); /// Creates a shadow stack garbage collector. This collector requires no code /// generator support. diff --git a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h index 5d0a3b4..442729b 100644 --- a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -311,8 +311,10 @@ namespace ISD { /// the shift amount can be any type, but care must be taken to ensure it is /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before /// legalization, types like i1024 can occur and i8 doesn't have enough bits - /// to represent the shift amount. By convention, DAGCombine and - /// SelectionDAGBuilder forces these shift amounts to i32 for simplicity. + /// to represent the shift amount. + /// When the 1st operand is a vector, the shift amount must be in the same + /// type. (TLI.getShiftAmountTy() will return the same type when the input + /// type is a vector.) SHL, SRA, SRL, ROTL, ROTR, /// Byte Swap and Counting operators. @@ -455,6 +457,9 @@ namespace ISD { FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, FLOG, FLOG2, FLOG10, FEXP, FEXP2, FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR, + + /// FSINCOS - Compute both fsin and fcos as a single operation. + FSINCOS, /// LOAD and STORE have token chains as their first operand, then the same /// operands as an LLVM load/store instruction, then an offset node that diff --git a/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h index 5a3fb4b..68389dd 100644 --- a/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h +++ b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h @@ -16,7 +16,7 @@ #ifndef LLVM_CODEGEN_INTRINSICLOWERING_H #define LLVM_CODEGEN_INTRINSICLOWERING_H -#include "llvm/Intrinsics.h" +#include "llvm/IR/Intrinsics.h" namespace llvm { class CallInst; diff --git a/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h b/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h index 89f00e9..9a73214 100644 --- a/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h +++ b/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h @@ -17,11 +17,11 @@ #ifndef LLVM_CODEGEN_JITCODEEMITTER_H #define LLVM_CODEGEN_JITCODEEMITTER_H -#include <string> +#include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MathExtras.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include "llvm/ADT/DenseMap.h" +#include <string> namespace llvm { @@ -207,8 +207,7 @@ public: /// emitString - This callback is invoked when a String needs to be /// written to the output stream. void emitString(const std::string &String) { - for (unsigned i = 0, N = static_cast<unsigned>(String.size()); - i < N; ++i) { + for (size_t i = 0, N = String.size(); i < N; ++i) { uint8_t C = String[i]; emitByte(C); } diff --git a/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h b/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h index 8fb31aa..d454347 100644 --- a/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LATENCY_PRIORITY_QUEUE_H -#define LATENCY_PRIORITY_QUEUE_H +#ifndef LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H +#define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H #include "llvm/CodeGen/ScheduleDAG.h" diff --git a/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h index 8414c64..ff65db4 100644 --- a/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h +++ b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h @@ -17,11 +17,11 @@ #ifndef LLVM_CODEGEN_LEXICALSCOPES_H #define LLVM_CODEGEN_LEXICALSCOPES_H -#include "llvm/Metadata.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Support/ValueHandle.h" #include <utility> @@ -159,9 +159,6 @@ public: LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) { -#ifndef NDEBUG - IndentLevel = 0; -#endif if (Parent) Parent->addChild(this); } @@ -228,7 +225,7 @@ public: void setDFSIn(unsigned I) { DFSIn = I; } /// dump - print lexical scope. - void dump() const; + void dump(unsigned Indent = 0) const; private: LexicalScope *Parent; // Parent to this scope. @@ -244,9 +241,6 @@ private: const MachineInstr *FirstInsn; // First instruction of this scope. unsigned DFSIn, DFSOut; // In & Out Depth use to determine // scope nesting. -#ifndef NDEBUG - mutable unsigned IndentLevel; // Private state for dump() -#endif }; } // end llvm namespace diff --git a/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h index 7d1b1fe..c3046da 100644 --- a/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h +++ b/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h @@ -29,6 +29,7 @@ namespace { return; llvm::linkOcamlGCPrinter(); + llvm::linkErlangGCPrinter(); } } ForceAsmWriterLinking; // Force link by creating a global definition. diff --git a/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h b/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h index 46dd004..916c0f2 100644 --- a/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -15,9 +15,9 @@ #ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H #define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H +#include "llvm/CodeGen/GCs.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/CodeGen/GCs.h" #include "llvm/Target/TargetMachine.h" #include <cstdlib> @@ -37,6 +37,7 @@ namespace { (void) llvm::createDefaultPBQPRegisterAllocator(); llvm::linkOcamlGC(); + llvm::linkErlangGC(); llvm::linkShadowStackGC(); (void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default); diff --git a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h index 185e414..244be9c 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h @@ -22,9 +22,9 @@ #define LLVM_CODEGEN_LIVEINTERVAL_H #include "llvm/ADT/IntEqClasses.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/AlignOf.h" #include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/Allocator.h" #include <cassert> #include <climits> @@ -86,9 +86,10 @@ namespace llvm { SlotIndex end; // End point of the interval (exclusive) VNInfo *valno; // identifier for the value contained in this interval. + LiveRange() : valno(0) {} + LiveRange(SlotIndex S, SlotIndex E, VNInfo *V) : start(S), end(E), valno(V) { - assert(S < E && "Cannot create empty or backwards range"); } @@ -373,8 +374,8 @@ namespace llvm { /// addRange - Add the specified LiveRange to this interval, merging /// intervals as appropriate. This returns an iterator to the inserted live /// range (which may have grown since it was inserted. - void addRange(LiveRange LR) { - addRangeFrom(LR, ranges.begin()); + iterator addRange(LiveRange LR) { + return addRangeFrom(LR, ranges.begin()); } /// extendInBlock - If this interval is live before Kill in the basic block @@ -460,9 +461,6 @@ namespace llvm { void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr); void markValNoForDeletion(VNInfo *V); - void mergeIntervalRanges(const LiveInterval &RHS, - VNInfo *LHSValNo = 0, - const VNInfo *RHSValNo = 0); LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION; @@ -473,6 +471,64 @@ namespace llvm { return OS; } + /// Helper class for performant LiveInterval bulk updates. + /// + /// Calling LiveInterval::addRange() repeatedly can be expensive on large + /// live ranges because segments after the insertion point may need to be + /// shifted. The LiveRangeUpdater class can defer the shifting when adding + /// many segments in order. + /// + /// The LiveInterval will be in an invalid state until flush() is called. + class LiveRangeUpdater { + LiveInterval *LI; + SlotIndex LastStart; + LiveInterval::iterator WriteI; + LiveInterval::iterator ReadI; + SmallVector<LiveRange, 16> Spills; + void mergeSpills(); + + public: + /// Create a LiveRangeUpdater for adding segments to LI. + /// LI will temporarily be in an invalid state until flush() is called. + LiveRangeUpdater(LiveInterval *li = 0) : LI(li) {} + + ~LiveRangeUpdater() { flush(); } + + /// Add a segment to LI and coalesce when possible, just like LI.addRange(). + /// Segments should be added in increasing start order for best performance. + void add(LiveRange); + + void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) { + add(LiveRange(Start, End, VNI)); + } + + /// Return true if the LI is currently in an invalid state, and flush() + /// needs to be called. + bool isDirty() const { return LastStart.isValid(); } + + /// Flush the updater state to LI so it is valid and contains all added + /// segments. + void flush(); + + /// Select a different destination live range. + void setDest(LiveInterval *li) { + if (LI != li && isDirty()) + flush(); + LI = li; + } + + /// Get the current destination live range. + LiveInterval *getDest() const { return LI; } + + void dump() const; + void print(raw_ostream&) const; + }; + + inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) { + X.print(OS); + return OS; + } + /// LiveRangeQuery - Query information about a live range around a given /// instruction. This class hides the implementation details of live ranges, /// and it should be used as the primary interface for examining live ranges diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h index b421753..7d72f37 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -20,22 +20,21 @@ #ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H #define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/IndexedMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/SlotIndexes.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/IndexedMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <cmath> #include <iterator> namespace llvm { class AliasAnalysis; + class BitVector; class LiveRangeCalc; class LiveVariables; class MachineDominatorTree; @@ -53,7 +52,6 @@ namespace llvm { const TargetRegisterInfo* TRI; const TargetInstrInfo* TII; AliasAnalysis *AA; - LiveVariables* LV; SlotIndexes* Indexes; MachineDominatorTree *DomTree; LiveRangeCalc *LRCalc; @@ -215,6 +213,13 @@ namespace llvm { return Indexes->getMBBFromIndex(index); } + void insertMBBInMaps(MachineBasicBlock *MBB) { + Indexes->insertMBBInMaps(MBB); + assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() && + "Blocks must be added in order."); + RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0)); + } + SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) { return Indexes->insertMachineInstrInMaps(MI); } @@ -275,6 +280,21 @@ namespace llvm { void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart, bool UpdateFlags = false); + /// repairIntervalsInRange - Update live intervals for instructions in a + /// range of iterators. It is intended for use after target hooks that may + /// insert or remove instructions, and is only efficient for a small number + /// of instructions. + /// + /// OrigRegs is a vector of registers that were originally used by the + /// instructions in the range between the two iterators. + /// + /// Currently, the only only changes that are supported are simple removal + /// and addition of uses. + void repairIntervalsInRange(MachineBasicBlock *MBB, + MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End, + ArrayRef<unsigned> OrigRegs); + // Register mask functions. // // Machine instructions may use a register mask operand to indicate that a @@ -347,37 +367,17 @@ namespace llvm { return RegUnitIntervals[Unit]; } - private: - /// computeIntervals - Compute live intervals. - void computeIntervals(); + const LiveInterval *getCachedRegUnit(unsigned Unit) const { + return RegUnitIntervals[Unit]; + } + private: /// Compute live intervals for all virtual registers. void computeVirtRegs(); /// Compute RegMaskSlots and RegMaskBits. void computeRegMasks(); - /// handleRegisterDef - update intervals for a register def - /// (calls handleVirtualRegisterDef) - void handleRegisterDef(MachineBasicBlock *MBB, - MachineBasicBlock::iterator MI, - SlotIndex MIIdx, - MachineOperand& MO, unsigned MOIdx); - - /// isPartialRedef - Return true if the specified def at the specific index - /// is partially re-defining the specified live interval. A common case of - /// this is a definition of the sub-register. - bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO, - LiveInterval &interval); - - /// handleVirtualRegisterDef - update intervals for a virtual - /// register def - void handleVirtualRegisterDef(MachineBasicBlock *MBB, - MachineBasicBlock::iterator MI, - SlotIndex MIIdx, MachineOperand& MO, - unsigned MOIdx, - LiveInterval& interval); - static LiveInterval* createInterval(unsigned Reg); void printInstrs(raw_ostream &O) const; diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h new file mode 100644 index 0000000..615b339 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalUnion.h @@ -0,0 +1,205 @@ +//===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// LiveIntervalUnion is a union of live segments across multiple live virtual +// registers. This may be used during coalescing to represent a congruence +// class, or during register allocation to model liveness of a physical +// register. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H +#define LLVM_CODEGEN_LIVEINTERVALUNION_H + +#include "llvm/ADT/IntervalMap.h" +#include "llvm/CodeGen/LiveInterval.h" + +namespace llvm { + +class TargetRegisterInfo; + +#ifndef NDEBUG +// forward declaration +template <unsigned Element> class SparseBitVector; +typedef SparseBitVector<128> LiveVirtRegBitSet; +#endif + +/// Compare a live virtual register segment to a LiveIntervalUnion segment. +inline bool +overlap(const LiveRange &VRSeg, + const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) { + return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end; +} + +/// Union of live intervals that are strong candidates for coalescing into a +/// single register (either physical or virtual depending on the context). We +/// expect the constituent live intervals to be disjoint, although we may +/// eventually make exceptions to handle value-based interference. +class LiveIntervalUnion { + // A set of live virtual register segments that supports fast insertion, + // intersection, and removal. + // Mapping SlotIndex intervals to virtual register numbers. + typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments; + +public: + // SegmentIter can advance to the next segment ordered by starting position + // which may belong to a different live virtual register. We also must be able + // to reach the current segment's containing virtual register. + typedef LiveSegments::iterator SegmentIter; + + // LiveIntervalUnions share an external allocator. + typedef LiveSegments::Allocator Allocator; + + class Query; + +private: + unsigned Tag; // unique tag for current contents. + LiveSegments Segments; // union of virtual reg segments + +public: + explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {} + + // Iterate over all segments in the union of live virtual registers ordered + // by their starting position. + SegmentIter begin() { return Segments.begin(); } + SegmentIter end() { return Segments.end(); } + SegmentIter find(SlotIndex x) { return Segments.find(x); } + bool empty() const { return Segments.empty(); } + SlotIndex startIndex() const { return Segments.start(); } + + // Provide public access to the underlying map to allow overlap iteration. + typedef LiveSegments Map; + const Map &getMap() { return Segments; } + + /// getTag - Return an opaque tag representing the current state of the union. + unsigned getTag() const { return Tag; } + + /// changedSince - Return true if the union change since getTag returned tag. + bool changedSince(unsigned tag) const { return tag != Tag; } + + // Add a live virtual register to this union and merge its segments. + void unify(LiveInterval &VirtReg); + + // Remove a live virtual register's segments from this union. + void extract(LiveInterval &VirtReg); + + // Remove all inserted virtual registers. + void clear() { Segments.clear(); ++Tag; } + + // Print union, using TRI to translate register names + void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const; + +#ifndef NDEBUG + // Verify the live intervals in this union and add them to the visited set. + void verify(LiveVirtRegBitSet& VisitedVRegs); +#endif + + /// Query interferences between a single live virtual register and a live + /// interval union. + class Query { + LiveIntervalUnion *LiveUnion; + LiveInterval *VirtReg; + LiveInterval::iterator VirtRegI; // current position in VirtReg + SegmentIter LiveUnionI; // current position in LiveUnion + SmallVector<LiveInterval*,4> InterferingVRegs; + bool CheckedFirstInterference; + bool SeenAllInterferences; + bool SeenUnspillableVReg; + unsigned Tag, UserTag; + + public: + Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {} + + Query(LiveInterval *VReg, LiveIntervalUnion *LIU): + LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false), + SeenAllInterferences(false), SeenUnspillableVReg(false) + {} + + void clear() { + LiveUnion = NULL; + VirtReg = NULL; + InterferingVRegs.clear(); + CheckedFirstInterference = false; + SeenAllInterferences = false; + SeenUnspillableVReg = false; + Tag = 0; + UserTag = 0; + } + + void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) { + assert(VReg && LIU && "Invalid arguments"); + if (UserTag == UTag && VirtReg == VReg && + LiveUnion == LIU && !LIU->changedSince(Tag)) { + // Retain cached results, e.g. firstInterference. + return; + } + clear(); + LiveUnion = LIU; + VirtReg = VReg; + Tag = LIU->getTag(); + UserTag = UTag; + } + + LiveInterval &virtReg() const { + assert(VirtReg && "uninitialized"); + return *VirtReg; + } + + // Does this live virtual register interfere with the union? + bool checkInterference() { return collectInterferingVRegs(1); } + + // Count the virtual registers in this union that interfere with this + // query's live virtual register, up to maxInterferingRegs. + unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX); + + // Was this virtual register visited during collectInterferingVRegs? + bool isSeenInterference(LiveInterval *VReg) const; + + // Did collectInterferingVRegs collect all interferences? + bool seenAllInterferences() const { return SeenAllInterferences; } + + // Did collectInterferingVRegs encounter an unspillable vreg? + bool seenUnspillableVReg() const { return SeenUnspillableVReg; } + + // Vector generated by collectInterferingVRegs. + const SmallVectorImpl<LiveInterval*> &interferingVRegs() const { + return InterferingVRegs; + } + + private: + Query(const Query&) LLVM_DELETED_FUNCTION; + void operator=(const Query&) LLVM_DELETED_FUNCTION; + }; + + // Array of LiveIntervalUnions. + class Array { + unsigned Size; + LiveIntervalUnion *LIUs; + public: + Array() : Size(0), LIUs(0) {} + ~Array() { clear(); } + + // Initialize the array to have Size entries. + // Reuse an existing allocation if the size matches. + void init(LiveIntervalUnion::Allocator&, unsigned Size); + + unsigned size() const { return Size; } + + void clear(); + + LiveIntervalUnion& operator[](unsigned idx) { + assert(idx < Size && "idx out of bounds"); + return LIUs[idx]; + } + }; +}; + +} // end namespace llvm + +#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION_H) diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h index def7b00..8a32a3c 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -83,7 +83,7 @@ private: /// allUsesAvailableAt - Return true if all registers used by OrigMI at /// OrigIdx are also available with the same value at UseIdx. bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, - SlotIndex UseIdx); + SlotIndex UseIdx) const; /// foldAsLoad - If LI has a single use and a single def that can be folded as /// a load, eliminate the register by folding the def into the use. diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h new file mode 100644 index 0000000..7a3e9e8 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h @@ -0,0 +1,148 @@ +//===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRegMatrix analysis pass keeps track of virtual register interference +// along two dimensions: Slot indexes and register units. The matrix is used by +// register allocators to ensure that no interfering virtual registers get +// assigned to overlapping physical registers. +// +// Register units are defined in MCRegisterInfo.h, they represent the smallest +// unit of interference when dealing with overlapping physical registers. The +// LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When +// a virtual register is assigned to a physical register, the live range for +// the virtual register is inserted into the LiveIntervalUnion for each regunit +// in the physreg. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVEREGMATRIX_H +#define LLVM_CODEGEN_LIVEREGMATRIX_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/CodeGen/LiveIntervalUnion.h" +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { + +class LiveInterval; +class LiveIntervalAnalysis; +class MachineRegisterInfo; +class TargetRegisterInfo; +class VirtRegMap; + +class LiveRegMatrix : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + LiveIntervals *LIS; + VirtRegMap *VRM; + + // UserTag changes whenever virtual registers have been modified. + unsigned UserTag; + + // The matrix is represented as a LiveIntervalUnion per register unit. + LiveIntervalUnion::Allocator LIUAlloc; + LiveIntervalUnion::Array Matrix; + + // Cached queries per register unit. + OwningArrayPtr<LiveIntervalUnion::Query> Queries; + + // Cached register mask interference info. + unsigned RegMaskTag; + unsigned RegMaskVirtReg; + BitVector RegMaskUsable; + + // MachineFunctionPass boilerplate. + virtual void getAnalysisUsage(AnalysisUsage&) const; + virtual bool runOnMachineFunction(MachineFunction&); + virtual void releaseMemory(); +public: + static char ID; + LiveRegMatrix(); + + //===--------------------------------------------------------------------===// + // High-level interface. + //===--------------------------------------------------------------------===// + // + // Check for interference before assigning virtual registers to physical + // registers. + // + + /// Invalidate cached interference queries after modifying virtual register + /// live ranges. Interference checks may return stale information unless + /// caches are invalidated. + void invalidateVirtRegs() { ++UserTag; } + + enum InterferenceKind { + /// No interference, go ahead and assign. + IK_Free = 0, + + /// Virtual register interference. There are interfering virtual registers + /// assigned to PhysReg or its aliases. This interference could be resolved + /// by unassigning those other virtual registers. + IK_VirtReg, + + /// Register unit interference. A fixed live range is in the way, typically + /// argument registers for a call. This can't be resolved by unassigning + /// other virtual registers. + IK_RegUnit, + + /// RegMask interference. The live range is crossing an instruction with a + /// regmask operand that doesn't preserve PhysReg. This typically means + /// VirtReg is live across a call, and PhysReg isn't call-preserved. + IK_RegMask + }; + + /// Check for interference before assigning VirtReg to PhysReg. + /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg). + /// When there is more than one kind of interference, the InterferenceKind + /// with the highest enum value is returned. + InterferenceKind checkInterference(LiveInterval &VirtReg, unsigned PhysReg); + + /// Assign VirtReg to PhysReg. + /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and + /// update VirtRegMap. The live range is expected to be available in PhysReg. + void assign(LiveInterval &VirtReg, unsigned PhysReg); + + /// Unassign VirtReg from its PhysReg. + /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes + /// the assignment and updates VirtRegMap accordingly. + void unassign(LiveInterval &VirtReg); + + //===--------------------------------------------------------------------===// + // Low-level interface. + //===--------------------------------------------------------------------===// + // + // Provide access to the underlying LiveIntervalUnions. + // + + /// Check for regmask interference only. + /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg. + /// If PhysReg is null, check if VirtReg crosses any regmask operands. + bool checkRegMaskInterference(LiveInterval &VirtReg, unsigned PhysReg = 0); + + /// Check for regunit interference only. + /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's + /// register units. + bool checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg); + + /// Query a line of the assigned virtual register matrix directly. + /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg. + /// This returns a reference to an internal Query data structure that is only + /// valid until the next query() call. + LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit); + + /// Directly access the live interval unions per regunit. + /// This returns an array indexed by the regunit number. + LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; } +}; + +} // end namespace llvm + +#endif // LLVM_CODEGEN_LIVEREGMATRIX_H diff --git a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h index 86c4d7c..92c35f7 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h @@ -13,13 +13,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H -#define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H +#ifndef LLVM_CODEGEN_LIVESTACKANALYSIS_H +#define LLVM_CODEGEN_LIVESTACKANALYSIS_H -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/LiveInterval.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <map> namespace llvm { diff --git a/contrib/llvm/include/llvm/CodeGen/LiveVariables.h b/contrib/llvm/include/llvm/CodeGen/LiveVariables.h index 3bb134b..6628fd2 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveVariables.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveVariables.h @@ -29,21 +29,19 @@ #ifndef LLVM_CODEGEN_LIVEVARIABLES_H #define LLVM_CODEGEN_LIVEVARIABLES_H -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SparseBitVector.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetRegisterInfo.h" namespace llvm { +class MachineBasicBlock; class MachineRegisterInfo; -class TargetRegisterInfo; class LiveVariables : public MachineFunctionPass { public: diff --git a/contrib/llvm/include/llvm/CodeGen/MachORelocation.h b/contrib/llvm/include/llvm/CodeGen/MachORelocation.h index 21fe74f..8c9b7a8 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachORelocation.h +++ b/contrib/llvm/include/llvm/CodeGen/MachORelocation.h @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H -#define LLVM_CODEGEN_MACHO_RELOCATION_H +#ifndef LLVM_CODEGEN_MACHORELOCATION_H +#define LLVM_CODEGEN_MACHORELOCATION_H #include "llvm/Support/DataTypes.h" @@ -53,4 +53,4 @@ namespace llvm { } // end llvm namespace -#endif // LLVM_CODEGEN_MACHO_RELOCATION_H +#endif // LLVM_CODEGEN_MACHORELOCATION_H diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h index 97c3945..492a3ff 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -14,8 +14,8 @@ #ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H #define LLVM_CODEGEN_MACHINEBASICBLOCK_H -#include "llvm/CodeGen/MachineInstr.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/Support/DataTypes.h" #include <functional> @@ -146,11 +146,11 @@ public: bundle_iterator(IterTy mii) : MII(mii) {} bundle_iterator(Ty &mi) : MII(mi) { - assert(!mi.isInsideBundle() && + assert(!mi.isBundledWithPred() && "It's not legal to initialize bundle_iterator with a bundled MI"); } bundle_iterator(Ty *mi) : MII(mi) { - assert((!mi || !mi->isInsideBundle()) && + assert((!mi || !mi->isBundledWithPred()) && "It's not legal to initialize bundle_iterator with a bundled MI"); } // Template allows conversion from const to nonconst. @@ -174,13 +174,13 @@ public: // Increment and decrement operators... bundle_iterator &operator--() { // predecrement - Back up do --MII; - while (MII->isInsideBundle()); + while (MII->isBundledWithPred()); return *this; } bundle_iterator &operator++() { // preincrement - Advance - IterTy E = MII->getParent()->instr_end(); - do ++MII; - while (MII != E && MII->isInsideBundle()); + while (MII->isBundledWithSucc()) + ++MII; + ++MII; return *this; } bundle_iterator operator--(int) { // postdecrement operators... @@ -441,80 +441,107 @@ public: void pop_back() { Insts.pop_back(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } - template<typename IT> - void insert(instr_iterator I, IT S, IT E) { - Insts.insert(I, S, E); - } - instr_iterator insert(instr_iterator I, MachineInstr *M) { - return Insts.insert(I, M); - } - instr_iterator insertAfter(instr_iterator I, MachineInstr *M) { - return Insts.insertAfter(I, M); - } + /// Insert MI into the instruction list before I, possibly inside a bundle. + /// + /// If the insertion point is inside a bundle, MI will be added to the bundle, + /// otherwise MI will not be added to any bundle. That means this function + /// alone can't be used to prepend or append instructions to bundles. See + /// MIBundleBuilder::insert() for a more reliable way of doing that. + instr_iterator insert(instr_iterator I, MachineInstr *M); + /// Insert a range of instructions into the instruction list before I. template<typename IT> void insert(iterator I, IT S, IT E) { Insts.insert(I.getInstrIterator(), S, E); } - iterator insert(iterator I, MachineInstr *M) { - return Insts.insert(I.getInstrIterator(), M); + + /// Insert MI into the instruction list before I. + iterator insert(iterator I, MachineInstr *MI) { + assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() && + "Cannot insert instruction with bundle flags"); + return Insts.insert(I.getInstrIterator(), MI); } - iterator insertAfter(iterator I, MachineInstr *M) { - return Insts.insertAfter(I.getInstrIterator(), M); + + /// Insert MI into the instruction list after I. + iterator insertAfter(iterator I, MachineInstr *MI) { + assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() && + "Cannot insert instruction with bundle flags"); + return Insts.insertAfter(I.getInstrIterator(), MI); } - /// erase - Remove the specified element or range from the instruction list. - /// These functions delete any instructions removed. + /// Remove an instruction from the instruction list and delete it. /// - instr_iterator erase(instr_iterator I) { - return Insts.erase(I); - } - instr_iterator erase(instr_iterator I, instr_iterator E) { - return Insts.erase(I, E); - } + /// If the instruction is part of a bundle, the other instructions in the + /// bundle will still be bundled after removing the single instruction. + instr_iterator erase(instr_iterator I); + + /// Remove an instruction from the instruction list and delete it. + /// + /// If the instruction is part of a bundle, the other instructions in the + /// bundle will still be bundled after removing the single instruction. instr_iterator erase_instr(MachineInstr *I) { - instr_iterator MII(I); - return erase(MII); + return erase(instr_iterator(I)); } - iterator erase(iterator I); + /// Remove a range of instructions from the instruction list and delete them. iterator erase(iterator I, iterator E) { return Insts.erase(I.getInstrIterator(), E.getInstrIterator()); } + + /// Remove an instruction or bundle from the instruction list and delete it. + /// + /// If I points to a bundle of instructions, they are all erased. + iterator erase(iterator I) { + return erase(I, llvm::next(I)); + } + + /// Remove an instruction from the instruction list and delete it. + /// + /// If I is the head of a bundle of instructions, the whole bundle will be + /// erased. iterator erase(MachineInstr *I) { - iterator MII(I); - return erase(MII); + return erase(iterator(I)); } - /// remove - Remove the instruction from the instruction list. This function - /// does not delete the instruction. WARNING: Note, if the specified - /// instruction is a bundle this function will remove all the bundled - /// instructions as well. It is up to the caller to keep a list of the - /// bundled instructions and re-insert them if desired. This function is - /// *not recommended* for manipulating instructions with bundles. Use - /// splice instead. - MachineInstr *remove(MachineInstr *I); + /// Remove the unbundled instruction from the instruction list without + /// deleting it. + /// + /// This function can not be used to remove bundled instructions, use + /// remove_instr to remove individual instructions from a bundle. + MachineInstr *remove(MachineInstr *I) { + assert(!I->isBundled() && "Cannot remove bundled instructions"); + return Insts.remove(I); + } + + /// Remove the possibly bundled instruction from the instruction list + /// without deleting it. + /// + /// If the instruction is part of a bundle, the other instructions in the + /// bundle will still be bundled after removing the single instruction. + MachineInstr *remove_instr(MachineInstr *I); + void clear() { Insts.clear(); } - /// splice - Take an instruction from MBB 'Other' at the position From, - /// and insert it into this MBB right before 'where'. - void splice(instr_iterator where, MachineBasicBlock *Other, - instr_iterator From) { - Insts.splice(where, Other->Insts, From); + /// Take an instruction from MBB 'Other' at the position From, and insert it + /// into this MBB right before 'Where'. + /// + /// If From points to a bundle of instructions, the whole bundle is moved. + void splice(iterator Where, MachineBasicBlock *Other, iterator From) { + // The range splice() doesn't allow noop moves, but this one does. + if (Where != From) + splice(Where, Other, From, llvm::next(From)); } - void splice(iterator where, MachineBasicBlock *Other, iterator From); - /// splice - Take a block of instructions from MBB 'Other' in the range [From, - /// To), and insert them into this MBB right before 'where'. - void splice(instr_iterator where, MachineBasicBlock *Other, instr_iterator From, - instr_iterator To) { - Insts.splice(where, Other->Insts, From, To); - } - void splice(iterator where, MachineBasicBlock *Other, iterator From, - iterator To) { - Insts.splice(where.getInstrIterator(), Other->Insts, + /// Take a block of instructions from MBB 'Other' in the range [From, To), + /// and insert them into this MBB right before 'Where'. + /// + /// The instruction at 'Where' must not be included in the range of + /// instructions to move. + void splice(iterator Where, MachineBasicBlock *Other, + iterator From, iterator To) { + Insts.splice(Where.getInstrIterator(), Other->Insts, From.getInstrIterator(), To.getInstrIterator()); } diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index 12189ce..98dd03b 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -1,4 +1,3 @@ - //==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==// // // The LLVM Compiler Infrastructure @@ -15,8 +14,8 @@ #ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H #define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H -#include "llvm/Pass.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" #include <climits> diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h b/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h index 86e8f27..9e41e6e 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h @@ -19,7 +19,6 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" - #include <string> namespace llvm { diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h index c5c0c44..ba9dfab 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EE_MACHINE_CODE_INFO_H -#define EE_MACHINE_CODE_INFO_H +#ifndef LLVM_CODEGEN_MACHINECODEINFO_H +#define LLVM_CODEGEN_MACHINECODEINFO_H #include "llvm/Support/DataTypes.h" diff --git a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h index 82a4ac8..e41d206 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h @@ -15,11 +15,11 @@ #ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H #define LLVM_CODEGEN_MACHINEDOMINATORS_H +#include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/Analysis/DominatorInternals.h" namespace llvm { @@ -41,15 +41,15 @@ class MachineDominatorTree : public MachineFunctionPass { public: static char ID; // Pass ID, replacement for typeid DominatorTreeBase<MachineBasicBlock>* DT; - + MachineDominatorTree(); - + ~MachineDominatorTree(); - + DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; } - + virtual void getAnalysisUsage(AnalysisUsage &AU) const; - + /// getRoots - Return the root blocks of the current CFG. This may include /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). @@ -57,33 +57,35 @@ public: inline const std::vector<MachineBasicBlock*> &getRoots() const { return DT->getRoots(); } - + inline MachineBasicBlock *getRoot() const { return DT->getRoot(); } - + inline MachineDomTreeNode *getRootNode() const { return DT->getRootNode(); } - + virtual bool runOnMachineFunction(MachineFunction &F); - - inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const { + + inline bool dominates(const MachineDomTreeNode* A, + const MachineDomTreeNode* B) const { return DT->dominates(A, B); } - - inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const { + + inline bool dominates(const MachineBasicBlock* A, + const MachineBasicBlock* B) const { return DT->dominates(A, B); } - + // dominates - Return true if A dominates B. This performs the // special checks necessary if A and B are in the same basic block. - bool dominates(MachineInstr *A, MachineInstr *B) const { - MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); + bool dominates(const MachineInstr *A, const MachineInstr *B) const { + const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); if (BBA != BBB) return DT->dominates(BBA, BBB); // Loop through the basic block until we find A or B. - MachineBasicBlock::iterator I = BBA->begin(); + MachineBasicBlock::const_iterator I = BBA->begin(); for (; &*I != A && &*I != B; ++I) /*empty*/ ; @@ -95,43 +97,43 @@ public: // return &*I == B; //} } - + inline bool properlyDominates(const MachineDomTreeNode* A, - MachineDomTreeNode* B) const { + const MachineDomTreeNode* B) const { return DT->properlyDominates(A, B); } - - inline bool properlyDominates(MachineBasicBlock* A, - MachineBasicBlock* B) const { + + inline bool properlyDominates(const MachineBasicBlock* A, + const MachineBasicBlock* B) const { return DT->properlyDominates(A, B); } - + /// findNearestCommonDominator - Find nearest common dominator basic block /// for basic block A and B. If there is no such block then return NULL. inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B) { return DT->findNearestCommonDominator(A, B); } - + inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { return DT->getNode(BB); } - + /// getNode - return the (Post)DominatorTree node for the specified basic /// block. This is the same as using operator[] on this class. /// inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { return DT->getNode(BB); } - + /// addNewBlock - Add a new node to the dominator tree information. This - /// creates a new node as a child of DomBB dominator node,linking it into + /// creates a new node as a child of DomBB dominator node,linking it into /// the children list of the immediate dominator. inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB) { return DT->addNewBlock(BB, DomBB); } - + /// changeImmediateDominator - This method is used to update the dominator /// tree information when a node's immediate dominator changes. /// @@ -139,19 +141,19 @@ public: MachineBasicBlock* NewIDom) { DT->changeImmediateDominator(N, NewIDom); } - + inline void changeImmediateDominator(MachineDomTreeNode *N, MachineDomTreeNode* NewIDom) { DT->changeImmediateDominator(N, NewIDom); } - + /// eraseNode - Removes a node from the dominator tree. Block must not /// dominate any other blocks. Removes node from its immediate dominator's /// children list. Deletes dominator node associated with basic block BB. inline void eraseNode(MachineBasicBlock *BB) { DT->eraseNode(BB); } - + /// splitBlock - BB is split and now it has one successor. Update dominator /// tree to reflect this change. inline void splitBlock(MachineBasicBlock* NewBB) { @@ -160,12 +162,12 @@ public: /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. - bool isReachableFromEntry(MachineBasicBlock *A) { + bool isReachableFromEntry(const MachineBasicBlock *A) { return DT->isReachableFromEntry(A); } virtual void releaseMemory(); - + virtual void print(raw_ostream &OS, const Module*) const; }; @@ -179,7 +181,7 @@ template<class T> struct GraphTraits; template <> struct GraphTraits<MachineDomTreeNode *> { typedef MachineDomTreeNode NodeType; typedef NodeType::iterator ChildIteratorType; - + static NodeType *getEntryNode(NodeType *N) { return N; } diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h index 0e4e132..cdec7e6 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -221,8 +221,11 @@ class MachineFrameInfo { /// just allocate them normally. bool UseLocalStackAllocationBlock; + /// Whether the "realign-stack" option is on. + bool RealignOption; public: - explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) { + explicit MachineFrameInfo(const TargetFrameLowering &tfi, bool RealignOpt) + : TFI(tfi), RealignOption(RealignOpt) { StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; HasVarSizedObjects = false; FrameAddressTaken = false; @@ -416,6 +419,9 @@ public: /// void setStackSize(uint64_t Size) { StackSize = Size; } + /// Estimate and return the size of the stack frame. + unsigned estimateStackSize(const MachineFunction &MF) const; + /// getOffsetAdjustment - Return the correction for frame offsets. /// int getOffsetAdjustment() const { return OffsetAdjustment; } @@ -432,9 +438,7 @@ public: /// ensureMaxAlignment - Make sure the function is at least Align bytes /// aligned. - void ensureMaxAlignment(unsigned Align) { - if (MaxAlignment < Align) MaxAlignment = Align; - } + void ensureMaxAlignment(unsigned Align); /// AdjustsStack - Return true if this function adjusts the stack -- e.g., /// when calling another function. This is only valid during and after @@ -496,26 +500,13 @@ public: /// a nonnegative identifier to represent it. /// int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, - bool MayNeedSP = false, const AllocaInst *Alloca = 0) { - assert(Size != 0 && "Cannot allocate zero size stack objects!"); - Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP, - Alloca)); - int Index = (int)Objects.size() - NumFixedObjects - 1; - assert(Index >= 0 && "Bad frame index!"); - ensureMaxAlignment(Alignment); - return Index; - } + bool MayNeedSP = false, const AllocaInst *Alloca = 0); /// CreateSpillStackObject - Create a new statically sized stack object that /// represents a spill slot, returning a nonnegative identifier to represent /// it. /// - int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { - CreateStackObject(Size, Alignment, true, false); - int Index = (int)Objects.size() - NumFixedObjects - 1; - ensureMaxAlignment(Alignment); - return Index; - } + int CreateSpillStackObject(uint64_t Size, unsigned Alignment); /// RemoveStackObject - Remove or mark dead a statically sized stack object. /// @@ -529,12 +520,7 @@ public: /// variable sized object is created, whether or not the index returned is /// actually used. /// - int CreateVariableSizedObject(unsigned Alignment) { - HasVarSizedObjects = true; - Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); - ensureMaxAlignment(Alignment); - return (int)Objects.size()-NumFixedObjects-1; - } + int CreateVariableSizedObject(unsigned Alignment); /// getCalleeSavedInfo - Returns a reference to call saved info vector for the /// current function. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h index 025e18a..82c4cd6 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h @@ -18,10 +18,11 @@ #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H #define LLVM_CODEGEN_MACHINEFUNCTION_H -#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/ADT/ilist.h" -#include "llvm/Support/DebugLoc.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/ArrayRecycler.h" +#include "llvm/Support/DebugLoc.h" #include "llvm/Support/Recycler.h" namespace llvm { @@ -105,6 +106,9 @@ class MachineFunction { // Allocation management for instructions in function. Recycler<MachineInstr> InstructionRecycler; + // Allocation management for operand arrays on instructions. + ArrayRecycler<MachineOperand> OperandRecycler; + // Allocation management for basic blocks in function. Recycler<MachineBasicBlock> BasicBlockRecycler; @@ -127,6 +131,9 @@ class MachineFunction { /// about the control flow of such functions. bool ExposesReturnsTwice; + /// True if the function includes MS-style inline assembly. + bool HasMSInlineAsm; + MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION; void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION; public: @@ -210,6 +217,17 @@ public: void setExposesReturnsTwice(bool B) { ExposesReturnsTwice = B; } + + /// Returns true if the function contains any MS-style inline assembly. + bool hasMSInlineAsm() const { + return HasMSInlineAsm; + } + + /// Set a flag that indicates that the function contains MS-style inline + /// assembly. + void setHasMSInlineAsm(bool B) { + HasMSInlineAsm = B; + } /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. @@ -394,6 +412,21 @@ public: MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, int64_t Offset, uint64_t Size); + typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity; + + /// Allocate an array of MachineOperands. This is only intended for use by + /// internal MachineInstr functions. + MachineOperand *allocateOperandArray(OperandCapacity Cap) { + return OperandRecycler.allocate(Cap, Allocator); + } + + /// Dellocate an array of MachineOperands and recycle the memory. This is + /// only intended for use by internal MachineInstr functions. + /// Cap must be the same capacity that was used to allocate the array. + void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) { + OperandRecycler.deallocate(Cap, Array); + } + /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand /// pointers. This array is owned by the MachineFunction. MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num); diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h index 50ea206..112f07e 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h @@ -11,15 +11,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H -#define LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H +#ifndef LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H +#define LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H #include "llvm/Pass.h" -#include "llvm/Target/TargetMachine.h" namespace llvm { class MachineFunction; +class TargetMachine; /// MachineFunctionAnalysis - This class is a Pass that manages a /// MachineFunction object. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h index b7bf0a3..04881e5 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h @@ -16,8 +16,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H -#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H +#ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H +#define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H #include "llvm/Pass.h" diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h index 7eb03a9..195cce7 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h @@ -16,17 +16,18 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/Target/TargetOpcodes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/ilist.h" -#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/DenseMapInfo.h" -#include "llvm/InlineAsm.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/Support/ArrayRecycler.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Target/TargetOpcodes.h" #include <vector> namespace llvm { @@ -42,6 +43,10 @@ class MachineMemOperand; //===----------------------------------------------------------------------===// /// MachineInstr - Representation of each machine instruction. /// +/// This class isn't a POD type, but it must have a trivial destructor. When a +/// MachineFunction is deleted, all the contained MachineInstrs are deallocated +/// without having their destructor called. +/// class MachineInstr : public ilist_node<MachineInstr> { public: typedef MachineMemOperand **mmo_iterator; @@ -58,11 +63,18 @@ public: NoFlags = 0, FrameSetup = 1 << 0, // Instruction is used as a part of // function frame setup code. - InsideBundle = 1 << 1 // Instruction is inside a bundle (not - // the first MI in a bundle) + BundledPred = 1 << 1, // Instruction has bundled predecessors. + BundledSucc = 1 << 2 // Instruction has bundled successors. }; private: const MCInstrDesc *MCID; // Instruction descriptor. + MachineBasicBlock *Parent; // Pointer to the owning basic block. + + // Operands are allocated by an ArrayRecycler. + MachineOperand *Operands; // Pointer to the first operand. + unsigned NumOperands; // Number of operands on instruction. + typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity; + OperandCapacity CapOperands; // Capacity of the Operands array. uint8_t Flags; // Various bits of additional // information about machine @@ -75,15 +87,15 @@ private: // anything other than to convey comment // information to AsmPrinter. - uint16_t NumMemRefs; // information on memory references + uint8_t NumMemRefs; // Information on memory references. mmo_iterator MemRefs; - std::vector<MachineOperand> Operands; // the operands - MachineBasicBlock *Parent; // Pointer to the owning basic block. DebugLoc debugLoc; // Source line information. MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION; void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION; + // Use MachineFunction::DeleteMachineInstr() instead. + ~MachineInstr() LLVM_DELETED_FUNCTION; // Intrusive list support friend struct ilist_traits<MachineInstr>; @@ -94,22 +106,11 @@ private: /// MachineInstr in the given MachineFunction. MachineInstr(MachineFunction &, const MachineInstr &); - /// MachineInstr ctor - This constructor creates a dummy MachineInstr with - /// MCID NULL and no operands. - MachineInstr(); - /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// MCInstrDesc. An explicit DebugLoc is supplied. - MachineInstr(const MCInstrDesc &MCID, 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, - const MCInstrDesc &MCID); - - ~MachineInstr(); + MachineInstr(MachineFunction&, const MCInstrDesc &MCID, + const DebugLoc dl, bool NoImp = false); // MachineInstrs are pool-allocated and owned by MachineFunction. friend class MachineFunction; @@ -160,7 +161,9 @@ public: } void setFlags(unsigned flags) { - Flags = flags; + // Filter out the automatically maintained flags. + unsigned Mask = BundledPred | BundledSucc; + Flags = (Flags & Mask) | (flags & ~Mask); } /// clearFlag - Clear a MI flag. @@ -205,21 +208,36 @@ public: /// The first instruction has the special opcode "BUNDLE". It's not "inside" /// a bundle, but the next three MIs are. bool isInsideBundle() const { - return getFlag(InsideBundle); - } - - /// setIsInsideBundle - Set InsideBundle bit. - /// - void setIsInsideBundle(bool Val = true) { - if (Val) - setFlag(InsideBundle); - else - clearFlag(InsideBundle); + return getFlag(BundledPred); } /// isBundled - Return true if this instruction part of a bundle. This is true /// if either itself or its following instruction is marked "InsideBundle". - bool isBundled() const; + bool isBundled() const { + return isBundledWithPred() || isBundledWithSucc(); + } + + /// Return true if this instruction is part of a bundle, and it is not the + /// first instruction in the bundle. + bool isBundledWithPred() const { return getFlag(BundledPred); } + + /// Return true if this instruction is part of a bundle, and it is not the + /// last instruction in the bundle. + bool isBundledWithSucc() const { return getFlag(BundledSucc); } + + /// Bundle this instruction with its predecessor. This can be an unbundled + /// instruction, or it can be the first instruction in a bundle. + void bundleWithPred(); + + /// Bundle this instruction with its successor. This can be an unbundled + /// instruction, or it can be the last instruction in a bundle. + void bundleWithSucc(); + + /// Break bundle above this instruction. + void unbundleFromPred(); + + /// Break bundle below this instruction. + void unbundleFromSucc(); /// getDebugLoc - Returns the debug location id of this MachineInstr. /// @@ -244,7 +262,7 @@ public: /// Access to explicit operands of the instruction. /// - unsigned getNumOperands() const { return (unsigned)Operands.size(); } + unsigned getNumOperands() const { return NumOperands; } const MachineOperand& getOperand(unsigned i) const { assert(i < getNumOperands() && "getOperand() out of range!"); @@ -260,14 +278,14 @@ public: unsigned getNumExplicitOperands() const; /// iterator/begin/end - Iterate over all operands of a machine instruction. - typedef std::vector<MachineOperand>::iterator mop_iterator; - typedef std::vector<MachineOperand>::const_iterator const_mop_iterator; + typedef MachineOperand *mop_iterator; + typedef const MachineOperand *const_mop_iterator; - mop_iterator operands_begin() { return Operands.begin(); } - mop_iterator operands_end() { return Operands.end(); } + mop_iterator operands_begin() { return Operands; } + mop_iterator operands_end() { return Operands + NumOperands; } - const_mop_iterator operands_begin() const { return Operands.begin(); } - const_mop_iterator operands_end() const { return Operands.end(); } + const_mop_iterator operands_begin() const { return Operands; } + const_mop_iterator operands_end() const { return Operands + NumOperands; } /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } @@ -295,11 +313,11 @@ public: /// The second argument indicates whether the query should look inside /// instruction bundles. bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const { - // Inline the fast path. - if (Type == IgnoreBundle || !isBundle()) + // Inline the fast path for unbundled or bundle-internal instructions. + if (Type == IgnoreBundle || !isBundled() || isBundledWithPred()) return getDesc().getFlags() & (1 << MCFlag); - // If we have a bundle, take the slow path. + // If this is the first instruction in a bundle, take the slow path. return hasPropertyInBundle(1 << MCFlag, Type); } @@ -578,14 +596,33 @@ public: bool isIdenticalTo(const MachineInstr *Other, MICheckType Check = CheckDefs) const; - /// removeFromParent - This method unlinks 'this' from the containing basic - /// block, and returns it, but does not delete it. + /// Unlink 'this' from the containing basic block, and return it without + /// deleting it. + /// + /// This function can not be used on bundled instructions, use + /// removeFromBundle() to remove individual instructions from a bundle. MachineInstr *removeFromParent(); - /// eraseFromParent - This method unlinks 'this' from the containing basic - /// block and deletes it. + /// Unlink this instruction from its basic block and return it without + /// deleting it. + /// + /// If the instruction is part of a bundle, the other instructions in the + /// bundle remain bundled. + MachineInstr *removeFromBundle(); + + /// Unlink 'this' from the containing basic block and delete it. + /// + /// If this instruction is the header of a bundle, the whole bundle is erased. + /// This function can not be used for instructions inside a bundle, use + /// eraseFromBundle() to erase individual bundled instructions. void eraseFromParent(); + /// Unlink 'this' form its basic block and delete it. + /// + /// If the instruction is part of a bundle, the other instructions in the + /// bundle remain bundled. + void eraseFromBundle(); + /// isLabel - Returns true if the MachineInstr represents a label. /// bool isLabel() const { @@ -605,6 +642,9 @@ public: bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } + bool isMSInlineAsm() const { + return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect(); + } bool isStackAligningInlineAsm() const; InlineAsm::AsmDialect getInlineAsmDialect() const; bool isInsertSubreg() const { @@ -662,7 +702,11 @@ public: } } - /// getBundleSize - Return the number of instructions inside the MI bundle. + /// Return the number of instructions inside the MI bundle, excluding the + /// bundle header. + /// + /// This is the number of instructions that MachineBasicBlock::iterator + /// skips, 0 for unbundled instructions. unsigned getBundleSize() const; /// readsRegister - Return true if the MachineInstr reads the specified @@ -821,13 +865,6 @@ public: /// void clearKillInfo(); - /// copyKillDeadInfo - Copies kill / dead operand properties from MI. - /// - void copyKillDeadInfo(const MachineInstr *MI); - - /// copyPredicates - Copies predicate operand(s) from MI. - void copyPredicates(const MachineInstr *MI); - /// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx, /// properly composing subreg indices where necessary. void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, @@ -909,21 +946,35 @@ public: /// copyImplicitOps - Copy implicit register operands from specified /// instruction to this instruction. - void copyImplicitOps(const MachineInstr *MI); + void copyImplicitOps(MachineFunction &MF, const MachineInstr *MI); // // Debugging support // - void print(raw_ostream &OS, const TargetMachine *TM = 0) const; + void print(raw_ostream &OS, const TargetMachine *TM = 0, + bool SkipOpers = false) const; void dump() const; //===--------------------------------------------------------------------===// // Accessors used to build up machine instructions. - /// 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 + /// 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). + /// + /// MF must be the machine function that was used to allocate this + /// instruction. + /// + /// MachineInstrBuilder provides a more convenient interface for creating + /// instructions and adding operands. + void addOperand(MachineFunction &MF, const MachineOperand &Op); + + /// Add an operand without providing an MF reference. This only works for + /// instructions that are inserted in a basic block. + /// + /// MachineInstrBuilder and the two-argument addOperand(MF, MO) should be + /// preferred. void addOperand(const MachineOperand &Op); /// setDesc - Replace the instruction descriptor (thus opcode) of @@ -950,7 +1001,8 @@ public: /// list. This does not transfer ownership. void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { MemRefs = NewMemRefs; - NumMemRefs = NewMemRefsEnd - NewMemRefs; + NumMemRefs = uint8_t(NewMemRefsEnd - NewMemRefs); + assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); } private: @@ -970,7 +1022,7 @@ private: /// addImplicitDefUseOperands - Add all implicit def and use operands to /// this instruction. - void addImplicitDefUseOperands(); + void addImplicitDefUseOperands(MachineFunction &MF); /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in /// this instruction from their respective use lists. This requires that the diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h index 7706853..92c8da9 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -18,6 +18,7 @@ #define LLVM_CODEGEN_MACHINEINSTRBUILDER_H #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -42,10 +43,14 @@ namespace RegState { } class MachineInstrBuilder { + MachineFunction *MF; MachineInstr *MI; public: - MachineInstrBuilder() : MI(0) {} - explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {} + MachineInstrBuilder() : MF(0), MI(0) {} + + /// Create a MachineInstrBuilder for manipulating an existing instruction. + /// F must be the machine function that was used to allocate I. + MachineInstrBuilder(MachineFunction &F, MachineInstr *I) : MF(&F), MI(I) {} /// Allow automatic conversion to the machine instruction we are working on. /// @@ -60,86 +65,94 @@ public: unsigned SubReg = 0) const { assert((flags & 0x1) == 0 && "Passing in 'true' to addReg is forbidden! Use enums instead."); - MI->addOperand(MachineOperand::CreateReg(RegNo, - flags & RegState::Define, - flags & RegState::Implicit, - flags & RegState::Kill, - flags & RegState::Dead, - flags & RegState::Undef, - flags & RegState::EarlyClobber, - SubReg, - flags & RegState::Debug, - flags & RegState::InternalRead)); + MI->addOperand(*MF, MachineOperand::CreateReg(RegNo, + flags & RegState::Define, + flags & RegState::Implicit, + flags & RegState::Kill, + flags & RegState::Dead, + flags & RegState::Undef, + flags & RegState::EarlyClobber, + SubReg, + flags & RegState::Debug, + flags & RegState::InternalRead)); return *this; } /// addImm - Add a new immediate operand. /// const MachineInstrBuilder &addImm(int64_t Val) const { - MI->addOperand(MachineOperand::CreateImm(Val)); + MI->addOperand(*MF, MachineOperand::CreateImm(Val)); return *this; } const MachineInstrBuilder &addCImm(const ConstantInt *Val) const { - MI->addOperand(MachineOperand::CreateCImm(Val)); + MI->addOperand(*MF, MachineOperand::CreateCImm(Val)); return *this; } const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const { - MI->addOperand(MachineOperand::CreateFPImm(Val)); + MI->addOperand(*MF, MachineOperand::CreateFPImm(Val)); return *this; } const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateMBB(MBB, TargetFlags)); return *this; } const MachineInstrBuilder &addFrameIndex(int Idx) const { - MI->addOperand(MachineOperand::CreateFI(Idx)); + MI->addOperand(*MF, MachineOperand::CreateFI(Idx)); return *this; } const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx, int Offset = 0, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateCPI(Idx, Offset, TargetFlags)); return *this; } const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateTargetIndex(Idx, Offset, + TargetFlags)); return *this; } const MachineInstrBuilder &addJumpTableIndex(unsigned Idx, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateJTI(Idx, TargetFlags)); return *this; } const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV, int64_t Offset = 0, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateGA(GV, Offset, TargetFlags)); return *this; } const MachineInstrBuilder &addExternalSymbol(const char *FnName, unsigned char TargetFlags = 0) const { - MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags)); + MI->addOperand(*MF, MachineOperand::CreateES(FnName, TargetFlags)); + return *this; + } + + const MachineInstrBuilder &addBlockAddress(const BlockAddress *BA, + int64_t Offset = 0, + unsigned char TargetFlags = 0) const { + MI->addOperand(*MF, MachineOperand::CreateBA(BA, Offset, TargetFlags)); return *this; } const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const { - MI->addOperand(MachineOperand::CreateRegMask(Mask)); + MI->addOperand(*MF, MachineOperand::CreateRegMask(Mask)); return *this; } const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const { - MI->addMemOperand(*MI->getParent()->getParent(), MMO); + MI->addMemOperand(*MF, MMO); return *this; } @@ -151,17 +164,17 @@ public: const MachineInstrBuilder &addOperand(const MachineOperand &MO) const { - MI->addOperand(MO); + MI->addOperand(*MF, MO); return *this; } const MachineInstrBuilder &addMetadata(const MDNode *MD) const { - MI->addOperand(MachineOperand::CreateMetadata(MD)); + MI->addOperand(*MF, MachineOperand::CreateMetadata(MD)); return *this; } const MachineInstrBuilder &addSym(MCSymbol *Sym) const { - MI->addOperand(MachineOperand::CreateMCSymbol(Sym)); + MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym)); return *this; } @@ -196,6 +209,12 @@ public: } } } + + /// Copy all the implicit operands from OtherMI onto this one. + const MachineInstrBuilder ©ImplicitOps(const MachineInstr *OtherMI) { + MI->copyImplicitOps(*MF, OtherMI); + return *this; + } }; /// BuildMI - Builder interface. Specify how to create the initial instruction @@ -204,7 +223,7 @@ public: inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID) { - return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)); + return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)); } /// BuildMI - This version of the builder sets up the first operand as a @@ -214,7 +233,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID, unsigned DestReg) { - return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL)) + return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)) .addReg(DestReg, RegState::Define); } @@ -227,9 +246,10 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, DebugLoc DL, const MCInstrDesc &MCID, unsigned DestReg) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); + MachineFunction &MF = *BB.getParent(); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); BB.insert(I, MI); - return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); + return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define); } inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, @@ -237,9 +257,10 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, DebugLoc DL, const MCInstrDesc &MCID, unsigned DestReg) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); + MachineFunction &MF = *BB.getParent(); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); BB.insert(I, MI); - return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define); + return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define); } inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, @@ -264,18 +285,20 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, const MCInstrDesc &MCID) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); + MachineFunction &MF = *BB.getParent(); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); BB.insert(I, MI); - return MachineInstrBuilder(MI); + return MachineInstrBuilder(MF, MI); } inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::instr_iterator I, DebugLoc DL, const MCInstrDesc &MCID) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL); + MachineFunction &MF = *BB.getParent(); + MachineInstr *MI = MF.CreateMachineInstr(MCID, DL); BB.insert(I, MI); - return MachineInstrBuilder(MI); + return MachineInstrBuilder(MF, MI); } inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, @@ -330,6 +353,94 @@ inline unsigned getUndefRegState(bool B) { inline unsigned getInternalReadRegState(bool B) { return B ? RegState::InternalRead : 0; } +inline unsigned getDebugRegState(bool B) { + return B ? RegState::Debug : 0; +} + + +/// Helper class for constructing bundles of MachineInstrs. +/// +/// MIBundleBuilder can create a bundle from scratch by inserting new +/// MachineInstrs one at a time, or it can create a bundle from a sequence of +/// existing MachineInstrs in a basic block. +class MIBundleBuilder { + MachineBasicBlock &MBB; + MachineBasicBlock::instr_iterator Begin; + MachineBasicBlock::instr_iterator End; + +public: + /// Create an MIBundleBuilder that inserts instructions into a new bundle in + /// BB above the bundle or instruction at Pos. + MIBundleBuilder(MachineBasicBlock &BB, + MachineBasicBlock::iterator Pos) + : MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {} + + /// Create a bundle from the sequence of instructions between B and E. + MIBundleBuilder(MachineBasicBlock &BB, + MachineBasicBlock::iterator B, + MachineBasicBlock::iterator E) + : MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) { + assert(B != E && "No instructions to bundle"); + ++B; + while (B != E) { + MachineInstr *MI = B; + ++B; + MI->bundleWithPred(); + } + } + + /// Create an MIBundleBuilder representing an existing instruction or bundle + /// that has MI as its head. + explicit MIBundleBuilder(MachineInstr *MI) + : MBB(*MI->getParent()), Begin(MI), End(getBundleEnd(MI)) {} + + /// Return a reference to the basic block containing this bundle. + MachineBasicBlock &getMBB() const { return MBB; } + + /// Return true if no instructions have been inserted in this bundle yet. + /// Empty bundles aren't representable in a MachineBasicBlock. + bool empty() const { return Begin == End; } + + /// Return an iterator to the first bundled instruction. + MachineBasicBlock::instr_iterator begin() const { return Begin; } + + /// Return an iterator beyond the last bundled instruction. + MachineBasicBlock::instr_iterator end() const { return End; } + + /// Insert MI into this bundle before I which must point to an instruction in + /// the bundle, or end(). + MIBundleBuilder &insert(MachineBasicBlock::instr_iterator I, + MachineInstr *MI) { + MBB.insert(I, MI); + if (I == Begin) { + if (!empty()) + MI->bundleWithSucc(); + Begin = MI; + return *this; + } + if (I == End) { + MI->bundleWithPred(); + return *this; + } + // MI was inserted in the middle of the bundle, so its neighbors' flags are + // already fine. Update MI's bundle flags manually. + MI->setFlag(MachineInstr::BundledPred); + MI->setFlag(MachineInstr::BundledSucc); + return *this; + } + + /// Insert MI into MBB by prepending it to the instructions in the bundle. + /// MI will become the first instruction in the bundle. + MIBundleBuilder &prepend(MachineInstr *MI) { + return insert(begin(), MI); + } + + /// Insert MI into MBB by appending it to the instructions in the bundle. + /// MI will become the last instruction in the bundle. + MIBundleBuilder &append(MachineInstr *MI) { + return insert(end(), MI); + } +}; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h index 854ba06..9519edb 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h @@ -45,18 +45,36 @@ bool finalizeBundles(MachineFunction &MF); /// inline MachineInstr *getBundleStart(MachineInstr *MI) { MachineBasicBlock::instr_iterator I = MI; - while (I->isInsideBundle()) + while (I->isBundledWithPred()) --I; return I; } inline const MachineInstr *getBundleStart(const MachineInstr *MI) { MachineBasicBlock::const_instr_iterator I = MI; - while (I->isInsideBundle()) + while (I->isBundledWithPred()) --I; return I; } +/// Return an iterator pointing beyond the bundle containing MI. +inline MachineBasicBlock::instr_iterator +getBundleEnd(MachineInstr *MI) { + MachineBasicBlock::instr_iterator I = MI; + while (I->isBundledWithSucc()) + ++I; + return ++I; +} + +/// Return an iterator pointing beyond the bundle containing MI. +inline MachineBasicBlock::const_instr_iterator +getBundleEnd(const MachineInstr *MI) { + MachineBasicBlock::const_instr_iterator I = MI; + while (I->isBundledWithSucc()) + ++I; + return ++I; +} + //===----------------------------------------------------------------------===// // MachineOperand iterator // @@ -149,16 +167,13 @@ public: /// PhysRegInfo - Information about a physical register used by a set of /// operands. struct PhysRegInfo { - /// Clobbers - Reg or an overlapping register is defined, or a regmask + /// Clobbers - Reg or an overlapping register is defined, or a regmask /// clobbers Reg. bool Clobbers; /// Defines - Reg or a super-register is defined. bool Defines; - /// DefinesOverlap - Reg or an overlapping register is defined. - bool DefinesOverlap; - /// Reads - Read or a super-register is read. bool Reads; diff --git a/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h index 928145d..adcd1d0 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -20,8 +20,8 @@ #ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H #define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H -#include <vector> #include <cassert> +#include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h index d53f041..b058ecb 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h @@ -27,11 +27,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H -#define LLVM_CODEGEN_MACHINE_LOOP_INFO_H +#ifndef LLVM_CODEGEN_MACHINELOOPINFO_H +#define LLVM_CODEGEN_MACHINELOOPINFO_H -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h deleted file mode 100644 index 6a30e8b..0000000 --- a/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h +++ /dev/null @@ -1,112 +0,0 @@ -//===- MachineLoopRanges.h - Ranges of machine loops -----------*- c++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the interface to the MachineLoopRanges analysis. -// -// Provide on-demand information about the ranges of machine instructions -// covered by a loop. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_MACHINELOOPRANGES_H -#define LLVM_CODEGEN_MACHINELOOPRANGES_H - -#include "llvm/ADT/IntervalMap.h" -#include "llvm/CodeGen/SlotIndexes.h" - -namespace llvm { - -class MachineLoop; -class MachineLoopInfo; -class raw_ostream; - -/// MachineLoopRange - Range information for a single loop. -class MachineLoopRange { - friend class MachineLoopRanges; - -public: - typedef IntervalMap<SlotIndex, unsigned, 4> Map; - typedef Map::Allocator Allocator; - -private: - /// The mapped loop. - const MachineLoop *const Loop; - - /// Map intervals to a bit mask. - /// Bit 0 = inside loop block. - Map Intervals; - - /// Loop area as measured by SlotIndex::distance. - unsigned Area; - - /// Create a MachineLoopRange, only accessible to MachineLoopRanges. - MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&); - -public: - /// getLoop - Return the mapped machine loop. - const MachineLoop *getLoop() const { return Loop; } - - /// overlaps - Return true if this loop overlaps the given range of machine - /// inteructions. - bool overlaps(SlotIndex Start, SlotIndex Stop); - - /// getNumber - Return the loop number. This is the same as the number of the - /// header block. - unsigned getNumber() const; - - /// getArea - Return the loop area. This number is approximately proportional - /// to the number of instructions in the loop. - unsigned getArea() const { return Area; } - - /// getMap - Allow public read-only access for IntervalMapOverlaps. - const Map &getMap() { return Intervals; } - - /// print - Print loop ranges on OS. - void print(raw_ostream&) const; - - /// byNumber - Comparator for array_pod_sort that sorts a list of - /// MachineLoopRange pointers by number. - static int byNumber(const void*, const void*); - - /// byAreaDesc - Comparator for array_pod_sort that sorts a list of - /// MachineLoopRange pointers by descending area, then by number. - static int byAreaDesc(const void*, const void*); -}; - -raw_ostream &operator<<(raw_ostream&, const MachineLoopRange&); - -/// MachineLoopRanges - Analysis pass that provides on-demand per-loop range -/// information. -class MachineLoopRanges : public MachineFunctionPass { - typedef DenseMap<const MachineLoop*, MachineLoopRange*> CacheMap; - typedef MachineLoopRange::Allocator MapAllocator; - - MapAllocator Allocator; - SlotIndexes *Indexes; - CacheMap Cache; - -public: - static char ID; // Pass identification, replacement for typeid - - MachineLoopRanges() : MachineFunctionPass(ID), Indexes(0) {} - ~MachineLoopRanges() { releaseMemory(); } - - /// getLoopRange - Return the range of loop. - MachineLoopRange *getLoopRange(const MachineLoop *Loop); - -private: - virtual bool runOnMachineFunction(MachineFunction&); - virtual void releaseMemory(); - virtual void getAnalysisUsage(AnalysisUsage&) const; -}; - - -} // end namespace llvm - -#endif // LLVM_CODEGEN_MACHINELOOPRANGES_H diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h index 6b88d4a..a3acec8 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -31,19 +31,18 @@ #ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H #define LLVM_CODEGEN_MACHINEMODULEINFO_H -#include "llvm/Pass.h" -#include "llvm/GlobalValue.h" -#include "llvm/Metadata.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/DebugLoc.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Metadata.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MachineLocation.h" +#include "llvm/Pass.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/DebugLoc.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { @@ -180,8 +179,9 @@ public: const MCObjectFileInfo *MOFI); ~MachineModuleInfo(); - bool doInitialization(); - bool doFinalization(); + // Initialization and Finalization + virtual bool doInitialization(Module &); + virtual bool doFinalization(Module &); /// EndFunction - Discard function meta information. /// @@ -295,7 +295,7 @@ public: /// isUsedFunction - Return true if the functions in the llvm.used list. This /// does not return true for things in llvm.compiler.used unless they are also /// in llvm.used. - bool isUsedFunction(const Function *F) { + bool isUsedFunction(const Function *F) const { return UsedFunctions.count(F); } @@ -372,7 +372,7 @@ public: /// getCurrentCallSite - Get the call site currently being processed, if any. /// return zero if none. - unsigned getCurrentCallSite(void) { return CurCallSite; } + unsigned getCurrentCallSite() { return CurCallSite; } /// getTypeInfos - Return a reference to the C++ typeinfo for the current /// function. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h index 606833c..414770b 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineOperand.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h @@ -35,6 +35,11 @@ class MCSymbol; /// MachineOperand class - Representation of each machine instruction operand. /// +/// This class isn't a POD type because it has a private constructor, but its +/// destructor must be trivial. Functions like MachineInstr::addOperand(), +/// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depend on +/// not having to call the MachineOperand destructor. +/// class MachineOperand { public: enum MachineOperandType { @@ -60,15 +65,11 @@ private: /// union. unsigned char OpKind; // MachineOperandType - // This union is discriminated by OpKind. - union { - /// SubReg - Subregister number, only valid for MO_Register. A value of 0 - /// indicates the MO_Register has no subReg. - unsigned char SubReg; - - /// TargetFlags - This is a set of target-specific operand flags. - unsigned char TargetFlags; - }; + /// Subregister number for MO_Register. A value of 0 indicates the + /// MO_Register has no subReg. + /// + /// For all other kinds of operands, this field holds target-specific flags. + unsigned SubReg_TargetFlags : 12; /// TiedTo - Non-zero when this register operand is tied to another register /// operand. The encoding of this field is described in the block comment @@ -176,24 +177,25 @@ private: } OffsetedInfo; } Contents; - explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) { - TargetFlags = 0; - } + explicit MachineOperand(MachineOperandType K) + : OpKind(K), SubReg_TargetFlags(0), ParentMI(0) {} public: /// getType - Returns the MachineOperandType for this operand. /// MachineOperandType getType() const { return (MachineOperandType)OpKind; } - unsigned char getTargetFlags() const { - return isReg() ? 0 : TargetFlags; + unsigned getTargetFlags() const { + return isReg() ? 0 : SubReg_TargetFlags; } - void setTargetFlags(unsigned char F) { + void setTargetFlags(unsigned F) { assert(!isReg() && "Register operands can't have target flags"); - TargetFlags = F; + SubReg_TargetFlags = F; + assert(SubReg_TargetFlags == F && "Target flags out of range"); } - void addTargetFlag(unsigned char F) { + void addTargetFlag(unsigned F) { assert(!isReg() && "Register operands can't have target flags"); - TargetFlags |= F; + SubReg_TargetFlags |= F; + assert((SubReg_TargetFlags & F) && "Target flags out of range"); } @@ -261,7 +263,7 @@ public: unsigned getSubReg() const { assert(isReg() && "Wrong MachineOperand accessor"); - return (unsigned)SubReg; + return SubReg_TargetFlags; } bool isUse() const { @@ -336,7 +338,8 @@ public: void setSubReg(unsigned subReg) { assert(isReg() && "Wrong MachineOperand accessor"); - SubReg = (unsigned char)subReg; + SubReg_TargetFlags = subReg; + assert(SubReg_TargetFlags == subReg && "SubReg out of range"); } /// substVirtReg - Substitute the current register with the virtual @@ -574,7 +577,7 @@ public: Op.SmallContents.RegNo = Reg; Op.Contents.Reg.Prev = 0; Op.Contents.Reg.Next = 0; - Op.SubReg = SubReg; + Op.setSubReg(SubReg); return Op; } static MachineOperand CreateMBB(MachineBasicBlock *MBB, diff --git a/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h b/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h index a9fc843..ca09aef 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h +++ b/contrib/llvm/include/llvm/CodeGen/MachinePostDominators.h @@ -15,10 +15,9 @@ #ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H #define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineDominators.h" #include "llvm/Analysis/Dominators.h" -#include "llvm/Analysis/DominatorInternals.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" namespace llvm { @@ -55,26 +54,27 @@ public: return DT->getNode(BB); } - bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const { + bool dominates(const MachineDomTreeNode *A, + const MachineDomTreeNode *B) const { return DT->dominates(A, B); } - bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const { + bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) const { return DT->dominates(A, B); } - bool - properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) const { + bool properlyDominates(const MachineDomTreeNode *A, + const MachineDomTreeNode *B) const { return DT->properlyDominates(A, B); } - bool - properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const { + bool properlyDominates(const MachineBasicBlock *A, + const MachineBasicBlock *B) const { return DT->properlyDominates(A, B); } MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, - MachineBasicBlock *B) { + MachineBasicBlock *B) { return DT->findNearestCommonDominator(A, B); } diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index 4e86363..4b43cc1 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -14,10 +14,10 @@ #ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H #define LLVM_CODEGEN_MACHINEREGISTERINFO_H -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/MachineInstrBundle.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <vector> namespace llvm { @@ -99,13 +99,11 @@ class MachineRegisterInfo { /// started. BitVector ReservedRegs; - /// LiveIns/LiveOuts - Keep track of the physical registers that are - /// livein/liveout of the function. Live in values are typically arguments in - /// registers, live out values are typically return values in registers. - /// LiveIn values are allowed to have virtual registers associated with them, - /// stored in the second element. + /// Keep track of the physical registers that are live in to the function. + /// Live in values are typically arguments in registers. LiveIn values are + /// allowed to have virtual registers associated with them, stored in the + /// second element. std::vector<std::pair<unsigned, unsigned> > LiveIns; - std::vector<unsigned> LiveOuts; MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION; @@ -156,6 +154,9 @@ public: // Strictly for use by MachineInstr.cpp. void removeRegOperandFromUseList(MachineOperand *MO); + // Strictly for use by MachineInstr.cpp. + void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps); + /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. @@ -376,6 +377,12 @@ public: return false; } + /// Mark the specified register unit as used in this function. + /// This should only be called during and after register allocation. + void setRegUnitUsed(unsigned RegUnit) { + UsedRegUnits.set(RegUnit); + } + /// setPhysRegUsed - Mark the specified register used in this function. /// This should only be called during and after register allocation. void setPhysRegUsed(unsigned Reg) { @@ -457,30 +464,24 @@ public: } //===--------------------------------------------------------------------===// - // LiveIn/LiveOut Management + // LiveIn Management //===--------------------------------------------------------------------===// - /// addLiveIn/Out - Add the specified register as a live in/out. Note that it + /// addLiveIn - Add the specified register as a live-in. Note that it /// is an error to add the same register to the same set more than once. void addLiveIn(unsigned Reg, unsigned vreg = 0) { LiveIns.push_back(std::make_pair(Reg, vreg)); } - void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); } - // Iteration support for live in/out sets. These sets are kept in sorted - // order by their register number. + // Iteration support for the live-ins set. It's kept in sorted order + // by register number. typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator livein_iterator; - typedef std::vector<unsigned>::const_iterator liveout_iterator; livein_iterator livein_begin() const { return LiveIns.begin(); } livein_iterator livein_end() const { return LiveIns.end(); } bool livein_empty() const { return LiveIns.empty(); } - liveout_iterator liveout_begin() const { return LiveOuts.begin(); } - liveout_iterator liveout_end() const { return LiveOuts.end(); } - bool liveout_empty() const { return LiveOuts.empty(); } bool isLiveIn(unsigned Reg) const; - bool isLiveOut(unsigned Reg) const; /// getLiveInPhysReg - If VReg is a live-in virtual register, return the /// corresponding live-in physical register. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h index 31bd606..57febe7 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h @@ -24,8 +24,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MACHINESCHEDULER_H -#define MACHINESCHEDULER_H +#ifndef LLVM_CODEGEN_MACHINESCHEDULER_H +#define LLVM_CODEGEN_MACHINESCHEDULER_H #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/RegisterPressure.h" @@ -43,6 +43,7 @@ class MachineDominatorTree; class MachineLoopInfo; class RegisterClassInfo; class ScheduleDAGInstrs; +class SchedDFSResult; /// MachineSchedContext provides enough context from the MachineScheduler pass /// for the target to instantiate a scheduler. @@ -119,6 +120,9 @@ public: /// be scheduled at the bottom. virtual SUnit *pickNode(bool &IsTopNode) = 0; + /// \brief Scheduler callback to notify that a new subtree is scheduled. + virtual void scheduleTree(unsigned SubtreeID) {} + /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an /// instruction and updated scheduled/remaining flags in the DAG nodes. virtual void schedNode(SUnit *SU, bool IsTopNode) = 0; @@ -164,6 +168,8 @@ public: iterator end() { return Queue.end(); } + ArrayRef<SUnit*> elements() { return Queue; } + iterator find(SUnit *SU) { return std::find(Queue.begin(), Queue.end(), SU); } @@ -181,7 +187,7 @@ public: return Queue.begin() + idx; } -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void dump(); #endif }; @@ -202,6 +208,15 @@ protected: RegisterClassInfo *RegClassInfo; MachineSchedStrategy *SchedImpl; + /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees + /// will be empty. + SchedDFSResult *DFSResult; + BitVector ScheduledTrees; + + /// Topo - A topological ordering for SUnits which permits fast IsReachable + /// and similar queries. + ScheduleDAGTopologicalSort Topo; + /// Ordered list of DAG postprocessing steps. std::vector<ScheduleDAGMutation*> Mutations; @@ -226,6 +241,10 @@ protected: IntervalPressure BotPressure; RegPressureTracker BotRPTracker; + /// Record the next node in a scheduled cluster. + const SUnit *NextClusterPred; + const SUnit *NextClusterSucc; + #ifndef NDEBUG /// The number of instructions scheduled so far. Used to cut off the /// scheduler at the point determined by misched-cutoff. @@ -235,25 +254,33 @@ protected: public: ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S): ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS), - AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), - RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure), - CurrentBottom(), BotRPTracker(BotPressure) { + AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0), + Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(), + TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure), + NextClusterPred(NULL), NextClusterSucc(NULL) { #ifndef NDEBUG NumInstrsScheduled = 0; #endif } - virtual ~ScheduleDAGMI() { - delete SchedImpl; - } + virtual ~ScheduleDAGMI(); /// Add a postprocessing step to the DAG builder. /// Mutations are applied in the order that they are added after normal DAG /// building and before MachineSchedStrategy initialization. + /// + /// ScheduleDAGMI takes ownership of the Mutation object. void addMutation(ScheduleDAGMutation *Mutation) { Mutations.push_back(Mutation); } + /// \brief Add a DAG edge to the given SU with the given predecessor + /// dependence data. + /// + /// \returns true if the edge may be added without creating a cycle OR if an + /// equivalent edge already existed (false indicates failure). + bool addEdge(SUnit *SuccSU, const SDep &PredDep); + MachineBasicBlock::iterator top() const { return CurrentTop; } MachineBasicBlock::iterator bottom() const { return CurrentBottom; } @@ -285,6 +312,22 @@ public: return RegionCriticalPSets; } + const SUnit *getNextClusterPred() const { return NextClusterPred; } + + const SUnit *getNextClusterSucc() const { return NextClusterSucc; } + + /// Compute a DFSResult after DAG building is complete, and before any + /// queue comparisons. + void computeDFSResult(); + + /// Return a non-null DFS result if the scheduling strategy initialized it. + const SchedDFSResult *getDFSResult() const { return DFSResult; } + + BitVector &getScheduledTrees() { return ScheduledTrees; } + + void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE; + void viewGraph() LLVM_OVERRIDE; + protected: // Top-Level entry points for the schedule() driver... @@ -298,8 +341,8 @@ protected: /// instances of ScheduleDAGMI to perform custom DAG postprocessing. void postprocessDAG(); - /// Identify DAG roots and setup scheduler queues. - void initQueues(); + /// Release ExitSU predecessors and setup scheduler queues. + void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots); /// Move an instruction and update register pressure. void scheduleMI(SUnit *SU, bool IsTopNode); @@ -317,12 +360,13 @@ protected: void initRegPressure(); - void updateScheduledPressure(std::vector<unsigned> NewMaxPressure); + void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure); void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); bool checkSchedLimit(); - void releaseRoots(); + void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots, + SmallVectorImpl<SUnit*> &BotRoots); void releaseSucc(SUnit *SU, SDep *SuccEdge); void releaseSuccessors(SUnit *SU); diff --git a/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h b/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h new file mode 100644 index 0000000..2775a04 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/MachineTraceMetrics.h @@ -0,0 +1,388 @@ +//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for the MachineTraceMetrics analysis pass +// that estimates CPU resource usage and critical data dependency paths through +// preferred traces. This is useful for super-scalar CPUs where execution speed +// can be limited both by data dependencies and by limited execution resources. +// +// Out-of-order CPUs will often be executing instructions from multiple basic +// blocks at the same time. This makes it difficult to estimate the resource +// usage accurately in a single basic block. Resources can be estimated better +// by looking at a trace through the current basic block. +// +// For every block, the MachineTraceMetrics pass will pick a preferred trace +// that passes through the block. The trace is chosen based on loop structure, +// branch probabilities, and resource usage. The intention is to pick likely +// traces that would be the most affected by code transformations. +// +// It is expensive to compute a full arbitrary trace for every block, so to +// save some computations, traces are chosen to be convergent. This means that +// if the traces through basic blocks A and B ever cross when moving away from +// A and B, they never diverge again. This applies in both directions - If the +// traces meet above A and B, they won't diverge when going further back. +// +// Traces tend to align with loops. The trace through a block in an inner loop +// will begin at the loop entry block and end at a back edge. If there are +// nested loops, the trace may begin and end at those instead. +// +// For each trace, we compute the critical path length, which is the number of +// cycles required to execute the trace when execution is limited by data +// dependencies only. We also compute the resource height, which is the number +// of cycles required to execute all instructions in the trace when ignoring +// data dependencies. +// +// Every instruction in the current block has a slack - the number of cycles +// execution of the instruction can be delayed without extending the critical +// path. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINE_TRACE_METRICS_H +#define LLVM_CODEGEN_MACHINE_TRACE_METRICS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/TargetSchedule.h" + +namespace llvm { + +class InstrItineraryData; +class MachineBasicBlock; +class MachineInstr; +class MachineLoop; +class MachineLoopInfo; +class MachineRegisterInfo; +class TargetInstrInfo; +class TargetRegisterInfo; +class raw_ostream; + +class MachineTraceMetrics : public MachineFunctionPass { + const MachineFunction *MF; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + const MachineRegisterInfo *MRI; + const MachineLoopInfo *Loops; + TargetSchedModel SchedModel; + +public: + class Ensemble; + class Trace; + static char ID; + MachineTraceMetrics(); + void getAnalysisUsage(AnalysisUsage&) const; + bool runOnMachineFunction(MachineFunction&); + void releaseMemory(); + void verifyAnalysis() const; + + friend class Ensemble; + friend class Trace; + + /// Per-basic block information that doesn't depend on the trace through the + /// block. + struct FixedBlockInfo { + /// The number of non-trivial instructions in the block. + /// Doesn't count PHI and COPY instructions that are likely to be removed. + unsigned InstrCount; + + /// True when the block contains calls. + bool HasCalls; + + FixedBlockInfo() : InstrCount(~0u), HasCalls(false) {} + + /// Returns true when resource information for this block has been computed. + bool hasResources() const { return InstrCount != ~0u; } + + /// Invalidate resource information. + void invalidate() { InstrCount = ~0u; } + }; + + /// Get the fixed resource information about MBB. Compute it on demand. + const FixedBlockInfo *getResources(const MachineBasicBlock*); + + /// Get the scaled number of cycles used per processor resource in MBB. + /// This is an array with SchedModel.getNumProcResourceKinds() entries. + /// The getResources() function above must have been called first. + /// + /// These numbers have already been scaled by SchedModel.getResourceFactor(). + ArrayRef<unsigned> getProcResourceCycles(unsigned MBBNum) const; + + /// A virtual register or regunit required by a basic block or its trace + /// successors. + struct LiveInReg { + /// The virtual register required, or a register unit. + unsigned Reg; + + /// For virtual registers: Minimum height of the defining instruction. + /// For regunits: Height of the highest user in the trace. + unsigned Height; + + LiveInReg(unsigned Reg, unsigned Height = 0) : Reg(Reg), Height(Height) {} + }; + + /// Per-basic block information that relates to a specific trace through the + /// block. Convergent traces means that only one of these is required per + /// block in a trace ensemble. + struct TraceBlockInfo { + /// Trace predecessor, or NULL for the first block in the trace. + /// Valid when hasValidDepth(). + const MachineBasicBlock *Pred; + + /// Trace successor, or NULL for the last block in the trace. + /// Valid when hasValidHeight(). + const MachineBasicBlock *Succ; + + /// The block number of the head of the trace. (When hasValidDepth()). + unsigned Head; + + /// The block number of the tail of the trace. (When hasValidHeight()). + unsigned Tail; + + /// Accumulated number of instructions in the trace above this block. + /// Does not include instructions in this block. + unsigned InstrDepth; + + /// Accumulated number of instructions in the trace below this block. + /// Includes instructions in this block. + unsigned InstrHeight; + + TraceBlockInfo() : + Pred(0), Succ(0), + InstrDepth(~0u), InstrHeight(~0u), + HasValidInstrDepths(false), HasValidInstrHeights(false) {} + + /// Returns true if the depth resources have been computed from the trace + /// above this block. + bool hasValidDepth() const { return InstrDepth != ~0u; } + + /// Returns true if the height resources have been computed from the trace + /// below this block. + bool hasValidHeight() const { return InstrHeight != ~0u; } + + /// Invalidate depth resources when some block above this one has changed. + void invalidateDepth() { InstrDepth = ~0u; HasValidInstrDepths = false; } + + /// Invalidate height resources when a block below this one has changed. + void invalidateHeight() { InstrHeight = ~0u; HasValidInstrHeights = false; } + + /// Assuming that this is a dominator of TBI, determine if it contains + /// useful instruction depths. A dominating block can be above the current + /// trace head, and any dependencies from such a far away dominator are not + /// expected to affect the critical path. + /// + /// Also returns true when TBI == this. + bool isUsefulDominator(const TraceBlockInfo &TBI) const { + // The trace for TBI may not even be calculated yet. + if (!hasValidDepth() || !TBI.hasValidDepth()) + return false; + // Instruction depths are only comparable if the traces share a head. + if (Head != TBI.Head) + return false; + // It is almost always the case that TBI belongs to the same trace as + // this block, but rare convoluted cases involving irreducible control + // flow, a dominator may share a trace head without actually being on the + // same trace as TBI. This is not a big problem as long as it doesn't + // increase the instruction depth. + return HasValidInstrDepths && InstrDepth <= TBI.InstrDepth; + } + + // Data-dependency-related information. Per-instruction depth and height + // are computed from data dependencies in the current trace, using + // itinerary data. + + /// Instruction depths have been computed. This implies hasValidDepth(). + bool HasValidInstrDepths; + + /// Instruction heights have been computed. This implies hasValidHeight(). + bool HasValidInstrHeights; + + /// Critical path length. This is the number of cycles in the longest data + /// dependency chain through the trace. This is only valid when both + /// HasValidInstrDepths and HasValidInstrHeights are set. + unsigned CriticalPath; + + /// Live-in registers. These registers are defined above the current block + /// and used by this block or a block below it. + /// This does not include PHI uses in the current block, but it does + /// include PHI uses in deeper blocks. + SmallVector<LiveInReg, 4> LiveIns; + + void print(raw_ostream&) const; + }; + + /// InstrCycles represents the cycle height and depth of an instruction in a + /// trace. + struct InstrCycles { + /// Earliest issue cycle as determined by data dependencies and instruction + /// latencies from the beginning of the trace. Data dependencies from + /// before the trace are not included. + unsigned Depth; + + /// Minimum number of cycles from this instruction is issued to the of the + /// trace, as determined by data dependencies and instruction latencies. + unsigned Height; + }; + + /// A trace represents a plausible sequence of executed basic blocks that + /// passes through the current basic block one. The Trace class serves as a + /// handle to internal cached data structures. + class Trace { + Ensemble &TE; + TraceBlockInfo &TBI; + + unsigned getBlockNum() const { return &TBI - &TE.BlockInfo[0]; } + + public: + explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {} + void print(raw_ostream&) const; + + /// Compute the total number of instructions in the trace. + unsigned getInstrCount() const { + return TBI.InstrDepth + TBI.InstrHeight; + } + + /// Return the resource depth of the top/bottom of the trace center block. + /// This is the number of cycles required to execute all instructions from + /// the trace head to the trace center block. The resource depth only + /// considers execution resources, it ignores data dependencies. + /// When Bottom is set, instructions in the trace center block are included. + unsigned getResourceDepth(bool Bottom) const; + + /// Return the resource length of the trace. This is the number of cycles + /// required to execute the instructions in the trace if they were all + /// independent, exposing the maximum instruction-level parallelism. + /// + /// Any blocks in Extrablocks are included as if they were part of the + /// trace. + unsigned getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks = + ArrayRef<const MachineBasicBlock*>()) const; + + /// Return the length of the (data dependency) critical path through the + /// trace. + unsigned getCriticalPath() const { return TBI.CriticalPath; } + + /// Return the depth and height of MI. The depth is only valid for + /// instructions in or above the trace center block. The height is only + /// valid for instructions in or below the trace center block. + InstrCycles getInstrCycles(const MachineInstr *MI) const { + return TE.Cycles.lookup(MI); + } + + /// Return the slack of MI. This is the number of cycles MI can be delayed + /// before the critical path becomes longer. + /// MI must be an instruction in the trace center block. + unsigned getInstrSlack(const MachineInstr *MI) const; + + /// Return the Depth of a PHI instruction in a trace center block successor. + /// The PHI does not have to be part of the trace. + unsigned getPHIDepth(const MachineInstr *PHI) const; + }; + + /// A trace ensemble is a collection of traces selected using the same + /// strategy, for example 'minimum resource height'. There is one trace for + /// every block in the function. + class Ensemble { + SmallVector<TraceBlockInfo, 4> BlockInfo; + DenseMap<const MachineInstr*, InstrCycles> Cycles; + SmallVector<unsigned, 0> ProcResourceDepths; + SmallVector<unsigned, 0> ProcResourceHeights; + friend class Trace; + + void computeTrace(const MachineBasicBlock*); + void computeDepthResources(const MachineBasicBlock*); + void computeHeightResources(const MachineBasicBlock*); + unsigned computeCrossBlockCriticalPath(const TraceBlockInfo&); + void computeInstrDepths(const MachineBasicBlock*); + void computeInstrHeights(const MachineBasicBlock*); + void addLiveIns(const MachineInstr *DefMI, unsigned DefOp, + ArrayRef<const MachineBasicBlock*> Trace); + + protected: + MachineTraceMetrics &MTM; + virtual const MachineBasicBlock *pickTracePred(const MachineBasicBlock*) =0; + virtual const MachineBasicBlock *pickTraceSucc(const MachineBasicBlock*) =0; + explicit Ensemble(MachineTraceMetrics*); + const MachineLoop *getLoopFor(const MachineBasicBlock*) const; + const TraceBlockInfo *getDepthResources(const MachineBasicBlock*) const; + const TraceBlockInfo *getHeightResources(const MachineBasicBlock*) const; + ArrayRef<unsigned> getProcResourceDepths(unsigned MBBNum) const; + ArrayRef<unsigned> getProcResourceHeights(unsigned MBBNum) const; + + public: + virtual ~Ensemble(); + virtual const char *getName() const =0; + void print(raw_ostream&) const; + void invalidate(const MachineBasicBlock *MBB); + void verify() const; + + /// Get the trace that passes through MBB. + /// The trace is computed on demand. + Trace getTrace(const MachineBasicBlock *MBB); + }; + + /// Strategies for selecting traces. + enum Strategy { + /// Select the trace through a block that has the fewest instructions. + TS_MinInstrCount, + + TS_NumStrategies + }; + + /// Get the trace ensemble representing the given trace selection strategy. + /// The returned Ensemble object is owned by the MachineTraceMetrics analysis, + /// and valid for the lifetime of the analysis pass. + Ensemble *getEnsemble(Strategy); + + /// Invalidate cached information about MBB. This must be called *before* MBB + /// is erased, or the CFG is otherwise changed. + /// + /// This invalidates per-block information about resource usage for MBB only, + /// and it invalidates per-trace information for any trace that passes + /// through MBB. + /// + /// Call Ensemble::getTrace() again to update any trace handles. + void invalidate(const MachineBasicBlock *MBB); + +private: + // One entry per basic block, indexed by block number. + SmallVector<FixedBlockInfo, 4> BlockInfo; + + // Cycles consumed on each processor resource per block. + // The number of processor resource kinds is constant for a given subtarget, + // but it is not known at compile time. The number of cycles consumed by + // block B on processor resource R is at ProcResourceCycles[B*Kinds + R] + // where Kinds = SchedModel.getNumProcResourceKinds(). + SmallVector<unsigned, 0> ProcResourceCycles; + + // One ensemble per strategy. + Ensemble* Ensembles[TS_NumStrategies]; + + // Convert scaled resource usage to a cycle count that can be compared with + // latencies. + unsigned getCycles(unsigned Scaled) { + unsigned Factor = SchedModel.getLatencyFactor(); + return (Scaled + Factor - 1) / Factor; + } +}; + +inline raw_ostream &operator<<(raw_ostream &OS, + const MachineTraceMetrics::Trace &Tr) { + Tr.print(OS); + return OS; +} + +inline raw_ostream &operator<<(raw_ostream &OS, + const MachineTraceMetrics::Ensemble &En) { + En.print(OS); + return OS; +} +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h index 83c379b..85bf511 100644 --- a/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h +++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h @@ -16,10 +16,10 @@ #define LLVM_CODEGEN_PBQP_GRAPH_H #include "Math.h" - +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" #include <list> #include <map> -#include <llvm/ADT/ilist.h> namespace PBQP { diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h index 35514f9..47e15b2 100644 --- a/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h +++ b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h @@ -18,8 +18,8 @@ #include "Graph.h" #include "Solution.h" -#include <vector> #include <limits> +#include <vector> namespace PBQP { diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index a859e58..307d81e 100644 --- a/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -18,9 +18,8 @@ #ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H #define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H -#include "../HeuristicSolver.h" #include "../HeuristicBase.h" - +#include "../HeuristicSolver.h" #include <limits> namespace PBQP { diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h index e7598bf..08f8b981a 100644 --- a/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h +++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_PBQP_MATH_H +#ifndef LLVM_CODEGEN_PBQP_MATH_H #define LLVM_CODEGEN_PBQP_MATH_H -#include <cassert> #include <algorithm> +#include <cassert> #include <functional> namespace PBQP { diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h index 57d9b95..b9f288b 100644 --- a/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h +++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h @@ -14,9 +14,8 @@ #ifndef LLVM_CODEGEN_PBQP_SOLUTION_H #define LLVM_CODEGEN_PBQP_SOLUTION_H -#include "Math.h" #include "Graph.h" - +#include "Math.h" #include <map> namespace PBQP { diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h index 7bd5764..fc8aa75 100644 --- a/contrib/llvm/include/llvm/CodeGen/Passes.h +++ b/contrib/llvm/include/llvm/CodeGen/Passes.h @@ -25,6 +25,7 @@ namespace llvm { class MachineFunctionPass; class PassInfo; class PassManagerBase; + class TargetLoweringBase; class TargetLowering; class TargetRegisterClass; class raw_ostream; @@ -141,6 +142,10 @@ public: /// Add passes to lower exception handling for the code generator. void addPassesToHandleExceptions(); + /// Add pass to prepare the LLVM IR for code generation. This should be done + /// before exception handling preparation passes. + virtual void addCodeGenPrepare(); + /// Add common passes that perform LLVM IR to IR transforms in preparation for /// instruction selection. virtual void addISelPrepare(); @@ -176,6 +181,16 @@ protected: /// instructions in SSA form. virtual void addMachineSSAOptimization(); + /// Add passes that optimize instruction level parallelism for out-of-order + /// targets. These passes are run while the machine code is still in SSA + /// form, so they can use MachineTraceMetrics to control their heuristics. + /// + /// All passes added here should preserve the MachineDominatorTree, + /// MachineLoopInfo, and MachineTraceMetrics analyses. + virtual bool addILPOpts() { + return false; + } + /// addPreRegAlloc - This method may be implemented by targets that want to /// run passes immediately before register allocation. This should return /// true if -print-machineinstrs should print after these passes. @@ -237,6 +252,11 @@ protected: return false; } + /// addGCPasses - Add late codegen passes that analyze code for garbage + /// collection. This should return true if GC info should be printed after + /// these passes. + virtual bool addGCPasses(); + /// Add standard basic block placement passes. virtual void addBlockPlacement(); @@ -271,6 +291,13 @@ protected: /// List of target independent CodeGen pass IDs. namespace llvm { + /// \brief Create a basic TargetTransformInfo analysis pass. + /// + /// This pass implements the target transform info analysis using the target + /// independent information available to the LLVM code generator. + ImmutablePass * + createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI); + /// createUnreachableBlockEliminationPass - The LLVM code generator does not /// work well with unreachable basic blocks (what live ranges make sense for a /// block that cannot be reached?). As such, a code generator should either @@ -288,9 +315,6 @@ namespace llvm { /// MachineLoopInfo - This pass is a loop analysis pass. extern char &MachineLoopInfoID; - /// MachineLoopRanges - This pass is an on-demand loop coverage analysis. - extern char &MachineLoopRangesID; - /// MachineDominators - This pass is a machine dominators analysis pass. extern char &MachineDominatorsID; @@ -420,10 +444,6 @@ namespace llvm { /// information. extern char &MachineBlockPlacementStatsID; - /// Code Placement - This pass optimize code placement and aligns loop - /// headers to target specific alignment boundary. - extern char &CodePlacementOptID; - /// GCLowering Pass - Performs target-independent LLVM IR transformations for /// highly portable strategies. /// @@ -435,10 +455,6 @@ namespace llvm { /// branch folding). extern char &GCMachineCodeAnalysisID; - /// Deleter Pass - Releases GC metadata. - /// - FunctionPass *createGCInfoDeleter(); - /// Creates a pass to print GC metadata. /// FunctionPass *createGCInfoPrinter(raw_ostream &OS); @@ -469,7 +485,7 @@ namespace llvm { /// createStackProtectorPass - This pass adds stack protectors to functions. /// - FunctionPass *createStackProtectorPass(const TargetLowering *tli); + FunctionPass *createStackProtectorPass(const TargetLoweringBase *tli); /// createMachineVerifierPass - This pass verifies cenerated machine code /// instructions for correctness. @@ -483,7 +499,7 @@ namespace llvm { /// createSjLjEHPreparePass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. /// - FunctionPass *createSjLjEHPreparePass(const TargetLowering *tli); + FunctionPass *createSjLjEHPreparePass(const TargetLoweringBase *tli); /// LocalStackSlotAllocation - This pass assigns local frame indices to stack /// slots relative to one another and allocates base registers to access them diff --git a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h index 8f52d3b..df74d08 100644 --- a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h +++ b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h @@ -14,7 +14,7 @@ #ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H #define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H -#include "llvm/Value.h" +#include "llvm/IR/Value.h" namespace llvm { class MachineFrameInfo; diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h index acfc07d..b617c14 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h +++ b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h @@ -20,7 +20,6 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/PBQP/Graph.h" #include "llvm/CodeGen/PBQP/Solution.h" - #include <map> #include <set> @@ -29,6 +28,7 @@ namespace llvm { class LiveIntervals; class MachineFunction; class MachineLoopInfo; + class TargetRegisterInfo; /// This class wraps up a PBQP instance representing a register allocation /// problem, plus the structures necessary to map back from the PBQP solution diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h index 100e357..ca49577 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h +++ b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGENREGALLOCREGISTRY_H -#define LLVM_CODEGENREGALLOCREGISTRY_H +#ifndef LLVM_CODEGEN_REGALLOCREGISTRY_H +#define LLVM_CODEGEN_REGALLOCREGISTRY_H #include "llvm/CodeGen/MachinePassRegistry.h" diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h b/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h index 4467b62..3ad22e6 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/RegisterClassInfo.h @@ -29,10 +29,15 @@ class RegisterClassInfo { unsigned Tag; unsigned NumRegs; bool ProperSubClass; - OwningArrayPtr<unsigned> Order; + uint8_t MinCost; + uint16_t LastCostChange; + OwningArrayPtr<MCPhysReg> Order; - RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {} - operator ArrayRef<unsigned>() const { + RCInfo() + : Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0), + LastCostChange(0) {} + + operator ArrayRef<MCPhysReg>() const { return makeArrayRef(Order.get(), NumRegs); } }; @@ -84,7 +89,7 @@ public: /// getOrder - Returns the preferred allocation order for RC. The order /// contains no reserved registers, and registers that alias callee saved /// registers come last. - ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const { + ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const { return get(RC); } @@ -106,6 +111,21 @@ public: return CalleeSaved[N-1]; return 0; } + + /// Get the minimum register cost in RC's allocation order. + /// This is the smallest value returned by TRI->getCostPerUse(Reg) for all + /// the registers in getOrder(RC). + unsigned getMinCost(const TargetRegisterClass *RC) { + return get(RC).MinCost; + } + + /// Get the position of the last cost change in getOrder(RC). + /// + /// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have the + /// same cost according to TRI->getCostPerUse(). + unsigned getLastCostChange(const TargetRegisterClass *RC) { + return get(RC).LastCostChange; + } }; } // end namespace llvm diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h index 30326d0..2670180 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h +++ b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h @@ -15,13 +15,14 @@ #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H #define LLVM_CODEGEN_REGISTERPRESSURE_H +#include "llvm/ADT/SparseSet.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/SparseSet.h" namespace llvm { class LiveIntervals; +class LiveInterval; class RegisterClassInfo; class MachineInstr; @@ -30,18 +31,24 @@ struct RegisterPressure { /// Map of max reg pressure indexed by pressure set ID, not class ID. std::vector<unsigned> MaxSetPressure; - /// List of live in registers. + /// List of live in virtual registers or physical register units. SmallVector<unsigned,8> LiveInRegs; SmallVector<unsigned,8> LiveOutRegs; /// Increase register pressure for each pressure set impacted by this register /// class. Normally called by RegPressureTracker, but may be called manually /// to account for live through (global liveness). - void increase(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI); + /// + /// \param Reg is either a virtual register number or register unit number. + void increase(unsigned Reg, const TargetRegisterInfo *TRI, + const MachineRegisterInfo *MRI); /// Decrease register pressure for each pressure set impacted by this register /// class. This is only useful to account for spilling or rematerialization. - void decrease(const TargetRegisterClass *RC, const TargetRegisterInfo *TRI); + /// + /// \param Reg is either a virtual register number or register unit number. + void decrease(unsigned Reg, const TargetRegisterInfo *TRI, + const MachineRegisterInfo *MRI); void dump(const TargetRegisterInfo *TRI) const; }; @@ -116,6 +123,33 @@ struct RegPressureDelta { RegPressureDelta() {} }; +/// \brief A set of live virtual registers and physical register units. +/// +/// Virtual and physical register numbers require separate sparse sets, but most +/// of the RegisterPressureTracker handles them uniformly. +struct LiveRegSet { + SparseSet<unsigned> PhysRegs; + SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs; + + bool contains(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.count(Reg); + return PhysRegs.count(Reg); + } + + bool insert(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.insert(Reg).second; + return PhysRegs.insert(Reg).second; + } + + bool erase(unsigned Reg) { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return VirtRegs.erase(Reg); + return PhysRegs.erase(Reg); + } +}; + /// Track the current register pressure at some position in the instruction /// stream, and remember the high water mark within the region traversed. This /// does not automatically consider live-through ranges. The client may @@ -150,15 +184,15 @@ class RegPressureTracker { bool RequireIntervals; /// Register pressure corresponds to liveness before this instruction - /// iterator. It may point to the end of the block rather than an instruction. + /// iterator. It may point to the end of the block or a DebugValue rather than + /// an instruction. MachineBasicBlock::const_iterator CurrPos; /// Pressure map indexed by pressure set ID, not class ID. std::vector<unsigned> CurrSetPressure; - /// List of live registers. - SparseSet<unsigned> LivePhysRegs; - SparseSet<unsigned, VirtReg2IndexFunctor> LiveVirtRegs; + /// Set of live registers. + LiveRegSet LiveRegs; public: RegPressureTracker(IntervalPressure &rp) : @@ -171,8 +205,9 @@ public: const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos); - /// Force liveness of registers. Particularly useful to initialize the - /// livein/out state of the tracker before the first call to advance/recede. + /// Force liveness of virtual registers or physical register + /// units. Particularly useful to initialize the livein/out state of the + /// tracker before the first call to advance/recede. void addLiveRegs(ArrayRef<unsigned> Regs); /// Get the MI position corresponding to this register pressure. @@ -184,6 +219,10 @@ public: // position changes while pressure does not. void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } + /// \brief Get the SlotIndex for the first nondebug instruction including or + /// after the current position. + SlotIndex getCurrSlot() const; + /// Recede across the previous instruction. bool recede(); @@ -203,11 +242,8 @@ public: /// than the pressure across the traversed region. std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } - void discoverPhysLiveIn(unsigned Reg); - void discoverPhysLiveOut(unsigned Reg); - - void discoverVirtLiveIn(unsigned Reg); - void discoverVirtLiveOut(unsigned Reg); + void discoverLiveOut(unsigned Reg); + void discoverLiveIn(unsigned Reg); bool isTopClosed() const; bool isBottomClosed() const; @@ -268,12 +304,13 @@ public: return getDownwardPressure(MI, PressureResult, MaxPressureResult); } + void dump() const; + protected: - void increasePhysRegPressure(ArrayRef<unsigned> Regs); - void decreasePhysRegPressure(ArrayRef<unsigned> Regs); + const LiveInterval *getInterval(unsigned Reg) const; - void increaseVirtRegPressure(ArrayRef<unsigned> Regs); - void decreaseVirtRegPressure(ArrayRef<unsigned> Regs); + void increaseRegPressure(ArrayRef<unsigned> Regs); + void decreaseRegPressure(ArrayRef<unsigned> Regs); void bumpUpwardPressure(const MachineInstr *MI); void bumpDownwardPressure(const MachineInstr *MI); diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h index 08d3169..95bf291 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h +++ b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h @@ -14,12 +14,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H -#define LLVM_CODEGEN_REGISTER_SCAVENGING_H +#ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H +#define LLVM_CODEGEN_REGISTERSCAVENGING_H +#include "llvm/ADT/BitVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/ADT/BitVector.h" namespace llvm { @@ -40,21 +40,23 @@ class RegScavenger { /// registers. bool Tracking; - /// ScavengingFrameIndex - Special spill slot used for scavenging a register - /// post register allocation. - int ScavengingFrameIndex; + /// Information on scavenged registers (held in a spill slot). + struct ScavengedInfo { + ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(NULL) {} - /// ScavengedReg - If none zero, the specific register is currently being - /// scavenged. That is, it is spilled to the special scavenging stack slot. - unsigned ScavengedReg; + /// A spill slot used for scavenging a register post register allocation. + int FrameIndex; - /// ScavengedRC - Register class of the scavenged register. - /// - const TargetRegisterClass *ScavengedRC; + /// If non-zero, the specific register is currently being + /// scavenged. That is, it is spilled to this scavenging stack slot. + unsigned Reg; - /// ScavengeRestore - Instruction that restores the scavenged register from - /// stack. - const MachineInstr *ScavengeRestore; + /// The instruction that restores the scavenged register from stack. + const MachineInstr *Restore; + }; + + /// A vector of information on scavenged registers. + SmallVector<ScavengedInfo, 2> Scavenged; /// CalleeSavedrRegs - A bitvector of callee saved registers for the target. /// @@ -71,8 +73,7 @@ class RegScavenger { public: RegScavenger() - : MBB(NULL), NumPhysRegs(0), Tracking(false), - ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {} + : MBB(NULL), NumPhysRegs(0), Tracking(false) {} /// enterBasicBlock - Start tracking liveness from the begin of the specific /// basic block. @@ -92,9 +93,25 @@ public: while (MBBI != I) forward(); } + /// Invert the behavior of forward() on the current instruction (undo the + /// changes to the available registers made by forward()). + void unprocess(); + + /// Unprocess instructions until you reach the provided iterator. + void unprocess(MachineBasicBlock::iterator I) { + while (MBBI != I) unprocess(); + } + /// skipTo - Move the internal MBB iterator but do not update register states. - /// - void skipTo(MachineBasicBlock::iterator I) { MBBI = I; } + void skipTo(MachineBasicBlock::iterator I) { + if (I == MachineBasicBlock::iterator(NULL)) + Tracking = false; + MBBI = I; + } + + MachineBasicBlock::iterator getCurrentPosition() const { + return MBBI; + } /// getRegsUsed - return all registers currently in use in used. void getRegsUsed(BitVector &used, bool includeReserved); @@ -107,10 +124,28 @@ public: /// Return 0 if none is found. unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; - /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of - /// ScavengingFrameIndex. - void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; } - int getScavengingFrameIndex() const { return ScavengingFrameIndex; } + /// Add a scavenging frame index. + void addScavengingFrameIndex(int FI) { + Scavenged.push_back(ScavengedInfo(FI)); + } + + /// Query whether a frame index is a scavenging frame index. + bool isScavengingFrameIndex(int FI) const { + for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex == FI) + return true; + + return false; + } + + /// Get an array of scavenging frame indices. + void getScavengingFrameIndices(SmallVectorImpl<int> &A) const { + for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex >= 0) + A.push_back(I->FrameIndex); + } /// scavengeRegister - Make a register of the specific register class /// available and do the appropriate bookkeeping. SPAdj is the stack @@ -129,10 +164,12 @@ private: /// isReserved - Returns true if a register is reserved. It is never "unused". bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } - /// isUsed / isUnused - Test if a register is currently being used. + /// isUsed - Test if a register is currently being used. When called by the + /// isAliasUsed function, we only check isReserved if this is the original + /// register, not an alias register. /// - bool isUsed(unsigned Reg) const { - return !RegsAvailable.test(Reg) || isReserved(Reg); + bool isUsed(unsigned Reg, bool CheckReserved = true) const { + return !RegsAvailable.test(Reg) || (CheckReserved && isReserved(Reg)); } /// isAliasUsed - Is Reg or an alias currently in use? @@ -147,6 +184,10 @@ private: RegsAvailable |= Regs; } + /// Processes the current instruction and fill the KillRegs and DefRegs bit + /// vectors. + void determineKillsAndDefs(); + /// Add Reg and all its sub-registers to BV. void addRegWithSubRegs(BitVector &BV, unsigned Reg); diff --git a/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h b/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h index 56b5855..f20a9fc 100644 --- a/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -14,12 +14,12 @@ // //===----------------------------------------------------------------------===// -#ifndef RESOURCE_PRIORITY_QUEUE_H -#define RESOURCE_PRIORITY_QUEUE_H +#ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H +#define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H #include "llvm/CodeGen/DFAPacketizer.h" -#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" diff --git a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h index 4bfd4ab..41289a4 100644 --- a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h @@ -86,100 +86,131 @@ namespace RTLIB { ADD_F32, ADD_F64, ADD_F80, + ADD_F128, ADD_PPCF128, SUB_F32, SUB_F64, SUB_F80, + SUB_F128, SUB_PPCF128, MUL_F32, MUL_F64, MUL_F80, + MUL_F128, MUL_PPCF128, DIV_F32, DIV_F64, DIV_F80, + DIV_F128, DIV_PPCF128, REM_F32, REM_F64, REM_F80, + REM_F128, REM_PPCF128, FMA_F32, FMA_F64, FMA_F80, + FMA_F128, FMA_PPCF128, POWI_F32, POWI_F64, POWI_F80, + POWI_F128, POWI_PPCF128, SQRT_F32, SQRT_F64, SQRT_F80, + SQRT_F128, SQRT_PPCF128, LOG_F32, LOG_F64, LOG_F80, + LOG_F128, LOG_PPCF128, LOG2_F32, LOG2_F64, LOG2_F80, + LOG2_F128, LOG2_PPCF128, LOG10_F32, LOG10_F64, LOG10_F80, + LOG10_F128, LOG10_PPCF128, EXP_F32, EXP_F64, EXP_F80, + EXP_F128, EXP_PPCF128, EXP2_F32, EXP2_F64, EXP2_F80, + EXP2_F128, EXP2_PPCF128, SIN_F32, SIN_F64, SIN_F80, + SIN_F128, SIN_PPCF128, COS_F32, COS_F64, COS_F80, + COS_F128, COS_PPCF128, + SINCOS_F32, + SINCOS_F64, + SINCOS_F80, + SINCOS_F128, + SINCOS_PPCF128, POW_F32, POW_F64, POW_F80, + POW_F128, POW_PPCF128, CEIL_F32, CEIL_F64, CEIL_F80, + CEIL_F128, CEIL_PPCF128, TRUNC_F32, TRUNC_F64, TRUNC_F80, + TRUNC_F128, TRUNC_PPCF128, RINT_F32, RINT_F64, RINT_F80, + RINT_F128, RINT_PPCF128, NEARBYINT_F32, NEARBYINT_F64, NEARBYINT_F80, + NEARBYINT_F128, NEARBYINT_PPCF128, FLOOR_F32, FLOOR_F64, FLOOR_F80, + FLOOR_F128, FLOOR_PPCF128, COPYSIGN_F32, COPYSIGN_F64, COPYSIGN_F80, + COPYSIGN_F128, COPYSIGN_PPCF128, // CONVERSION + FPEXT_F64_F128, + FPEXT_F32_F128, FPEXT_F32_F64, FPEXT_F16_F32, FPROUND_F32_F16, FPROUND_F64_F32, FPROUND_F80_F32, + FPROUND_F128_F32, FPROUND_PPCF128_F32, FPROUND_F80_F64, + FPROUND_F128_F64, FPROUND_PPCF128_F64, FPTOSINT_F32_I8, FPTOSINT_F32_I16, @@ -194,6 +225,9 @@ namespace RTLIB { FPTOSINT_F80_I32, FPTOSINT_F80_I64, FPTOSINT_F80_I128, + FPTOSINT_F128_I32, + FPTOSINT_F128_I64, + FPTOSINT_F128_I128, FPTOSINT_PPCF128_I32, FPTOSINT_PPCF128_I64, FPTOSINT_PPCF128_I128, @@ -210,51 +244,68 @@ namespace RTLIB { FPTOUINT_F80_I32, FPTOUINT_F80_I64, FPTOUINT_F80_I128, + FPTOUINT_F128_I32, + FPTOUINT_F128_I64, + FPTOUINT_F128_I128, FPTOUINT_PPCF128_I32, FPTOUINT_PPCF128_I64, FPTOUINT_PPCF128_I128, SINTTOFP_I32_F32, SINTTOFP_I32_F64, SINTTOFP_I32_F80, + SINTTOFP_I32_F128, SINTTOFP_I32_PPCF128, SINTTOFP_I64_F32, SINTTOFP_I64_F64, SINTTOFP_I64_F80, + SINTTOFP_I64_F128, SINTTOFP_I64_PPCF128, SINTTOFP_I128_F32, SINTTOFP_I128_F64, SINTTOFP_I128_F80, + SINTTOFP_I128_F128, SINTTOFP_I128_PPCF128, UINTTOFP_I32_F32, UINTTOFP_I32_F64, UINTTOFP_I32_F80, + UINTTOFP_I32_F128, UINTTOFP_I32_PPCF128, UINTTOFP_I64_F32, UINTTOFP_I64_F64, UINTTOFP_I64_F80, + UINTTOFP_I64_F128, UINTTOFP_I64_PPCF128, UINTTOFP_I128_F32, UINTTOFP_I128_F64, UINTTOFP_I128_F80, + UINTTOFP_I128_F128, UINTTOFP_I128_PPCF128, // COMPARISON OEQ_F32, OEQ_F64, + OEQ_F128, UNE_F32, UNE_F64, + UNE_F128, OGE_F32, OGE_F64, + OGE_F128, OLT_F32, OLT_F64, + OLT_F128, OLE_F32, OLE_F64, + OLE_F128, OGT_F32, OGT_F64, + OGT_F128, UO_F32, UO_F64, + UO_F128, O_F32, O_F64, + O_F128, // MEMORY MEMCPY, diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h index 7e0ca14..8c959da 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h @@ -16,13 +16,12 @@ #ifndef LLVM_CODEGEN_SCHEDULEDAG_H #define LLVM_CODEGEN_SCHEDULEDAG_H -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetLowering.h" namespace llvm { class AliasAnalysis; @@ -53,11 +52,22 @@ namespace llvm { Order ///< Any other ordering dependency. }; + // Strong dependencies must be respected by the scheduler. Artificial + // dependencies may be removed only if they are redundant with another + // strong depedence. + // + // Weak dependencies may be violated by the scheduling strategy, but only if + // the strategy can prove it is correct to do so. + // + // Strong OrderKinds must occur before "Weak". + // Weak OrderKinds must occur after "Weak". enum OrderKind { Barrier, ///< An unknown scheduling barrier. MayAliasMem, ///< Nonvolatile load/Store instructions that may alias. MustAliasMem, ///< Nonvolatile load/Store instructions that must alias. - Artificial ///< Arbitrary weak DAG edge (no actual dependence). + Artificial, ///< Arbitrary strong DAG edge (no real dependence). + Weak, ///< Arbitrary weak DAG edge. + Cluster ///< Weak DAG edge linking a chain of clustered instrs. }; private: @@ -200,12 +210,26 @@ namespace llvm { return getKind() == Order && Contents.OrdKind == MustAliasMem; } + /// isWeak - Test if this a weak dependence. Weak dependencies are + /// considered DAG edges for height computation and other heuristics, but do + /// not force ordering. Breaking a weak edge may require the scheduler to + /// compensate, for example by inserting a copy. + bool isWeak() const { + return getKind() == Order && Contents.OrdKind >= Weak; + } + /// isArtificial - Test if this is an Order dependence that is marked /// as "artificial", meaning it isn't necessary for correctness. bool isArtificial() const { return getKind() == Order && Contents.OrdKind == Artificial; } + /// isCluster - Test if this is an Order dependence that is marked + /// as "cluster", meaning it is artificial and wants to be adjacent. + bool isCluster() const { + return getKind() == Order && Contents.OrdKind == Cluster; + } + /// isAssignedRegDep - Test if this is a Data dependence that is /// associated with a register. bool isAssignedRegDep() const { @@ -243,6 +267,8 @@ namespace llvm { /// SUnit - Scheduling unit. This is a node in the scheduling DAG. class SUnit { private: + enum { BoundaryID = ~0u }; + SDNode *Node; // Representative node. MachineInstr *Instr; // Alternatively, a MachineInstr. public: @@ -267,6 +293,8 @@ namespace llvm { unsigned NumSuccs; // # of SDep::Data sucss. unsigned NumPredsLeft; // # of preds not scheduled. unsigned NumSuccsLeft; // # of succs not scheduled. + unsigned WeakPredsLeft; // # of weak preds not scheduled. + unsigned WeakSuccsLeft; // # of weak 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. @@ -301,12 +329,12 @@ namespace llvm { SUnit(SDNode *node, unsigned nodenum) : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), - NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), - isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), - isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isScheduleLow(false), isCloned(false), - SchedulingPref(Sched::None), + NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), + Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), + isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), + hasPhysRegClobbers(false), isPending(false), isAvailable(false), + isScheduled(false), isScheduleHigh(false), isScheduleLow(false), + isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -315,28 +343,37 @@ namespace llvm { SUnit(MachineInstr *instr, unsigned nodenum) : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), - NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), - isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), - isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isScheduleLow(false), isCloned(false), - SchedulingPref(Sched::None), + NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), + Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), + isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), + hasPhysRegClobbers(false), isPending(false), isAvailable(false), + isScheduled(false), isScheduleHigh(false), isScheduleLow(false), + isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} /// SUnit - Construct a placeholder SUnit. SUnit() - : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u), + : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), - NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), - isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), - isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isScheduleLow(false), isCloned(false), - SchedulingPref(Sched::None), + NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), + Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), + isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), + hasPhysRegClobbers(false), isPending(false), isAvailable(false), + isScheduled(false), isScheduleHigh(false), isScheduleLow(false), + isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} + /// \brief Boundary nodes are placeholders for the boundary of the + /// scheduling region. + /// + /// BoundaryNodes can have DAG edges, including Data edges, but they do not + /// correspond to schedulable entities (e.g. instructions) and do not have a + /// valid ID. Consequently, always check for boundary nodes before accessing + /// an assoicative data structure keyed on node ID. + bool isBoundaryNode() const { return NodeNum == BoundaryID; }; + /// setNode - Assign the representative SDNode for this SUnit. /// This may be used during pre-regalloc scheduling. void setNode(SDNode *N) { @@ -372,7 +409,7 @@ namespace llvm { /// addPred - This adds the specified edge as a pred of the current node if /// not already. It also adds the current node as a successor of the /// specified node. - bool addPred(const SDep &D); + bool addPred(const SDep &D, bool Required = true); /// removePred - This removes the specified edge as a pred of the current /// node if it exists. It also removes the current node as a successor of @@ -438,6 +475,10 @@ namespace llvm { return NumSuccsLeft == 0; } + /// \brief Order this node's predecessor edges such that the critical path + /// edge occurs first. + void biasCriticalPath(); + void dump(const ScheduleDAG *G) const; void dumpAll(const ScheduleDAG *G) const; void print(raw_ostream &O, const ScheduleDAG *G) const; @@ -546,8 +587,8 @@ namespace llvm { /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. /// - void viewGraph(const Twine &Name, const Twine &Title); - void viewGraph(); + virtual void viewGraph(const Twine &Name, const Twine &Title); + virtual void viewGraph(); virtual void dumpNode(const SUnit *SU) const = 0; @@ -654,6 +695,7 @@ namespace llvm { class ScheduleDAGTopologicalSort { /// SUnits - A reference to the ScheduleDAG's SUnits. std::vector<SUnit> &SUnits; + SUnit *ExitSU; /// Index2Node - Maps topological index to the node number. std::vector<int> Index2Node; @@ -675,7 +717,7 @@ namespace llvm { void Allocate(int n, int index); public: - explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits); + ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU); /// InitDAGTopologicalSorting - create the initial topological /// ordering from the DAG to be scheduled. diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGILP.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGILP.h deleted file mode 100644 index 1aa4058..0000000 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGILP.h +++ /dev/null @@ -1,86 +0,0 @@ -//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Definition of an ILP metric for machine level instruction scheduling. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H -#define LLVM_CODEGEN_SCHEDULEDAGILP_H - -#include "llvm/Support/DataTypes.h" -#include <vector> - -namespace llvm { - -class raw_ostream; -class ScheduleDAGInstrs; -class SUnit; - -/// \brief Represent the ILP of the subDAG rooted at a DAG node. -struct ILPValue { - unsigned InstrCount; - unsigned Cycles; - - ILPValue(): InstrCount(0), Cycles(0) {} - - ILPValue(unsigned count, unsigned cycles): - InstrCount(count), Cycles(cycles) {} - - bool isValid() const { return Cycles > 0; } - - // Order by the ILP metric's value. - bool operator<(ILPValue RHS) const { - return (uint64_t)InstrCount * RHS.Cycles - < (uint64_t)Cycles * RHS.InstrCount; - } - bool operator>(ILPValue RHS) const { - return RHS < *this; - } - bool operator<=(ILPValue RHS) const { - return (uint64_t)InstrCount * RHS.Cycles - <= (uint64_t)Cycles * RHS.InstrCount; - } - bool operator>=(ILPValue RHS) const { - return RHS <= *this; - } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void print(raw_ostream &OS) const; - - void dump() const; -#endif -}; - -/// \brief Compute the values of each DAG node for an ILP metric. -/// -/// This metric assumes that the DAG is a forest of trees with roots at the -/// bottom of the schedule. -class ScheduleDAGILP { - bool IsBottomUp; - std::vector<ILPValue> ILPValues; - -public: - ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {} - - /// \brief Initialize the result data with the size of the DAG. - void resize(unsigned NumSUnits); - - /// \brief Compute the ILP metric for the subDAG at this root. - void computeILP(const SUnit *Root); - - /// \brief Get the ILP value for a DAG node. - ILPValue getILP(const SUnit *SU); -}; - -raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); - -} // namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h index 4bcd35a..2219520 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -12,20 +12,18 @@ // //===----------------------------------------------------------------------===// -#ifndef SCHEDULEDAGINSTRS_H -#define SCHEDULEDAGINSTRS_H +#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H +#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/ADT/SparseSet.h" +#include "llvm/ADT/SparseMultiSet.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/TargetSchedule.h" #include "llvm/Support/Compiler.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/SparseSet.h" -#include <map> namespace llvm { + class MachineFrameInfo; class MachineLoopInfo; class MachineDominatorTree; class LiveIntervals; @@ -48,56 +46,18 @@ namespace llvm { struct PhysRegSUOper { SUnit *SU; int OpIdx; + unsigned Reg; - PhysRegSUOper(SUnit *su, int op): SU(su), OpIdx(op) {} - }; - - /// Combine a SparseSet with a 1x1 vector to track physical registers. - /// The SparseSet allows iterating over the (few) live registers for quickly - /// comparing against a regmask or clearing the set. - /// - /// Storage for the map is allocated once for the pass. The map can be - /// cleared between scheduling regions without freeing unused entries. - class Reg2SUnitsMap { - SparseSet<unsigned> PhysRegSet; - std::vector<std::vector<PhysRegSUOper> > SUnits; - public: - typedef SparseSet<unsigned>::const_iterator const_iterator; - - // Allow iteration over register numbers (keys) in the map. If needed, we - // can provide an iterator over SUnits (values) as well. - const_iterator reg_begin() const { return PhysRegSet.begin(); } - const_iterator reg_end() const { return PhysRegSet.end(); } - - /// Initialize the map with the number of registers. - /// If the map is already large enough, no allocation occurs. - /// For simplicity we expect the map to be empty(). - void setRegLimit(unsigned Limit); + PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {} - /// Returns true if the map is empty. - bool empty() const { return PhysRegSet.empty(); } - - /// Clear the map without deallocating storage. - void clear(); - - bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); } - - /// If this register is mapped, return its existing SUnits vector. - /// Otherwise map the register and return an empty SUnits vector. - std::vector<PhysRegSUOper> &operator[](unsigned Reg) { - bool New = PhysRegSet.insert(Reg).second; - assert((!New || SUnits[Reg].empty()) && "stale SUnits vector"); - (void)New; - return SUnits[Reg]; - } - - /// Erase an existing element without freeing memory. - void erase(unsigned Reg) { - PhysRegSet.erase(Reg); - SUnits[Reg].clear(); - } + unsigned getSparseSetIndex() const { return Reg; } }; + /// Use a SparseMultiSet to track physical registers. Storage is only + /// allocated once for the pass. It can be cleared in constant time and reused + /// without any frees. + typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t> Reg2SUnitsMap; + /// Use SparseSet as a SparseMap by relying on the fact that it never /// compares ValueT's, only unsigned keys. This allows the set to be cleared /// between scheduling regions in constant time as long as ValueT does not diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h new file mode 100644 index 0000000..73ce99f --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDFS.h @@ -0,0 +1,196 @@ +//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of an ILP metric for machine level instruction scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SCHEDULEDFS_H +#define LLVM_CODEGEN_SCHEDULEDFS_H + +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { + +class raw_ostream; +class IntEqClasses; +class ScheduleDAGInstrs; +class SUnit; + +/// \brief Represent the ILP of the subDAG rooted at a DAG node. +/// +/// ILPValues summarize the DAG subtree rooted at each node. ILPValues are +/// valid for all nodes regardless of their subtree membership. +/// +/// When computed using bottom-up DFS, this metric assumes that the DAG is a +/// forest of trees with roots at the bottom of the schedule branching upward. +struct ILPValue { + unsigned InstrCount; + /// Length may either correspond to depth or height, depending on direction, + /// and cycles or nodes depending on context. + unsigned Length; + + ILPValue(unsigned count, unsigned length): + InstrCount(count), Length(length) {} + + // Order by the ILP metric's value. + bool operator<(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Length + < (uint64_t)Length * RHS.InstrCount; + } + bool operator>(ILPValue RHS) const { + return RHS < *this; + } + bool operator<=(ILPValue RHS) const { + return (uint64_t)InstrCount * RHS.Length + <= (uint64_t)Length * RHS.InstrCount; + } + bool operator>=(ILPValue RHS) const { + return RHS <= *this; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + void print(raw_ostream &OS) const; + + void dump() const; +#endif +}; + +/// \brief Compute the values of each DAG node for various metrics during DFS. +class SchedDFSResult { + friend class SchedDFSImpl; + + static const unsigned InvalidSubtreeID = ~0u; + + /// \brief Per-SUnit data computed during DFS for various metrics. + /// + /// A node's SubtreeID is set to itself when it is visited to indicate that it + /// is the root of a subtree. Later it is set to its parent to indicate an + /// interior node. Finally, it is set to a representative subtree ID during + /// finalization. + struct NodeData { + unsigned InstrCount; + unsigned SubtreeID; + + NodeData(): InstrCount(0), SubtreeID(InvalidSubtreeID) {} + }; + + /// \brief Per-Subtree data computed during DFS. + struct TreeData { + unsigned ParentTreeID; + unsigned SubInstrCount; + + TreeData(): ParentTreeID(InvalidSubtreeID), SubInstrCount(0) {} + }; + + /// \brief Record a connection between subtrees and the connection level. + struct Connection { + unsigned TreeID; + unsigned Level; + + Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {} + }; + + bool IsBottomUp; + unsigned SubtreeLimit; + /// DFS results for each SUnit in this DAG. + std::vector<NodeData> DFSNodeData; + + // Store per-tree data indexed on tree ID, + SmallVector<TreeData, 16> DFSTreeData; + + // For each subtree discovered during DFS, record its connections to other + // subtrees. + std::vector<SmallVector<Connection, 4> > SubtreeConnections; + + /// Cache the current connection level of each subtree. + /// This mutable array is updated during scheduling. + std::vector<unsigned> SubtreeConnectLevels; + +public: + SchedDFSResult(bool IsBU, unsigned lim) + : IsBottomUp(IsBU), SubtreeLimit(lim) {} + + /// \brief Get the node cutoff before subtrees are considered significant. + unsigned getSubtreeLimit() const { return SubtreeLimit; } + + /// \brief Return true if this DFSResult is uninitialized. + /// + /// resize() initializes DFSResult, while compute() populates it. + bool empty() const { return DFSNodeData.empty(); } + + /// \brief Clear the results. + void clear() { + DFSNodeData.clear(); + DFSTreeData.clear(); + SubtreeConnections.clear(); + SubtreeConnectLevels.clear(); + } + + /// \brief Initialize the result data with the size of the DAG. + void resize(unsigned NumSUnits) { + DFSNodeData.resize(NumSUnits); + } + + /// \brief Compute various metrics for the DAG with given roots. + void compute(ArrayRef<SUnit> SUnits); + + /// \brief Get the number of instructions in the given subtree and its + /// children. + unsigned getNumInstrs(const SUnit *SU) const { + return DFSNodeData[SU->NodeNum].InstrCount; + } + + /// \brief Get the number of instructions in the given subtree not including + /// children. + unsigned getNumSubInstrs(unsigned SubtreeID) const { + return DFSTreeData[SubtreeID].SubInstrCount; + } + + /// \brief Get the ILP value for a DAG node. + /// + /// A leaf node has an ILP of 1/1. + ILPValue getILP(const SUnit *SU) const { + return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth()); + } + + /// \brief The number of subtrees detected in this DAG. + unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); } + + /// \brief Get the ID of the subtree the given DAG node belongs to. + /// + /// For convenience, if DFSResults have not been computed yet, give everything + /// tree ID 0. + unsigned getSubtreeID(const SUnit *SU) const { + if (empty()) + return 0; + assert(SU->NodeNum < DFSNodeData.size() && "New Node"); + return DFSNodeData[SU->NodeNum].SubtreeID; + } + + /// \brief Get the connection level of a subtree. + /// + /// For bottom-up trees, the connection level is the latency depth (in cycles) + /// of the deepest connection to another subtree. + unsigned getSubtreeLevel(unsigned SubtreeID) const { + return SubtreeConnectLevels[SubtreeID]; + } + + /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is + /// initially scheduled. + void scheduleTree(unsigned SubtreeID); +}; + +raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val); + +} // namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h index 836b73a..51ac7f2 100644 --- a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h +++ b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H -#define LLVM_CODEGENSCHEDULERREGISTRY_H +#ifndef LLVM_CODEGEN_SCHEDULERREGISTRY_H +#define LLVM_CODEGEN_SCHEDULERREGISTRY_H #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/Target/TargetMachine.h" diff --git a/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 060e89a..c2103fb 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -18,7 +18,6 @@ #include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/Support/DataTypes.h" - #include <cassert> #include <cstring> diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h index 619ee69..e5adf67 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -15,16 +15,17 @@ #ifndef LLVM_CODEGEN_SELECTIONDAG_H #define LLVM_CODEGEN_SELECTIONDAG_H -#include "llvm/ADT/ilist.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/ilist.h" +#include "llvm/CodeGen/DAGCombine.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Support/RecyclingAllocator.h" #include "llvm/Target/TargetMachine.h" #include <cassert> -#include <vector> #include <map> #include <string> +#include <vector> namespace llvm { @@ -36,6 +37,7 @@ class SDNodeOrdering; class SDDbgValue; class TargetLowering; class TargetSelectionDAGInfo; +class TargetTransformInfo; template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> { private: @@ -111,13 +113,6 @@ public: DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); } }; -enum CombineLevel { - BeforeLegalizeTypes, - AfterLegalizeTypes, - AfterLegalizeVectorOps, - AfterLegalizeDAG -}; - class SelectionDAG; void checkForCycles(const SDNode *N); void checkForCycles(const SelectionDAG *DAG); @@ -137,6 +132,7 @@ class SelectionDAG { const TargetMachine &TM; const TargetLowering &TLI; const TargetSelectionDAGInfo &TSI; + const TargetTransformInfo *TTI; MachineFunction *MF; LLVMContext *Context; CodeGenOpt::Level OptLevel; @@ -232,7 +228,7 @@ public: /// init - Prepare this SelectionDAG to process code in the given /// MachineFunction. /// - void init(MachineFunction &mf); + void init(MachineFunction &mf, const TargetTransformInfo *TTI); /// clear - Clear state and free memory necessary to make this /// SelectionDAG ready to process a new block. @@ -243,6 +239,7 @@ public: const TargetMachine &getTarget() const { return TM; } const TargetLowering &getTargetLoweringInfo() const { return TLI; } const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; } + const TargetTransformInfo *getTargetTransformInfo() const { return TTI; } LLVMContext *getContext() const {return Context; } /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'. @@ -570,7 +567,7 @@ public: SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, const SDValue *Ops, unsigned NumOps); SDValue getNode(unsigned Opcode, DebugLoc DL, - const std::vector<EVT> &ResultTys, + ArrayRef<EVT> ResultTys, const SDValue *Ops, unsigned NumOps); SDValue getNode(unsigned Opcode, DebugLoc DL, const EVT *VTs, unsigned NumVTs, const SDValue *Ops, unsigned NumOps); @@ -834,7 +831,7 @@ public: MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, EVT VT3, EVT VT4, const SDValue *Ops, unsigned NumOps); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, - const std::vector<EVT> &ResultTys, const SDValue *Ops, + ArrayRef<EVT> ResultTys, const SDValue *Ops, unsigned NumOps); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps); @@ -938,6 +935,20 @@ public: } } + /// Returns an APFloat semantics tag appropriate for the given type. If VT is + /// a vector type, the element semantics are returned. + static const fltSemantics &EVTToAPFloatSemantics(EVT VT) { + switch (VT.getScalarType().getSimpleVT().SimpleTy) { + default: llvm_unreachable("Unknown FP format"); + case MVT::f16: return APFloat::IEEEhalf; + case MVT::f32: return APFloat::IEEEsingle; + case MVT::f64: return APFloat::IEEEdouble; + case MVT::f80: return APFloat::x87DoubleExtended; + case MVT::f128: return APFloat::IEEEquad; + case MVT::ppcf128: return APFloat::PPCDoubleDouble; + } + } + /// AssignOrdering - Assign an order to the SDNode. void AssignOrdering(const SDNode *SD, unsigned Order); @@ -981,10 +992,8 @@ public: SDValue CreateStackTemporary(EVT VT1, EVT VT2); /// FoldConstantArithmetic - - SDValue FoldConstantArithmetic(unsigned Opcode, - EVT VT, - ConstantSDNode *Cst1, - ConstantSDNode *Cst2); + SDValue FoldConstantArithmetic(unsigned Opcode, EVT VT, + SDNode *Cst1, SDNode *Cst2); /// FoldSetCC - Constant fold a setcc to true or false. SDValue FoldSetCC(EVT VT, SDValue N1, diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h index c42f655..5f503de 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H -#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H +#ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H +#define LLVM_CODEGEN_SELECTIONDAGISEL_H -#include "llvm/BasicBlock.h" -#include "llvm/Pass.h" -#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/Pass.h" namespace llvm { class FastISel; @@ -31,6 +31,7 @@ namespace llvm { class TargetLowering; class TargetLibraryInfo; class TargetInstrInfo; + class TargetTransformInfo; class FunctionLoweringInfo; class ScheduleHazardRecognizer; class GCFunctionInfo; @@ -44,6 +45,7 @@ public: const TargetMachine &TM; const TargetLowering &TLI; const TargetLibraryInfo *LibInfo; + const TargetTransformInfo *TTI; FunctionLoweringInfo *FuncInfo; MachineFunction *MF; MachineRegisterInfo *RegInfo; @@ -247,16 +249,26 @@ private: const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); void PrepareEHLandingPad(); + + /// \brief Perform instruction selection on all basic blocks in the function. void SelectAllBasicBlocks(const Function &Fn); - bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst, - FastISel *FastIS); - void FinishBasicBlock(); + /// \brief Perform instruction selection on a single basic block, for + /// instructions between \p Begin and \p End. \p HadTailCall will be set + /// to true if a call in the block was translated as a tail call. void SelectBasicBlock(BasicBlock::const_iterator Begin, BasicBlock::const_iterator End, bool &HadTailCall); + + bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst, + FastISel *FastIS); + void FinishBasicBlock(); + void CodeGenAndEmitDAG(); - void LowerArguments(const BasicBlock *BB); + + /// \brief Generate instructions for lowering the incoming arguments of the + /// given function. + void LowerArguments(const Function &F); void ComputeLiveOutVRegInfo(); @@ -279,4 +291,4 @@ private: } -#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */ +#endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */ diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 362e9af..fef567f 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -19,20 +19,20 @@ #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H #define LLVM_CODEGEN_SELECTIONDAGNODES_H -#include "llvm/Constants.h" -#include "llvm/Instructions.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/CodeGen/ISDOpcodes.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineMemOperand.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Support/MathExtras.h" #include <cassert> namespace llvm { @@ -49,7 +49,7 @@ template <typename T> struct simplify_type; template <typename T> struct ilist_traits; void checkForCycles(const SDNode *N); - + /// SDVTList - This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by /// SelectionDAG::getVTList(...). @@ -108,7 +108,7 @@ public: void setNode(SDNode *N) { Node = N; } inline SDNode *operator->() const { return Node; } - + bool operator==(const SDValue &O) const { return Node == O.Node && ResNo == O.ResNo; } @@ -130,6 +130,11 @@ public: /// inline EVT getValueType() const; + /// Return the simple ValueType of the referenced return value. + MVT getSimpleValueType() const { + return getValueType().getSimpleVT(); + } + /// getValueSizeInBits - Returns the size of the value in bits. /// unsigned getValueSizeInBits() const { @@ -191,14 +196,14 @@ template <> struct isPodLike<SDValue> { static const bool value = true; }; /// SDValues as if they were SDNode*'s. template<> struct simplify_type<SDValue> { typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDValue &Val) { - return static_cast<SimpleType>(Val.getNode()); + static SimpleType getSimplifiedValue(SDValue &Val) { + return Val.getNode(); } }; template<> struct simplify_type<const SDValue> { - typedef SDNode* SimpleType; + typedef /*const*/ SDNode* SimpleType; static SimpleType getSimplifiedValue(const SDValue &Val) { - return static_cast<SimpleType>(Val.getNode()); + return Val.getNode(); } }; @@ -290,14 +295,8 @@ private: /// SDValues as if they were SDNode*'s. template<> struct simplify_type<SDUse> { typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast<SimpleType>(Val.getNode()); - } -}; -template<> struct simplify_type<const SDUse> { - typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast<SimpleType>(Val.getNode()); + static SimpleType getSimplifiedValue(SDUse &Val) { + return Val.getNode(); } }; @@ -525,7 +524,7 @@ public: /// NOTE: This is still very expensive. Use carefully. bool hasPredecessorHelper(const SDNode *N, SmallPtrSet<const SDNode *, 32> &Visited, - SmallVector<const SDNode *, 16> &Worklist) const; + SmallVector<const SDNode *, 16> &Worklist) const; /// getNumOperands - Return the number of values used by this operation. /// @@ -595,6 +594,12 @@ public: return ValueList[ResNo]; } + /// Return the type of a specified result as a simple type. + /// + MVT getSimpleValueType(unsigned ResNo) const { + return getValueType(ResNo).getSimpleVT(); + } + /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)). /// unsigned getValueSizeInBits(unsigned ResNo) const { @@ -1287,7 +1292,7 @@ class ConstantPoolSDNode : public SDNode { : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { - assert((int)Offset >= 0 && "Offset is too large"); + assert(Offset >= 0 && "Offset is too large"); Val.ConstVal = c; } ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, @@ -1295,7 +1300,7 @@ class ConstantPoolSDNode : public SDNode { : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { - assert((int)Offset >= 0 && "Offset is too large"); + assert(Offset >= 0 && "Offset is too large"); Val.MachineCPVal = v; Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1); } @@ -1303,7 +1308,7 @@ public: bool isMachineConstantPoolEntry() const { - return (int)Offset < 0; + return Offset < 0; } const Constant *getConstVal() const { diff --git a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h index c52599b..a277080 100644 --- a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -19,13 +19,14 @@ #ifndef LLVM_CODEGEN_SLOTINDEXES_H #define LLVM_CODEGEN_SLOTINDEXES_H -#include "llvm/CodeGen/MachineInstrBundle.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/ilist.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ilist.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/Support/Allocator.h" namespace llvm { @@ -111,7 +112,7 @@ namespace llvm { return lie.getPointer(); } - int getIndex() const { + unsigned getIndex() const { return listEntry()->getIndex() | getSlot(); } @@ -359,6 +360,11 @@ namespace llvm { /// Renumber the index list, providing space for new instructions. void renumberIndexes(); + /// Repair indexes after adding and removing instructions. + void repairIndexesInRange(MachineBasicBlock *MBB, + MachineBasicBlock::iterator Begin, + MachineBasicBlock::iterator End); + /// Returns the zero index for this analysis. SlotIndex getZeroIndex() { assert(indexList.front().getIndex() == 0 && "First index is not 0?"); @@ -390,12 +396,16 @@ namespace llvm { return index.isValid() ? index.listEntry()->getInstr() : 0; } - /// Returns the next non-null index. - SlotIndex getNextNonNullIndex(SlotIndex index) { - IndexList::iterator itr(index.listEntry()); - ++itr; - while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; } - return SlotIndex(itr, index.getSlot()); + /// Returns the next non-null index, if one exists. + /// Otherwise returns getLastIndex(). + SlotIndex getNextNonNullIndex(SlotIndex Index) { + IndexList::iterator I = Index.listEntry(); + IndexList::iterator E = indexList.end(); + while (++I != E) + if (I->getInstr()) + return SlotIndex(I, Index.getSlot()); + // We reached the end of the function. + return getLastIndex(); } /// getIndexBefore - Returns the index of the last indexed instruction @@ -601,29 +611,35 @@ namespace llvm { void insertMBBInMaps(MachineBasicBlock *mbb) { MachineFunction::iterator nextMBB = llvm::next(MachineFunction::iterator(mbb)); - IndexListEntry *startEntry = createEntry(0, 0); - IndexListEntry *stopEntry = createEntry(0, 0); - IndexListEntry *nextEntry = 0; + IndexListEntry *startEntry = 0; + IndexListEntry *endEntry = 0; + IndexList::iterator newItr; if (nextMBB == mbb->getParent()->end()) { - nextEntry = indexList.end(); + startEntry = &indexList.back(); + endEntry = createEntry(0, 0); + newItr = indexList.insertAfter(startEntry, endEntry); } else { - nextEntry = getMBBStartIdx(nextMBB).listEntry(); + startEntry = createEntry(0, 0); + endEntry = getMBBStartIdx(nextMBB).listEntry(); + newItr = indexList.insert(endEntry, startEntry); } - indexList.insert(nextEntry, startEntry); - indexList.insert(nextEntry, stopEntry); - SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); - SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block); + SlotIndex endIdx(endEntry, SlotIndex::Slot_Block); + + MachineFunction::iterator prevMBB(mbb); + assert(prevMBB != mbb->getParent()->end() && + "Can't insert a new block at the beginning of a function."); + --prevMBB; + MBBRanges[prevMBB->getNumber()].second = startIdx; 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)); - renumberIndexes(); + renumberIndexes(newItr); std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); } @@ -631,17 +647,8 @@ namespace llvm { // Specialize IntervalMapInfo for half-open slot index intervals. - template <typename> struct IntervalMapInfo; - template <> struct IntervalMapInfo<SlotIndex> { - static inline bool startLess(const SlotIndex &x, const SlotIndex &a) { - return x < a; - } - static inline bool stopLess(const SlotIndex &b, const SlotIndex &x) { - return b <= x; - } - static inline bool adjacent(const SlotIndex &a, const SlotIndex &b) { - return a == b; - } + template <> + struct IntervalMapInfo<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> { }; } diff --git a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 9849e92..e7098e4 100644 --- a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -15,9 +15,9 @@ #ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H #define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/ADT/StringRef.h" namespace llvm { class MachineModuleInfo; @@ -55,13 +55,12 @@ public: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; - /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference - /// to the specified global variable from exception handling information. - /// + /// getTTypeGlobalReference - Return an MCExpr to use for a reference to the + /// specified type info global variable from exception handling information. virtual const MCExpr * - getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const; + getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const; // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. virtual MCSymbol * @@ -103,12 +102,12 @@ public: virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *) const; - /// getExprForDwarfGlobalReference - The mach-o version of this method + /// getTTypeGlobalReference - The mach-o version of this method /// defaults to returning a stub reference. virtual const MCExpr * - getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const; + getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const; // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. virtual MCSymbol * diff --git a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h index 88e6105..3e22252 100644 --- a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h +++ b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h @@ -13,13 +13,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETSCHEDMODEL_H -#define LLVM_TARGET_TARGETSCHEDMODEL_H +#ifndef LLVM_CODEGEN_TARGETSCHEDULE_H +#define LLVM_CODEGEN_TARGETSCHEDULE_H -#include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/MC/MCSchedule.h" -#include "llvm/MC/MCInstrItineraries.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/MCSchedule.h" +#include "llvm/Target/TargetSubtargetInfo.h" namespace llvm { @@ -84,6 +84,9 @@ public: /// \brief Maximum number of micro-ops that may be scheduled per cycle. unsigned getIssueWidth() const { return SchedModel.IssueWidth; } + /// \brief Number of cycles the OOO processor is expected to hide. + unsigned getILPWindow() const { return SchedModel.ILPWindow; } + /// \brief Return the number of issue slots required for this MI. unsigned getNumMicroOps(const MachineInstr *MI, const MCSchedClassDesc *SC = 0) const; diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h index 2401992..ec48b67 100644 --- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h @@ -33,6 +33,10 @@ namespace llvm { class MVT { public: enum SimpleValueType { + // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are + // considered extended value types. + INVALID_SIMPLE_VALUE_TYPE = -1, + // If you change this numbering, you must change the values in // ValueTypes.td as well! Other = 0, // This is a non-standard value @@ -60,52 +64,61 @@ namespace llvm { v4i1 = 14, // 4 x i1 v8i1 = 15, // 8 x i1 v16i1 = 16, // 16 x i1 - v2i8 = 17, // 2 x i8 - v4i8 = 18, // 4 x i8 - v8i8 = 19, // 8 x i8 - v16i8 = 20, // 16 x i8 - v32i8 = 21, // 32 x i8 - v1i16 = 22, // 1 x i16 - v2i16 = 23, // 2 x i16 - v4i16 = 24, // 4 x i16 - v8i16 = 25, // 8 x i16 - v16i16 = 26, // 16 x i16 - v1i32 = 27, // 1 x i32 - v2i32 = 28, // 2 x i32 - v4i32 = 29, // 4 x i32 - v8i32 = 30, // 8 x i32 - v16i32 = 31, // 16 x i32 - v1i64 = 32, // 1 x i64 - v2i64 = 33, // 2 x i64 - v4i64 = 34, // 4 x i64 - v8i64 = 35, // 8 x i64 - v16i64 = 36, // 16 x i64 - - v2f16 = 37, // 2 x f16 - v2f32 = 38, // 2 x f32 - v4f32 = 39, // 4 x f32 - v8f32 = 40, // 8 x f32 - v2f64 = 41, // 2 x f64 - v4f64 = 42, // 4 x f64 + v32i1 = 17, // 32 x i1 + v64i1 = 18, // 64 x i1 + + v2i8 = 19, // 2 x i8 + v4i8 = 20, // 4 x i8 + v8i8 = 21, // 8 x i8 + v16i8 = 22, // 16 x i8 + v32i8 = 23, // 32 x i8 + v64i8 = 24, // 64 x i8 + v1i16 = 25, // 1 x i16 + v2i16 = 26, // 2 x i16 + v4i16 = 27, // 4 x i16 + v8i16 = 28, // 8 x i16 + v16i16 = 29, // 16 x i16 + v32i16 = 30, // 32 x i16 + v1i32 = 31, // 1 x i32 + v2i32 = 32, // 2 x i32 + v4i32 = 33, // 4 x i32 + v8i32 = 34, // 8 x i32 + v16i32 = 35, // 16 x i32 + v1i64 = 36, // 1 x i64 + v2i64 = 37, // 2 x i64 + v4i64 = 38, // 4 x i64 + v8i64 = 39, // 8 x i64 + v16i64 = 40, // 16 x i64 - FIRST_VECTOR_VALUETYPE = v2i1, - LAST_VECTOR_VALUETYPE = v4f64, FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, LAST_INTEGER_VECTOR_VALUETYPE = v16i64, + + v2f16 = 41, // 2 x f16 + v2f32 = 42, // 2 x f32 + v4f32 = 43, // 4 x f32 + v8f32 = 44, // 8 x f32 + v16f32 = 45, // 16 x f32 + v2f64 = 46, // 2 x f64 + v4f64 = 47, // 4 x f64 + v8f64 = 48, // 8 x f64 + FIRST_FP_VECTOR_VALUETYPE = v2f16, - LAST_FP_VECTOR_VALUETYPE = v4f64, + LAST_FP_VECTOR_VALUETYPE = v8f64, - x86mmx = 43, // This is an X86 MMX value + FIRST_VECTOR_VALUETYPE = v2i1, + LAST_VECTOR_VALUETYPE = v8f64, + + x86mmx = 49, // This is an X86 MMX value - Glue = 44, // This glues nodes together during pre-RA sched + Glue = 50, // This glues nodes together during pre-RA sched - isVoid = 45, // This has no value + isVoid = 51, // This has no value - Untyped = 46, // This value takes a register, but has + Untyped = 52, // This value takes a register, but has // unspecified type. The register class // will be determined by the opcode. - LAST_VALUETYPE = 47, // This always remains at the end of the list. + LAST_VALUETYPE = 53, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors @@ -137,14 +150,7 @@ namespace llvm { // iPTR - An int value the size of the pointer of the current // target. This should only be used internal to tblgen! - iPTR = 255, - - // LastSimpleValueType - The greatest valid SimpleValueType value. - LastSimpleValueType = 255, - - // INVALID_SIMPLE_VALUE_TYPE - Simple value types greater than or equal - // to this are considered extended value types. - INVALID_SIMPLE_VALUE_TYPE = LastSimpleValueType + 1 + iPTR = 255 }; SimpleValueType SimpleTy; @@ -216,7 +222,9 @@ namespace llvm { /// is512BitVector - Return true if this is a 512-bit vector type. bool is512BitVector() const { - return (SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); + return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 || + SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 || + SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); } /// is1024BitVector - Return true if this is a 1024-bit vector type. @@ -254,17 +262,21 @@ namespace llvm { case v2i1 : case v4i1 : case v8i1 : - case v16i1: return i1; + case v16i1 : + case v32i1 : + case v64i1: return i1; case v2i8 : case v4i8 : case v8i8 : case v16i8: - case v32i8: return i8; + case v32i8: + case v64i8: return i8; case v1i16: case v2i16: case v4i16: case v8i16: - case v16i16: return i16; + case v16i16: + case v32i16: return i16; case v1i32: case v2i32: case v4i32: @@ -278,9 +290,11 @@ namespace llvm { case v2f16: return f16; case v2f32: case v4f32: - case v8f32: return f32; + case v8f32: + case v16f32: return f32; case v2f64: - case v4f64: return f64; + case v4f64: + case v8f64: return f64; } } @@ -288,18 +302,24 @@ namespace llvm { switch (SimpleTy) { default: llvm_unreachable("Not a vector MVT!"); - case v32i8: return 32; + case v32i1: + case v32i8: + case v32i16: return 32; + case v64i1: + case v64i8: return 64; case v16i1: case v16i8: case v16i16: case v16i32: - case v16i64:return 16; - case v8i1: + case v16i64: + case v16f32: return 16; + case v8i1 : case v8i8 : case v8i16: case v8i32: case v8i64: - case v8f32: return 8; + case v8f32: + case v8f64: return 8; case v4i1: case v4i8: case v4i16: @@ -328,7 +348,10 @@ namespace llvm { case iPTRAny: case iAny: case fAny: + case vAny: llvm_unreachable("Value type is overloaded."); + case Metadata: + llvm_unreachable("Value type is metadata."); default: llvm_unreachable("getSizeInBits called on extended MVT."); case i1 : return 1; @@ -343,13 +366,15 @@ namespace llvm { case v1i16: return 16; case f32 : case i32 : + case v32i1: case v4i8: case v2i16: - case v2f16: + case v2f16: case v1i32: return 32; case x86mmx: case f64 : case i64 : + case v64i1: case v8i8: case v4i16: case v2i32: @@ -371,8 +396,12 @@ namespace llvm { case v4i64: case v8f32: case v4f64: return 256; + case v64i8: + case v32i16: case v16i32: - case v8i64: return 512; + case v8i64: + case v16f32: + case v8f64: return 512; case v16i64:return 1024; } } @@ -389,6 +418,27 @@ namespace llvm { return getStoreSize() * 8; } + /// Return true if this has more bits than VT. + bool bitsGT(MVT VT) const { + return getSizeInBits() > VT.getSizeInBits(); + } + + /// Return true if this has no less bits than VT. + bool bitsGE(MVT VT) const { + return getSizeInBits() >= VT.getSizeInBits(); + } + + /// Return true if this has less bits than VT. + bool bitsLT(MVT VT) const { + return getSizeInBits() < VT.getSizeInBits(); + } + + /// Return true if this has no more bits than VT. + bool bitsLE(MVT VT) const { + return getSizeInBits() <= VT.getSizeInBits(); + } + + static MVT getFloatingPointVT(unsigned BitWidth) { switch (BitWidth) { default: @@ -434,6 +484,8 @@ namespace llvm { if (NumElements == 4) return MVT::v4i1; if (NumElements == 8) return MVT::v8i1; if (NumElements == 16) return MVT::v16i1; + if (NumElements == 32) return MVT::v32i1; + if (NumElements == 64) return MVT::v64i1; break; case MVT::i8: if (NumElements == 2) return MVT::v2i8; @@ -441,6 +493,7 @@ namespace llvm { if (NumElements == 8) return MVT::v8i8; if (NumElements == 16) return MVT::v16i8; if (NumElements == 32) return MVT::v32i8; + if (NumElements == 64) return MVT::v64i8; break; case MVT::i16: if (NumElements == 1) return MVT::v1i16; @@ -448,6 +501,7 @@ namespace llvm { if (NumElements == 4) return MVT::v4i16; if (NumElements == 8) return MVT::v8i16; if (NumElements == 16) return MVT::v16i16; + if (NumElements == 32) return MVT::v32i16; break; case MVT::i32: if (NumElements == 1) return MVT::v1i32; @@ -470,14 +524,22 @@ namespace llvm { if (NumElements == 2) return MVT::v2f32; if (NumElements == 4) return MVT::v4f32; if (NumElements == 8) return MVT::v8f32; + if (NumElements == 16) return MVT::v16f32; break; case MVT::f64: if (NumElements == 2) return MVT::v2f64; if (NumElements == 4) return MVT::v4f64; + if (NumElements == 8) return MVT::v8f64; break; } return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); } + + /// Return the value type corresponding to the specified type. This returns + /// all pointers as iPTR. If HandleUnknown is true, unknown types are + /// returned as Other, otherwise they are invalid. + static MVT getVT(Type *Ty, bool HandleUnknown = false); + }; @@ -501,7 +563,7 @@ namespace llvm { bool operator!=(EVT VT) const { if (V.SimpleTy != VT.V.SimpleTy) return true; - if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) + if (V.SimpleTy < 0) return LLVMTy != VT.LLVMTy; return false; } @@ -517,7 +579,7 @@ namespace llvm { /// number of bits. static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { MVT M = MVT::getIntegerVT(BitWidth); - if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) + if (M.SimpleTy >= 0) return M; return getExtendedIntegerVT(Context, BitWidth); } @@ -526,7 +588,7 @@ namespace llvm { /// length, where each element is of type VT. static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) { MVT M = MVT::getVectorVT(VT.V, NumElements); - if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) + if (M.SimpleTy >= 0) return M; return getExtendedVectorVT(Context, VT, NumElements); } @@ -541,7 +603,7 @@ namespace llvm { unsigned BitWidth = EltTy.getSizeInBits(); MVT IntTy = MVT::getIntegerVT(BitWidth); MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); - assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE && + assert(VecTy.SimpleTy >= 0 && "Simple vector VT not representable by simple integer vector VT!"); return VecTy; } @@ -549,7 +611,7 @@ namespace llvm { /// isSimple - Test if the given EVT is simple (as opposed to being /// extended). bool isSimple() const { - return V.SimpleTy <= MVT::LastSimpleValueType; + return V.SimpleTy >= 0; } /// isExtended - Test if the given EVT is extended (as opposed to @@ -765,7 +827,7 @@ namespace llvm { /// types are returned as Other, otherwise they are invalid. static EVT getEVT(Type *Ty, bool HandleUnknown = false); - intptr_t getRawBits() { + intptr_t getRawBits() const { if (isSimple()) return V.SimpleTy; else diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td index a707f88..76df6ac 100644 --- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td @@ -37,39 +37,45 @@ def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value def v16i1 : ValueType<16, 16>; // 16 x i1 vector value -def v2i8 : ValueType<16 , 17>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 18>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 19>; // 8 x i8 vector value -def v16i8 : ValueType<128, 20>; // 16 x i8 vector value -def v32i8 : ValueType<256, 21>; // 32 x i8 vector value -def v1i16 : ValueType<16 , 22>; // 1 x i16 vector value -def v2i16 : ValueType<32 , 23>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 24>; // 4 x i16 vector value -def v8i16 : ValueType<128, 25>; // 8 x i16 vector value -def v16i16 : ValueType<256, 26>; // 16 x i16 vector value -def v1i32 : ValueType<32 , 27>; // 1 x i32 vector value -def v2i32 : ValueType<64 , 28>; // 2 x i32 vector value -def v4i32 : ValueType<128, 29>; // 4 x i32 vector value -def v8i32 : ValueType<256, 30>; // 8 x i32 vector value -def v16i32 : ValueType<512, 31>; // 16 x i32 vector value -def v1i64 : ValueType<64 , 32>; // 1 x i64 vector value -def v2i64 : ValueType<128, 33>; // 2 x i64 vector value -def v4i64 : ValueType<256, 34>; // 4 x i64 vector value -def v8i64 : ValueType<512, 35>; // 8 x i64 vector value -def v16i64 : ValueType<1024,36>; // 16 x i64 vector value +def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value +def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value +def v2i8 : ValueType<16 , 19>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 20>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 21>; // 8 x i8 vector value +def v16i8 : ValueType<128, 22>; // 16 x i8 vector value +def v32i8 : ValueType<256, 23>; // 32 x i8 vector value +def v64i8 : ValueType<256, 24>; // 64 x i8 vector value +def v1i16 : ValueType<16 , 25>; // 1 x i16 vector value +def v2i16 : ValueType<32 , 26>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 27>; // 4 x i16 vector value +def v8i16 : ValueType<128, 28>; // 8 x i16 vector value +def v16i16 : ValueType<256, 29>; // 16 x i16 vector value +def v32i16 : ValueType<256, 30>; // 32 x i16 vector value +def v1i32 : ValueType<32 , 31>; // 1 x i32 vector value +def v2i32 : ValueType<64 , 32>; // 2 x i32 vector value +def v4i32 : ValueType<128, 33>; // 4 x i32 vector value +def v8i32 : ValueType<256, 34>; // 8 x i32 vector value +def v16i32 : ValueType<512, 35>; // 16 x i32 vector value +def v1i64 : ValueType<64 , 36>; // 1 x i64 vector value +def v2i64 : ValueType<128, 37>; // 2 x i64 vector value +def v4i64 : ValueType<256, 38>; // 4 x i64 vector value +def v8i64 : ValueType<512, 39>; // 8 x i64 vector value +def v16i64 : ValueType<1024,40>; // 16 x i64 vector value -def v2f16 : ValueType<32 , 37>; // 2 x f16 vector value -def v2f32 : ValueType<64 , 38>; // 2 x f32 vector value -def v4f32 : ValueType<128, 39>; // 4 x f32 vector value -def v8f32 : ValueType<256, 40>; // 8 x f32 vector value -def v2f64 : ValueType<128, 41>; // 2 x f64 vector value -def v4f64 : ValueType<256, 42>; // 4 x f64 vector value +def v2f16 : ValueType<32 , 41>; // 2 x f16 vector value +def v2f32 : ValueType<64 , 42>; // 2 x f32 vector value +def v4f32 : ValueType<128, 43>; // 4 x f32 vector value +def v8f32 : ValueType<256, 44>; // 8 x f32 vector value +def v16f32 : ValueType<512, 45>; // 16 x f32 vector value +def v2f64 : ValueType<128, 46>; // 2 x f64 vector value +def v4f64 : ValueType<256, 47>; // 4 x f64 vector value +def v8f64 : ValueType<512, 48>; // 8 x f64 vector value -def x86mmx : ValueType<64 , 43>; // X86 MMX value -def FlagVT : ValueType<0 , 44>; // Pre-RA sched glue -def isVoid : ValueType<0 , 45>; // Produces no value -def untyped: ValueType<8 , 46>; // Produces an untyped value +def x86mmx : ValueType<64 , 49>; // X86 MMX value +def FlagVT : ValueType<0 , 50>; // Pre-RA sched glue +def isVoid : ValueType<0 , 51>; // Produces no value +def untyped: ValueType<8 , 52>; // Produces an untyped value def MetadataVT: ValueType<0, 250>; // Metadata // Pseudo valuetype mapped to the current pointer size to any address space. diff --git a/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h b/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h new file mode 100644 index 0000000..3bc6ebd --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/VirtRegMap.h @@ -0,0 +1,190 @@ +//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a virtual register map. This maps virtual registers to +// physical registers and virtual registers to stack slots. It is created and +// updated by a register allocator and then used by a machine code rewriter that +// adds spill code and rewrites virtual into physical register references. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_VIRTREGMAP_H +#define LLVM_CODEGEN_VIRTREGMAP_H + +#include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetRegisterInfo.h" + +namespace llvm { + class MachineInstr; + class MachineFunction; + class MachineRegisterInfo; + class TargetInstrInfo; + class raw_ostream; + class SlotIndexes; + + class VirtRegMap : public MachineFunctionPass { + public: + enum { + NO_PHYS_REG = 0, + NO_STACK_SLOT = (1L << 30)-1, + MAX_STACK_SLOT = (1L << 18)-1 + }; + + private: + MachineRegisterInfo *MRI; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineFunction *MF; + + /// Virt2PhysMap - This is a virtual to physical register + /// mapping. Each virtual register is required to have an entry in + /// it; even spilled virtual registers (the register mapped to a + /// spilled register is the temporary used to load it from the + /// stack). + IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap; + + /// Virt2StackSlotMap - This is virtual register to stack slot + /// mapping. Each spilled virtual register has an entry in it + /// which corresponds to the stack slot this register is spilled + /// at. + IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap; + + /// Virt2SplitMap - This is virtual register to splitted virtual register + /// mapping. + IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap; + + /// createSpillSlot - Allocate a spill slot for RC from MFI. + unsigned createSpillSlot(const TargetRegisterClass *RC); + + VirtRegMap(const VirtRegMap&) LLVM_DELETED_FUNCTION; + void operator=(const VirtRegMap&) LLVM_DELETED_FUNCTION; + + public: + static char ID; + VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG), + Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { } + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + MachineFunction &getMachineFunction() const { + assert(MF && "getMachineFunction called before runOnMachineFunction"); + return *MF; + } + + MachineRegisterInfo &getRegInfo() const { return *MRI; } + const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } + + void grow(); + + /// @brief returns true if the specified virtual register is + /// mapped to a physical register + bool hasPhys(unsigned virtReg) const { + return getPhys(virtReg) != NO_PHYS_REG; + } + + /// @brief returns the physical register mapped to the specified + /// virtual register + unsigned getPhys(unsigned virtReg) const { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2PhysMap[virtReg]; + } + + /// @brief creates a mapping for the specified virtual register to + /// the specified physical register + void assignVirt2Phys(unsigned virtReg, unsigned physReg) { + assert(TargetRegisterInfo::isVirtualRegister(virtReg) && + TargetRegisterInfo::isPhysicalRegister(physReg)); + assert(Virt2PhysMap[virtReg] == NO_PHYS_REG && + "attempt to assign physical register to already mapped " + "virtual register"); + Virt2PhysMap[virtReg] = physReg; + } + + /// @brief clears the specified virtual register's, physical + /// register mapping + void clearVirt(unsigned virtReg) { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + assert(Virt2PhysMap[virtReg] != NO_PHYS_REG && + "attempt to clear a not assigned virtual register"); + Virt2PhysMap[virtReg] = NO_PHYS_REG; + } + + /// @brief clears all virtual to physical register mappings + void clearAllVirt() { + Virt2PhysMap.clear(); + grow(); + } + + /// @brief returns true if VirtReg is assigned to its preferred physreg. + bool hasPreferredPhys(unsigned VirtReg); + + /// @brief returns true if VirtReg has a known preferred register. + /// This returns false if VirtReg has a preference that is a virtual + /// register that hasn't been assigned yet. + bool hasKnownPreference(unsigned VirtReg); + + /// @brief records virtReg is a split live interval from SReg. + void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { + Virt2SplitMap[virtReg] = SReg; + } + + /// @brief returns the live interval virtReg is split from. + unsigned getPreSplitReg(unsigned virtReg) const { + return Virt2SplitMap[virtReg]; + } + + /// getOriginal - Return the original virtual register that VirtReg descends + /// from through splitting. + /// A register that was not created by splitting is its own original. + /// This operation is idempotent. + unsigned getOriginal(unsigned VirtReg) const { + unsigned Orig = getPreSplitReg(VirtReg); + return Orig ? Orig : VirtReg; + } + + /// @brief returns true if the specified virtual register is not + /// mapped to a stack slot or rematerialized. + bool isAssignedReg(unsigned virtReg) const { + if (getStackSlot(virtReg) == NO_STACK_SLOT) + return true; + // Split register can be assigned a physical register as well as a + // stack slot or remat id. + return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG); + } + + /// @brief returns the stack slot mapped to the specified virtual + /// register + int getStackSlot(unsigned virtReg) const { + assert(TargetRegisterInfo::isVirtualRegister(virtReg)); + return Virt2StackSlotMap[virtReg]; + } + + /// @brief create a mapping for the specifed virtual register to + /// the next available stack slot + int assignVirt2StackSlot(unsigned virtReg); + /// @brief create a mapping for the specified virtual register to + /// the specified stack slot + void assignVirt2StackSlot(unsigned virtReg, int frameIndex); + + void print(raw_ostream &OS, const Module* M = 0) const; + void dump() const; + }; + + inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) { + VRM.print(OS); + return OS; + } +} // End llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/DIBuilder.h b/contrib/llvm/include/llvm/DIBuilder.h index 2f07800..4f0aa07 100644 --- a/contrib/llvm/include/llvm/DIBuilder.h +++ b/contrib/llvm/include/llvm/DIBuilder.h @@ -12,12 +12,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_DIBUILDER_H -#define LLVM_ANALYSIS_DIBUILDER_H +#ifndef LLVM_DIBUILDER_H +#define LLVM_DIBUILDER_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class BasicBlock; @@ -28,6 +28,9 @@ namespace llvm { class LLVMContext; class MDNode; class StringRef; + class DIBasicType; + class DICompositeType; + class DIDerivedType; class DIDescriptor; class DIFile; class DIEnumerator; @@ -88,9 +91,12 @@ namespace llvm { /// by a tool analyzing generated debugging information. /// @param RV This indicates runtime version for languages like /// Objective-C. + /// @param SplitName The name of the file that we'll split debug info out + /// into. void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir, - StringRef Producer, - bool isOptimized, StringRef Flags, unsigned RV); + StringRef Producer, bool isOptimized, + StringRef Flags, unsigned RV, + StringRef SplitName = StringRef()); /// createFile - Create a file descriptor to hold debugging information /// for a file. @@ -108,27 +114,32 @@ namespace llvm { /// @param SizeInBits Size of the type. /// @param AlignInBits Type alignment. /// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float. - DIType createBasicType(StringRef Name, uint64_t SizeInBits, - uint64_t AlignInBits, unsigned Encoding); + DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits, + uint64_t AlignInBits, unsigned Encoding); /// createQualifiedType - Create debugging information entry for a qualified /// type, e.g. 'const int'. /// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type /// @param FromTy Base Type. - DIType createQualifiedType(unsigned Tag, DIType FromTy); + DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy); /// createPointerType - Create debugging information entry for a pointer. /// @param PointeeTy Type pointed by this pointer. /// @param SizeInBits Size. /// @param AlignInBits Alignment. (optional) /// @param Name Pointer type name. (optional) - DIType createPointerType(DIType PointeeTy, uint64_t SizeInBits, - uint64_t AlignInBits = 0, - StringRef Name = StringRef()); + DIDerivedType + createPointerType(DIType PointeeTy, uint64_t SizeInBits, + uint64_t AlignInBits = 0, StringRef Name = StringRef()); + + /// \brief Create debugging information entry for a pointer to member. + /// @param PointeeTy Type pointed to by this pointer. + /// @param Class Type for which this pointer points to members of. + DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class); /// createReferenceType - Create debugging information entry for a c++ /// style reference or rvalue reference type. - DIType createReferenceType(unsigned Tag, DIType RTy); + DIDerivedType createReferenceType(unsigned Tag, DIType RTy); /// createTypedef - Create debugging information entry for a typedef. /// @param Ty Original type. @@ -136,8 +147,8 @@ namespace llvm { /// @param File File where this type is defined. /// @param LineNo Line number. /// @param Context The surrounding context for the typedef. - DIType createTypedef(DIType Ty, StringRef Name, DIFile File, - unsigned LineNo, DIDescriptor Context); + DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File, + unsigned LineNo, DIDescriptor Context); /// createFriend - Create debugging information entry for a 'friend'. DIType createFriend(DIType Ty, DIType FriendTy); @@ -149,8 +160,8 @@ namespace llvm { /// @param BaseOffset Base offset. /// @param Flags Flags to describe inheritance attribute, /// e.g. private - DIType createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset, - unsigned Flags); + DIDerivedType createInheritance(DIType Ty, DIType BaseTy, + uint64_t BaseOffset, unsigned Flags); /// createMemberType - Create debugging information entry for a member. /// @param Scope Member scope. @@ -162,10 +173,23 @@ namespace llvm { /// @param OffsetInBits Member offset. /// @param Flags Flags to encode member attribute, e.g. private /// @param Ty Parent type. - DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNo, uint64_t SizeInBits, - uint64_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, DIType Ty); + DIDerivedType + createMemberType(DIDescriptor Scope, StringRef Name, DIFile File, + unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, DIType Ty); + + /// createStaticMemberType - Create debugging information entry for a + /// C++ static data member. + /// @param Scope Member scope. + /// @param Name Member name. + /// @param File File where this member is declared. + /// @param LineNo Line number. + /// @param Ty Type of the static member. + /// @param Flags Flags to encode member attribute, e.g. private. + /// @param Val Const initializer of the member. + DIType createStaticMemberType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNo, DIType Ty, + unsigned Flags, llvm::Value *Val); /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. @@ -241,12 +265,13 @@ namespace llvm { /// DW_AT_containing_type. See DWARF documentation /// for more info. /// @param TemplateParms Template type parameters. - DIType createClassType(DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNumber, uint64_t SizeInBits, - uint64_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, DIType DerivedFrom, - DIArray Elements, MDNode *VTableHolder = 0, - MDNode *TemplateParms = 0); + DICompositeType createClassType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType DerivedFrom, DIArray Elements, + MDNode *VTableHolder = 0, + MDNode *TemplateParms = 0); /// createStructType - Create debugging information entry for a struct. /// @param Scope Scope in which this struct is defined. @@ -258,10 +283,12 @@ namespace llvm { /// @param Flags Flags to encode member attribute, e.g. private /// @param Elements Struct elements. /// @param RunTimeLang Optional parameter, Objective-C runtime version. - DIType createStructType(DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNumber, uint64_t SizeInBits, - uint64_t AlignInBits, unsigned Flags, - DIArray Elements, unsigned RunTimeLang = 0); + DICompositeType createStructType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, + unsigned Flags, DIType DerivedFrom, + DIArray Elements, unsigned RunTimeLang = 0, + MDNode *VTableHolder = 0); /// createUnionType - Create debugging information entry for an union. /// @param Scope Scope in which this union is defined. @@ -273,10 +300,10 @@ namespace llvm { /// @param Flags Flags to encode member attribute, e.g. private /// @param Elements Union elements. /// @param RunTimeLang Optional parameter, Objective-C runtime version. - DIType createUnionType(DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNumber, uint64_t SizeInBits, - uint64_t AlignInBits, unsigned Flags, - DIArray Elements, unsigned RunTimeLang = 0); + DICompositeType createUnionType( + DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, + DIArray Elements, unsigned RunTimeLang = 0); /// createTemplateTypeParameter - Create debugging information for template /// type parameter. @@ -311,8 +338,8 @@ namespace llvm { /// @param AlignInBits Alignment. /// @param Ty Element type. /// @param Subscripts Subscripts. - DIType createArrayType(uint64_t Size, uint64_t AlignInBits, - DIType Ty, DIArray Subscripts); + DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits, + DIType Ty, DIArray Subscripts); /// createVectorType - Create debugging information entry for a vector type. /// @param Size Array size. @@ -331,16 +358,16 @@ namespace llvm { /// @param SizeInBits Member size. /// @param AlignInBits Member alignment. /// @param Elements Enumeration elements. - DIType createEnumerationType(DIDescriptor Scope, StringRef Name, - DIFile File, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - DIArray Elements, DIType ClassType); + DICompositeType createEnumerationType( + DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, + DIType ClassType); /// createSubroutineType - Create subroutine type. /// @param File File in which this subroutine is defined. /// @param ParameterTypes An array of subroutine parameter types. This /// includes return type at 0th index. - DIType createSubroutineType(DIFile File, DIArray ParameterTypes); + DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes); /// createArtificialType - Create a new DIType with "artificial" flag set. DIType createArtificialType(DIType Ty); @@ -349,10 +376,6 @@ namespace llvm { /// flag set. DIType createObjectPointerType(DIType Ty); - /// createTemporaryType - Create a temporary forward-declared type. - DIType createTemporaryType(); - DIType createTemporaryType(DIFile F); - /// createForwardDecl - Create a temporary forward-declared type. DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang = 0, @@ -371,7 +394,7 @@ namespace llvm { /// getOrCreateSubrange - Create a descriptor for a value range. This /// implicitly uniques the values returned. - DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi); + DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count); /// createGlobalVariable - Create a new descriptor for the specified global. /// @param Name Name of the variable. @@ -385,6 +408,19 @@ namespace llvm { createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo, DIType Ty, bool isLocalToUnit, llvm::Value *Val); + /// \brief Create a new descriptor for the specified global. + /// @param Name Name of the variable. + /// @param LinkageName Mangled variable name. + /// @param File File where this variable is defined. + /// @param LineNo Line number. + /// @param Ty Variable Type. + /// @param isLocalToUnit Boolean flag indicate whether this variable is + /// externally visible or not. + /// @param Val llvm::Value of the variable. + DIGlobalVariable + createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File, + unsigned LineNo, DIType Ty, bool isLocalToUnit, + llvm::Value *Val); /// createStaticVariable - Create a new descriptor for the specified /// variable. @@ -397,10 +433,12 @@ namespace llvm { /// @param isLocalToUnit Boolean flag indicate whether this variable is /// externally visible or not. /// @param Val llvm::Value of the variable. + /// @param Decl Reference to the corresponding declaration. DIGlobalVariable createStaticVariable(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, - DIType Ty, bool isLocalToUnit, llvm::Value *Val); + DIType Ty, bool isLocalToUnit, llvm::Value *Val, + MDNode *Decl = NULL); /// createLocalVariable - Create a new descriptor for the specified diff --git a/contrib/llvm/include/llvm/DebugInfo.h b/contrib/llvm/include/llvm/DebugInfo.h index dae03ad..15f9187 100644 --- a/contrib/llvm/include/llvm/DebugInfo.h +++ b/contrib/llvm/include/llvm/DebugInfo.h @@ -14,11 +14,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_DEBUGINFO_H -#define LLVM_ANALYSIS_DEBUGINFO_H +#ifndef LLVM_DEBUGINFO_H +#define LLVM_DEBUGINFO_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Dwarf.h" @@ -61,7 +61,9 @@ namespace llvm { FlagExplicit = 1 << 7, FlagPrototyped = 1 << 8, FlagObjcClassComplete = 1 << 9, - FlagObjectPointer = 1 << 10 + FlagObjectPointer = 1 << 10, + FlagVector = 1 << 11, + FlagStaticMember = 1 << 12 }; protected: const MDNode *DbgNode; @@ -71,6 +73,7 @@ namespace llvm { return (unsigned)getUInt64Field(Elt); } uint64_t getUInt64Field(unsigned Elt) const; + int64_t getInt64Field(unsigned Elt) const; DIDescriptor getDescriptorField(unsigned Elt) const; template <typename DescTy> @@ -93,15 +96,11 @@ namespace llvm { explicit DIDescriptor(const DIVariable F); explicit DIDescriptor(const DIType F); - bool Verify() const { return DbgNode != 0; } + bool Verify() const; operator MDNode *() const { return const_cast<MDNode*>(DbgNode); } MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); } - unsigned getVersion() const { - return getUnsignedField(0) & LLVMDebugVersionMask; - } - unsigned getTag() const { return getUnsignedField(0) & ~LLVMDebugVersionMask; } @@ -141,8 +140,9 @@ namespace llvm { public: explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {} - uint64_t getLo() const { return getUInt64Field(1); } - uint64_t getHi() const { return getUInt64Field(2); } + int64_t getLo() const { return getInt64Field(1); } + int64_t getCount() const { return getInt64Field(2); } + bool Verify() const; }; /// DIArray - This descriptor holds an array of descriptors. @@ -169,6 +169,18 @@ namespace llvm { StringRef getDirectory() const; }; + /// DIFile - This is a wrapper for a file. + class DIFile : public DIScope { + friend class DIDescriptor; + public: + explicit DIFile(const MDNode *N = 0) : DIScope(N) { + if (DbgNode && !isFile()) + DbgNode = 0; + } + MDNode *getFileNode() const; + bool Verify() const; + }; + /// DICompileUnit - A wrapper for a compile unit. class DICompileUnit : public DIScope { friend class DIDescriptor; @@ -176,51 +188,24 @@ namespace llvm { public: explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} - unsigned getLanguage() const { return getUnsignedField(2); } - StringRef getFilename() const { return getStringField(3); } - StringRef getDirectory() const { return getStringField(4); } - StringRef getProducer() const { return getStringField(5); } - - /// isMain - Each input file is encoded as a separate compile unit in LLVM - /// debugging information output. However, many target specific tool chains - /// prefer to encode only one compile unit in an object file. In this - /// situation, the LLVM code generator will include debugging information - /// entities in the compile unit that is marked as main compile unit. The - /// code generator accepts maximum one main compile unit per module. If a - /// module does not contain any main compile unit then the code generator - /// will emit multiple compile units in the output object file. - - bool isMain() const { return getUnsignedField(6) != 0; } - bool isOptimized() const { return getUnsignedField(7) != 0; } - StringRef getFlags() const { return getStringField(8); } - unsigned getRunTimeVersion() const { return getUnsignedField(9); } + unsigned getLanguage() const { return getUnsignedField(2); } + StringRef getProducer() const { return getStringField(3); } + + bool isOptimized() const { return getUnsignedField(4) != 0; } + StringRef getFlags() const { return getStringField(5); } + unsigned getRunTimeVersion() const { return getUnsignedField(6); } DIArray getEnumTypes() const; DIArray getRetainedTypes() const; DIArray getSubprograms() const; DIArray getGlobalVariables() const; + StringRef getSplitDebugFilename() const { return getStringField(11); } + /// Verify - Verify that a compile unit is well formed. bool Verify() const; }; - /// DIFile - This is a wrapper for a file. - class DIFile : public DIScope { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const {} // FIXME: Output something? - public: - explicit DIFile(const MDNode *N = 0) : DIScope(N) { - if (DbgNode && !isFile()) - DbgNode = 0; - } - StringRef getFilename() const { return getStringField(1); } - StringRef getDirectory() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); - return getFieldAs<DICompileUnit>(3); - } - }; - /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). /// FIXME: it seems strange that this doesn't have either a reference to the /// type/precision or a file/line pair for location info. @@ -232,6 +217,7 @@ namespace llvm { StringRef getName() const { return getStringField(1); } uint64_t getEnumValue() const { return getUInt64Field(2); } + bool Verify() const; }; /// DIType - This is a wrapper for a type. @@ -250,16 +236,8 @@ namespace llvm { explicit DIType(const MDNode *N); explicit DIType() {} - DIScope getContext() const { return getFieldAs<DIScope>(1); } - StringRef getName() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs<DICompileUnit>(3); - - return getFieldAs<DIFile>(3).getCompileUnit(); - } - DIFile getFile() const { return getFieldAs<DIFile>(3); } + DIScope getContext() const { return getFieldAs<DIScope>(2); } + StringRef getName() const { return getStringField(3); } unsigned getLineNumber() const { return getUnsignedField(4); } uint64_t getSizeInBits() const { return getUInt64Field(5); } uint64_t getAlignInBits() const { return getUInt64Field(6); } @@ -295,20 +273,14 @@ namespace llvm { bool isObjcClassComplete() const { return (getFlags() & FlagObjcClassComplete) != 0; } - bool isValid() const { - return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); + bool isVector() const { + return (getFlags() & FlagVector) != 0; } - StringRef getDirectory() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getDirectory(); - - return getFieldAs<DIFile>(3).getDirectory(); + bool isStaticMember() const { + return (getFlags() & FlagStaticMember) != 0; } - StringRef getFilename() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs<DIFile>(3).getFilename(); + bool isValid() const { + return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); } /// isUnsignedDIType - Return true if type encoding is unsigned. @@ -332,7 +304,8 @@ namespace llvm { }; /// DIDerivedType - A simple derived type, like a const qualified type, - /// a typedef, a pointer or reference, etc. + /// a typedef, a pointer or reference, et cetera. Or, a data member of + /// a class/struct/union. class DIDerivedType : public DIType { friend class DIDescriptor; void printInternal(raw_ostream &OS) const; @@ -349,46 +322,18 @@ namespace llvm { /// return base type size. uint64_t getOriginalTypeSize() const; - /// getObjCProperty - Return property node, if this ivar is + /// getObjCProperty - Return property node, if this ivar is /// associated with one. MDNode *getObjCProperty() const; - StringRef getObjCPropertyName() const { - if (getVersion() > LLVMDebugVersion11) - return StringRef(); - return getStringField(10); - } - StringRef getObjCPropertyGetterName() const { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return getStringField(11); - } - StringRef getObjCPropertySetterName() const { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return getStringField(12); - } - bool isReadOnlyObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; - } - bool isReadWriteObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; - } - bool isAssignObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; - } - bool isRetainObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; - } - bool isCopyObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; + DIType getClassType() const { + assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); + return getFieldAs<DIType>(10); } - bool isNonAtomicObjCProperty() { - assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request"); - return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; + + Constant *getConstant() const { + assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); + return getConstantField(10); } /// Verify - Verify that a derived type descriptor is well formed. @@ -409,10 +354,12 @@ namespace llvm { } DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } + void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); unsigned getRunTimeLang() const { return getUnsignedField(11); } DICompositeType getContainingType() const { return getFieldAs<DICompositeType>(12); } + void setContainingType(DICompositeType ContainingType); DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } /// Verify - Verify that a composite type descriptor is well formed. @@ -427,14 +374,15 @@ namespace llvm { DIScope getContext() const { return getFieldAs<DIScope>(1); } StringRef getName() const { return getStringField(2); } DIType getType() const { return getFieldAs<DIType>(3); } - StringRef getFilename() const { + StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); } - StringRef getDirectory() const { + StringRef getDirectory() const { return getFieldAs<DIFile>(4).getDirectory(); } unsigned getLineNumber() const { return getUnsignedField(5); } unsigned getColumnNumber() const { return getUnsignedField(6); } + bool Verify() const; }; /// DITemplateValueParameter - This is a wrapper for template value parameter. @@ -446,14 +394,15 @@ namespace llvm { StringRef getName() const { return getStringField(2); } DIType getType() const { return getFieldAs<DIType>(3); } uint64_t getValue() const { return getUInt64Field(4); } - StringRef getFilename() const { + StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); } - StringRef getDirectory() const { + StringRef getDirectory() const { return getFieldAs<DIFile>(5).getDirectory(); } unsigned getLineNumber() const { return getUnsignedField(6); } unsigned getColumnNumber() const { return getUnsignedField(7); } + bool Verify() const; }; /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). @@ -467,93 +416,66 @@ namespace llvm { StringRef getName() const { return getStringField(3); } StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs<DICompileUnit>(6); - - return getFieldAs<DIFile>(6).getCompileUnit(); - } - unsigned getLineNumber() const { return getUnsignedField(7); } - DICompositeType getType() const { return getFieldAs<DICompositeType>(8); } + unsigned getLineNumber() const { return getUnsignedField(6); } + DICompositeType getType() const { return getFieldAs<DICompositeType>(7); } /// getReturnTypeName - Subprogram return types are encoded either as /// DIType or as DICompositeType. StringRef getReturnTypeName() const { - DICompositeType DCT(getFieldAs<DICompositeType>(8)); + DICompositeType DCT(getFieldAs<DICompositeType>(7)); if (DCT.Verify()) { DIArray A = DCT.getTypeArray(); DIType T(A.getElement(0)); return T.getName(); } - DIType T(getFieldAs<DIType>(8)); + DIType T(getFieldAs<DIType>(7)); return T.getName(); } /// isLocalToUnit - Return true if this subprogram is local to the current /// compile unit, like 'static' in C. - unsigned isLocalToUnit() const { return getUnsignedField(9); } - unsigned isDefinition() const { return getUnsignedField(10); } + unsigned isLocalToUnit() const { return getUnsignedField(8); } + unsigned isDefinition() const { return getUnsignedField(9); } - unsigned getVirtuality() const { return getUnsignedField(11); } - unsigned getVirtualIndex() const { return getUnsignedField(12); } + unsigned getVirtuality() const { return getUnsignedField(10); } + unsigned getVirtualIndex() const { return getUnsignedField(11); } DICompositeType getContainingType() const { - return getFieldAs<DICompositeType>(13); + return getFieldAs<DICompositeType>(12); + } + + unsigned getFlags() const { + return getUnsignedField(13); } - unsigned isArtificial() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return getUnsignedField(14); - return (getUnsignedField(14) & FlagArtificial) != 0; + unsigned isArtificial() const { + return (getUnsignedField(13) & FlagArtificial) != 0; } /// isPrivate - Return true if this subprogram has "private" /// access specifier. - bool isPrivate() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagPrivate) != 0; + bool isPrivate() const { + return (getUnsignedField(13) & FlagPrivate) != 0; } /// isProtected - Return true if this subprogram has "protected" /// access specifier. - bool isProtected() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagProtected) != 0; + bool isProtected() const { + return (getUnsignedField(13) & FlagProtected) != 0; } /// isExplicit - Return true if this subprogram is marked as explicit. - bool isExplicit() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagExplicit) != 0; + bool isExplicit() const { + return (getUnsignedField(13) & FlagExplicit) != 0; } /// isPrototyped - Return true if this subprogram is prototyped. - bool isPrototyped() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; - return (getUnsignedField(14) & FlagPrototyped) != 0; + bool isPrototyped() const { + return (getUnsignedField(13) & FlagPrototyped) != 0; } unsigned isOptimized() const; - StringRef getFilename() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs<DIFile>(6).getFilename(); - } - - StringRef getDirectory() const { - if (getVersion() == llvm::LLVMDebugVersion7) - return getCompileUnit().getFilename(); - - return getFieldAs<DIFile>(6).getDirectory(); - } - /// getScopeLineNumber - Get the beginning of the scope of the /// function, not necessarily where the name of the program /// starts. - unsigned getScopeLineNumber() const { return getUnsignedField(20); } + unsigned getScopeLineNumber() const { return getUnsignedField(19); } /// Verify - Verify that a subprogram descriptor is well formed. bool Verify() const; @@ -562,11 +484,11 @@ namespace llvm { /// information for the function F. bool describes(const Function *F); - Function *getFunction() const { return getFunctionField(16); } - void replaceFunction(Function *F) { replaceFunctionField(16, F); } - DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); } + Function *getFunction() const { return getFunctionField(15); } + void replaceFunction(Function *F) { replaceFunctionField(15, F); } + DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); } DISubprogram getFunctionDeclaration() const { - return getFieldAs<DISubprogram>(18); + return getFieldAs<DISubprogram>(17); } MDNode *getVariablesNodes() const; DIArray getVariables() const; @@ -583,25 +505,13 @@ namespace llvm { StringRef getName() const { return getStringField(3); } StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs<DICompileUnit>(6); - - DIFile F = getFieldAs<DIFile>(6); - return F.getCompileUnit(); - } StringRef getFilename() const { - if (getVersion() <= llvm::LLVMDebugVersion10) - return getContext().getFilename(); return getFieldAs<DIFile>(6).getFilename(); - } + } StringRef getDirectory() const { - if (getVersion() <= llvm::LLVMDebugVersion10) - return getContext().getDirectory(); return getFieldAs<DIFile>(6).getDirectory(); - } + } unsigned getLineNumber() const { return getUnsignedField(7); } DIType getType() const { return getFieldAs<DIType>(8); } @@ -610,6 +520,9 @@ namespace llvm { GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } Constant *getConstant() const { return getConstantField(11); } + DIDerivedType getStaticDataMemberDeclaration() const { + return getFieldAs<DIDerivedType>(12); + } /// Verify - Verify that a global variable descriptor is well formed. bool Verify() const; @@ -626,27 +539,18 @@ namespace llvm { DIScope getContext() const { return getFieldAs<DIScope>(1); } StringRef getName() const { return getStringField(2); } - DICompileUnit getCompileUnit() const { - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs<DICompileUnit>(3); - - DIFile F = getFieldAs<DIFile>(3); - return F.getCompileUnit(); - } - unsigned getLineNumber() const { - return (getUnsignedField(4) << 8) >> 8; + DIFile getFile() const { return getFieldAs<DIFile>(3); } + unsigned getLineNumber() const { + return (getUnsignedField(4) << 8) >> 8; } unsigned getArgNumber() const { - unsigned L = getUnsignedField(4); + unsigned L = getUnsignedField(4); return L >> 24; } DIType getType() const { return getFieldAs<DIType>(5); } - + /// isArtificial - Return true if this variable is marked as "artificial". - bool isArtificial() const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return false; + bool isArtificial() const { return (getUnsignedField(6) & FlagArtificial) != 0; } @@ -666,12 +570,8 @@ namespace llvm { } unsigned getNumAddrElements() const; - + uint64_t getAddrElement(unsigned Idx) const { - if (getVersion() <= llvm::LLVMDebugVersion8) - return getUInt64Field(Idx+6); - if (getVersion() == llvm::LLVMDebugVersion9) - return getUInt64Field(Idx+7); return getUInt64Field(Idx+8); } @@ -681,7 +581,7 @@ namespace llvm { return getType().isBlockByrefStruct(); } - /// isInlinedFnArgument - Return trule if this variable provides debugging + /// isInlinedFnArgument - Return true if this variable provides debugging /// information for an inlined function arguments. bool isInlinedFnArgument(const Function *CurFn); @@ -692,17 +592,10 @@ namespace llvm { class DILexicalBlock : public DIScope { public: explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getFieldAs<DIScope>(1); } - unsigned getLineNumber() const { return getUnsignedField(2); } - unsigned getColumnNumber() const { return getUnsignedField(3); } - StringRef getDirectory() const { - StringRef dir = getFieldAs<DIFile>(4).getDirectory(); - return !dir.empty() ? dir : getContext().getDirectory(); - } - StringRef getFilename() const { - StringRef filename = getFieldAs<DIFile>(4).getFilename(); - return !filename.empty() ? filename : getContext().getFilename(); - } + DIScope getContext() const { return getFieldAs<DIScope>(2); } + unsigned getLineNumber() const { return getUnsignedField(3); } + unsigned getColumnNumber() const { return getUnsignedField(4); } + bool Verify() const; }; /// DILexicalBlockFile - This is a wrapper for a lexical block with @@ -710,40 +603,21 @@ namespace llvm { class DILexicalBlockFile : public DIScope { public: explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getScope().getContext(); } + DIScope getContext() const { if (getScope().isSubprogram()) return getScope(); return getScope().getContext(); } unsigned getLineNumber() const { return getScope().getLineNumber(); } unsigned getColumnNumber() const { return getScope().getColumnNumber(); } - StringRef getDirectory() const { - StringRef dir = getFieldAs<DIFile>(2).getDirectory(); - return !dir.empty() ? dir : getContext().getDirectory(); - } - StringRef getFilename() const { - StringRef filename = getFieldAs<DIFile>(2).getFilename(); - assert(!filename.empty() && "Why'd you create this then?"); - return filename; - } - DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); } + DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } + bool Verify() const; }; /// DINameSpace - A wrapper for a C++ style name space. - class DINameSpace : public DIScope { + class DINameSpace : public DIScope { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; public: explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getFieldAs<DIScope>(1); } - StringRef getName() const { return getStringField(2); } - StringRef getDirectory() const { - return getFieldAs<DIFile>(3).getDirectory(); - } - StringRef getFilename() const { - return getFieldAs<DIFile>(3).getFilename(); - } - DICompileUnit getCompileUnit() const{ - assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); - if (getVersion() == llvm::LLVMDebugVersion7) - return getFieldAs<DICompileUnit>(3); - - return getFieldAs<DIFile>(3).getCompileUnit(); - } + DIScope getContext() const { return getFieldAs<DIScope>(2); } + StringRef getName() const { return getStringField(3); } unsigned getLineNumber() const { return getUnsignedField(4); } bool Verify() const; }; @@ -818,7 +692,7 @@ namespace llvm { /// to hold function specific information. NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); - /// getFnSpecificMDNode - Return a NameMDNode, if available, that is + /// getFnSpecificMDNode - Return a NameMDNode, if available, that is /// suitable to hold function specific information. NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); @@ -836,7 +710,7 @@ namespace llvm { public: /// processModule - Process entire module and collect debug info /// anchors. - void processModule(Module &M); + void processModule(const Module &M); private: /// processType - Process DIType. @@ -849,7 +723,7 @@ namespace llvm { void processSubprogram(DISubprogram SP); /// processDeclare - Process DbgDeclareInst. - void processDeclare(DbgDeclareInst *DDI); + void processDeclare(const DbgDeclareInst *DDI); /// processLocation - Process DILocation. void processLocation(DILocation Loc); diff --git a/contrib/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm/include/llvm/DebugInfo/DIContext.h index 26bd1f6..8fcd9e0 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DIContext.h +++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h @@ -16,9 +16,11 @@ #define LLVM_DEBUGINFO_DICONTEXT_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/RelocVisitor.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -56,6 +58,8 @@ public: } }; +typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable; + /// DIInliningInfo - a format-neutral container for inlined code description. class DIInliningInfo { SmallVector<DILineInfo, 4> Frames; @@ -90,6 +94,24 @@ public: } }; +/// Selects which debug sections get dumped. +enum DIDumpType { + DIDT_Null, + DIDT_All, + DIDT_Abbrev, + DIDT_AbbrevDwo, + DIDT_Aranges, + DIDT_Frames, + DIDT_Info, + DIDT_InfoDwo, + DIDT_Line, + DIDT_Ranges, + DIDT_Pubnames, + DIDT_Str, + DIDT_StrDwo, + DIDT_StrOffsetsDwo +}; + // In place of applying the relocations to the data we've read from disk we use // a separate mapping table to the side and checking that at locations in the // dwarf where we expect relocated values. This adds a bit of complexity to the @@ -102,19 +124,14 @@ public: virtual ~DIContext(); /// getDWARFContext - get a context for binary DWARF data. - static DIContext *getDWARFContext(bool isLittleEndian, - StringRef infoSection, - StringRef abbrevSection, - StringRef aRangeSection = StringRef(), - StringRef lineSection = StringRef(), - StringRef stringSection = StringRef(), - StringRef rangeSection = StringRef(), - const RelocAddrMap &Map = RelocAddrMap()); + static DIContext *getDWARFContext(object::ObjectFile *); - virtual void dump(raw_ostream &OS) = 0; + virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0; virtual DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; + virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, + uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; }; diff --git a/contrib/llvm/include/llvm/DefaultPasses.h b/contrib/llvm/include/llvm/DefaultPasses.h deleted file mode 100644 index 9f1ade8..0000000 --- a/contrib/llvm/include/llvm/DefaultPasses.h +++ /dev/null @@ -1,168 +0,0 @@ -//===- llvm/DefaultPasses.h - Default Pass Support code --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// This file defines the infrastructure for registering the standard pass list. -// This defines sets of standard optimizations that plugins can modify and -// front ends can use. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEFAULT_PASS_SUPPORT_H -#define LLVM_DEFAULT_PASS_SUPPORT_H - -#include "llvm/PassSupport.h" - -namespace llvm { - -class PassManagerBase; - -/// Unique identifiers for the default standard passes. The addresses of -/// these symbols are used to uniquely identify passes from the default list. -namespace DefaultStandardPasses { -extern unsigned char AggressiveDCEID; -extern unsigned char ArgumentPromotionID; -extern unsigned char BasicAliasAnalysisID; -extern unsigned char CFGSimplificationID; -extern unsigned char ConstantMergeID; -extern unsigned char CorrelatedValuePropagationID; -extern unsigned char DeadArgEliminationID; -extern unsigned char DeadStoreEliminationID; -extern unsigned char EarlyCSEID; -extern unsigned char FunctionAttrsID; -extern unsigned char FunctionInliningID; -extern unsigned char GVNID; -extern unsigned char GlobalDCEID; -extern unsigned char GlobalOptimizerID; -extern unsigned char GlobalsModRefID; -extern unsigned char IPSCCPID; -extern unsigned char IndVarSimplifyID; -extern unsigned char InlinerPlaceholderID; -extern unsigned char InstructionCombiningID; -extern unsigned char JumpThreadingID; -extern unsigned char LICMID; -extern unsigned char LoopDeletionID; -extern unsigned char LoopIdiomID; -extern unsigned char LoopRotateID; -extern unsigned char LoopUnrollID; -extern unsigned char LoopUnswitchID; -extern unsigned char MemCpyOptID; -extern unsigned char PruneEHID; -extern unsigned char ReassociateID; -extern unsigned char SCCPID; -extern unsigned char ScalarReplAggregatesID; -extern unsigned char SimplifyLibCallsID; -extern unsigned char StripDeadPrototypesID; -extern unsigned char TailCallEliminationID; -extern unsigned char TypeBasedAliasAnalysisID; -} - -/// StandardPass - The class responsible for maintaining the lists of standard -class StandardPass { - friend class RegisterStandardPassLists; - public: - /// Predefined standard sets of passes - enum StandardSet { - AliasAnalysis, - Function, - Module, - LTO - }; - /// Flags to specify whether a pass should be enabled. Passes registered - /// with the standard sets may specify a minimum optimization level and one - /// or more flags that must be set when constructing the set for the pass to - /// be used. - enum OptimizationFlags { - /// Optimize for size was requested. - OptimizeSize = 1<<0, - /// Allow passes which may make global module changes. - UnitAtATime = 1<<1, - /// UnrollLoops - Allow loop unrolling. - UnrollLoops = 1<<2, - /// Allow library calls to be simplified. - SimplifyLibCalls = 1<<3, - /// Whether the module may have code using exceptions. - HaveExceptions = 1<<4, - // Run an inliner pass as part of this set. - RunInliner = 1<<5 - }; - enum OptimizationFlagComponents { - /// The low bits are used to store the optimization level. When requesting - /// passes, this should store the requested optimisation level. When - /// setting passes, this should set the minimum optimization level at which - /// the pass will run. - OptimizationLevelMask=0xf, - /// The maximum optimisation level at which the pass is run. - MaxOptimizationLevelMask=0xf0, - // Flags that must be set - RequiredFlagMask=0xff00, - // Flags that may not be set. - DisallowedFlagMask=0xff0000, - MaxOptimizationLevelShift=4, - RequiredFlagShift=8, - DisallowedFlagShift=16 - }; - /// Returns the optimisation level from a set of flags. - static unsigned OptimizationLevel(unsigned flags) { - return flags & OptimizationLevelMask; - } - /// Returns the maximum optimization level for this set of flags - static unsigned MaxOptimizationLevel(unsigned flags) { - return (flags & MaxOptimizationLevelMask) >> 4; - } - /// Constructs a set of flags from the specified minimum and maximum - /// optimisation level - static unsigned OptimzationFlags(unsigned minLevel=0, unsigned maxLevel=0xf, - unsigned requiredFlags=0, unsigned disallowedFlags=0) { - return ((minLevel & OptimizationLevelMask) | - ((maxLevel<<MaxOptimizationLevelShift) & MaxOptimizationLevelMask) - | ((requiredFlags<<RequiredFlagShift) & RequiredFlagMask) - | ((disallowedFlags<<DisallowedFlagShift) & DisallowedFlagMask)); - } - /// Returns the flags that must be set for this to match - static unsigned RequiredFlags(unsigned flags) { - return (flags & RequiredFlagMask) >> RequiredFlagShift; - } - /// Returns the flags that must not be set for this to match - static unsigned DisallowedFlags(unsigned flags) { - return (flags & DisallowedFlagMask) >> DisallowedFlagShift; - } - /// Register a standard pass in the specified set. If flags is non-zero, - /// then the pass will only be returned when the specified flags are set. - template<typename passName> - class RegisterStandardPass { - public: - RegisterStandardPass(StandardSet set, unsigned char *runBefore=0, - unsigned flags=0, unsigned char *ID=0) { - // Use the pass's ID if one is not specified - RegisterDefaultPass(PassInfo::NormalCtor_t(callDefaultCtor<passName>), - ID ? ID : (unsigned char*)&passName::ID, runBefore, set, flags); - } - }; - /// Adds the passes from the specified set to the provided pass manager - static void AddPassesFromSet(PassManagerBase *PM, - StandardSet set, - unsigned flags=0, - bool VerifyEach=false, - Pass *inliner=0); - private: - /// Registers the default passes. This is set by RegisterStandardPassLists - /// and is called lazily. - static void (*RegisterDefaultPasses)(void); - /// Creates the verifier pass that is inserted when a VerifyEach is passed to - /// AddPassesFromSet() - static Pass* (*CreateVerifierPass)(void); - /// Registers the pass - static void RegisterDefaultPass(PassInfo::NormalCtor_t constructor, - unsigned char *newPass, - unsigned char *oldPass, - StandardSet set, - unsigned flags=0); -}; - -} // namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h index 8073d8f..3fd69e2 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -12,22 +12,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_H -#define LLVM_EXECUTION_ENGINE_H +#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H +#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H -#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include <vector> #include <map> #include <string> +#include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h index a2fed98..0e92f79 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// -#ifndef GENERIC_VALUE_H -#define GENERIC_VALUE_H +#ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H +#define LLVM_EXECUTIONENGINE_GENERICVALUE_H #include "llvm/ADT/APInt.h" #include "llvm/Support/DataTypes.h" @@ -24,21 +24,30 @@ typedef void* PointerTy; class APInt; struct GenericValue { + struct IntPair { + unsigned int first; + unsigned int second; + }; union { double DoubleVal; float FloatVal; PointerTy PointerVal; - struct { unsigned int first; unsigned int second; } UIntPairVal; + struct IntPair UIntPairVal; unsigned char Untyped[8]; }; - APInt IntVal; // also used for long doubles - - GenericValue() : DoubleVal(0.0), IntVal(1,0) {} + APInt IntVal; // also used for long doubles. + // For aggregate data types. + std::vector<GenericValue> AggregateVal; + + // to make code faster, set GenericValue to zero could be omitted, but it is + // potentially can cause problems, since GenericValue to store garbage + // instead of zero. + GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;} explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { } }; inline GenericValue PTOGV(void *P) { return GenericValue(P); } inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; } -} // End llvm namespace +} // End llvm namespace. #endif diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h b/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h index 72d97ef..f49d0c4 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef EXECUTION_ENGINE_INTERPRETER_H -#define EXECUTION_ENGINE_INTERPRETER_H +#ifndef LLVM_EXECUTIONENGINE_INTERPRETER_H +#define LLVM_EXECUTIONENGINE_INTERPRETER_H #include "llvm/ExecutionEngine/ExecutionEngine.h" #include <cstdlib> diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JIT.h b/contrib/llvm/include/llvm/ExecutionEngine/JIT.h index b4cda1d..581d6e6 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/JIT.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/JIT.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_JIT_H -#define LLVM_EXECUTION_ENGINE_JIT_H +#ifndef LLVM_EXECUTIONENGINE_JIT_H +#define LLVM_EXECUTIONENGINE_JIT_H #include "llvm/ExecutionEngine/ExecutionEngine.h" #include <cstdlib> diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h index e6586e7..ed66102 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h @@ -12,13 +12,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H -#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H +#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H +#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" - #include <vector> namespace llvm { @@ -128,4 +127,4 @@ public: } // end namespace llvm. -#endif // defined LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H +#endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h b/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h index 9089646..714a980 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H -#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H +#ifndef LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H +#define LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Support/DataTypes.h" - #include <string> namespace llvm { diff --git a/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h b/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h index ac16bdc..66ddb7c 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H -#define LLVM_EXECUTION_ENGINE_MCJIT_H +#ifndef LLVM_EXECUTIONENGINE_MCJIT_H +#define LLVM_EXECUTIONENGINE_MCJIT_H #include "llvm/ExecutionEngine/ExecutionEngine.h" #include <cstdlib> diff --git a/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h b/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h index ab7f25e..05da594 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h @@ -17,8 +17,8 @@ // //===----------------------------------------------------------------------===// -#ifndef OPROFILE_WRAPPER_H -#define OPROFILE_WRAPPER_H +#ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H +#define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H #include "llvm/Support/DataTypes.h" #include <opagent.h> @@ -41,10 +41,10 @@ class OProfileWrapper { typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t); // Also used for op_minor_version function which has the same signature - typedef int (*op_major_version_ptr_t)(void); + typedef int (*op_major_version_ptr_t)(); // This is not a part of the opagent API, but is useful nonetheless - typedef bool (*IsOProfileRunningPtrT)(void); + typedef bool (*IsOProfileRunningPtrT)(); op_agent_t Agent; @@ -99,8 +99,8 @@ public: size_t num_entries, struct debug_line_info const* info); int op_unload_native_code(uint64_t addr); - int op_major_version(void); - int op_minor_version(void); + int op_major_version(); + int op_minor_version(); // Returns true if the oprofiled process is running, the opagent library is // loaded and a connection to the agent has been established, and false @@ -121,4 +121,4 @@ private: } // namespace llvm -#endif //OPROFILE_WRAPPER_H +#endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H diff --git a/contrib/llvm/include/llvm/ExecutionEngine/ObjectBuffer.h b/contrib/llvm/include/llvm/ExecutionEngine/ObjectBuffer.h index a0a77b8..96a48b2 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/ObjectBuffer.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -1,80 +1,80 @@ -//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares a wrapper class to hold the memory into which an
-// object will be generated.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
-#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-namespace llvm {
-
-/// ObjectBuffer - This class acts as a container for the memory buffer used during
-/// generation and loading of executable objects using MCJIT and RuntimeDyld. The
-/// underlying memory for the object will be owned by the ObjectBuffer instance
-/// throughout its lifetime. The getMemBuffer() method provides a way to create a
-/// MemoryBuffer wrapper object instance to be owned by other classes (such as
-/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
-/// actual memory it points to.
-class ObjectBuffer {
-public:
- ObjectBuffer() {}
- ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
- virtual ~ObjectBuffer() {}
-
- /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
- /// returns a pointer to an object that is owned by the caller. However,
- /// the caller does not take ownership of the underlying memory.
- MemoryBuffer *getMemBuffer() const {
- return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
- }
-
- const char *getBufferStart() const { return Buffer->getBufferStart(); }
- size_t getBufferSize() const { return Buffer->getBufferSize(); }
-
-protected:
- // The memory contained in an ObjectBuffer
- OwningPtr<MemoryBuffer> Buffer;
-};
-
-/// ObjectBufferStream - This class encapsulates the SmallVector and
-/// raw_svector_ostream needed to generate an object using MC code emission
-/// while providing a common ObjectBuffer interface for access to the
-/// memory once the object has been generated.
-class ObjectBufferStream : public ObjectBuffer {
-public:
- ObjectBufferStream() : OS(SV) {}
- virtual ~ObjectBufferStream() {}
-
- raw_ostream &getOStream() { return OS; }
- void flush()
- {
- OS.flush();
-
- // Make the data accessible via the ObjectBuffer::Buffer
- Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
- "",
- false));
- }
-
-protected:
- SmallVector<char, 4096> SV; // Working buffer into which we JIT.
- raw_svector_ostream OS; // streaming wrapper
-};
-
-} // namespace llvm
-
-#endif
+//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares a wrapper class to hold the memory into which an +// object will be generated. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H +#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +/// ObjectBuffer - This class acts as a container for the memory buffer used during +/// generation and loading of executable objects using MCJIT and RuntimeDyld. The +/// underlying memory for the object will be owned by the ObjectBuffer instance +/// throughout its lifetime. The getMemBuffer() method provides a way to create a +/// MemoryBuffer wrapper object instance to be owned by other classes (such as +/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the +/// actual memory it points to. +class ObjectBuffer { +public: + ObjectBuffer() {} + ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {} + virtual ~ObjectBuffer() {} + + /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function + /// returns a pointer to an object that is owned by the caller. However, + /// the caller does not take ownership of the underlying memory. + MemoryBuffer *getMemBuffer() const { + return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false); + } + + const char *getBufferStart() const { return Buffer->getBufferStart(); } + size_t getBufferSize() const { return Buffer->getBufferSize(); } + +protected: + // The memory contained in an ObjectBuffer + OwningPtr<MemoryBuffer> Buffer; +}; + +/// ObjectBufferStream - This class encapsulates the SmallVector and +/// raw_svector_ostream needed to generate an object using MC code emission +/// while providing a common ObjectBuffer interface for access to the +/// memory once the object has been generated. +class ObjectBufferStream : public ObjectBuffer { +public: + ObjectBufferStream() : OS(SV) {} + virtual ~ObjectBufferStream() {} + + raw_ostream &getOStream() { return OS; } + void flush() + { + OS.flush(); + + // Make the data accessible via the ObjectBuffer::Buffer + Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()), + "", + false)); + } + +protected: + SmallVector<char, 4096> SV; // Working buffer into which we JIT. + raw_svector_ostream OS; // streaming wrapper +}; + +} // namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/ExecutionEngine/ObjectImage.h b/contrib/llvm/include/llvm/ExecutionEngine/ObjectImage.h index 82549ad..9fddca7 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/ObjectImage.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/ObjectImage.h @@ -1,61 +1,63 @@ -//===---- ObjectImage.h - Format independent executuable object image -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares a file format independent ObjectImage class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
-#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
-
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/ExecutionEngine/ObjectBuffer.h"
-
-namespace llvm {
-
-
-/// ObjectImage - A container class that represents an ObjectFile that has been
-/// or is in the process of being loaded into memory for execution.
-class ObjectImage {
- ObjectImage() LLVM_DELETED_FUNCTION;
- ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
-
-protected:
- OwningPtr<ObjectBuffer> Buffer;
-
-public:
- ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
- virtual ~ObjectImage() {}
-
- virtual object::symbol_iterator begin_symbols() const = 0;
- virtual object::symbol_iterator end_symbols() const = 0;
-
- virtual object::section_iterator begin_sections() const = 0;
- virtual object::section_iterator end_sections() const = 0;
-
- virtual /* Triple::ArchType */ unsigned getArch() const = 0;
-
- // Subclasses can override these methods to update the image with loaded
- // addresses for sections and common symbols
- virtual void updateSectionAddress(const object::SectionRef &Sec,
- uint64_t Addr) = 0;
- virtual void updateSymbolAddress(const object::SymbolRef &Sym,
- uint64_t Addr) = 0;
-
- virtual StringRef getData() const = 0;
-
- // Subclasses can override these methods to provide JIT debugging support
- virtual void registerWithDebugger() = 0;
- virtual void deregisterWithDebugger() = 0;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
+//===---- ObjectImage.h - Format independent executuable object image -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares a file format independent ObjectImage class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H +#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H + +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/Object/ObjectFile.h" + +namespace llvm { + + +/// ObjectImage - A container class that represents an ObjectFile that has been +/// or is in the process of being loaded into memory for execution. +class ObjectImage { + ObjectImage() LLVM_DELETED_FUNCTION; + ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION; + +protected: + OwningPtr<ObjectBuffer> Buffer; + +public: + ObjectImage(ObjectBuffer *Input) : Buffer(Input) {} + virtual ~ObjectImage() {} + + virtual object::symbol_iterator begin_symbols() const = 0; + virtual object::symbol_iterator end_symbols() const = 0; + + virtual object::section_iterator begin_sections() const = 0; + virtual object::section_iterator end_sections() const = 0; + + virtual /* Triple::ArchType */ unsigned getArch() const = 0; + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + virtual void updateSectionAddress(const object::SectionRef &Sec, + uint64_t Addr) = 0; + virtual void updateSymbolAddress(const object::SymbolRef &Sym, + uint64_t Addr) = 0; + + virtual StringRef getData() const = 0; + + virtual object::ObjectFile* getObjectFile() const = 0; + + // Subclasses can override these methods to provide JIT debugging support + virtual void registerWithDebugger() = 0; + virtual void deregisterWithDebugger() = 0; +}; + +} // end namespace llvm + +#endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H + diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index 891f534..4222d53 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_RUNTIME_DYLD_H -#define LLVM_RUNTIME_DYLD_H +#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H +#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" @@ -36,29 +36,36 @@ public: RTDyldMemoryManager() {} virtual ~RTDyldMemoryManager(); - /// allocateCodeSection - Allocate a memory block of (at least) the given - /// size suitable for executable code. The SectionID is a unique identifier - /// assigned by the JIT engine, and optionally recorded by the memory manager - /// to access a loaded section. + /// Allocate a memory block of (at least) the given size suitable for + /// executable code. The SectionID is a unique identifier assigned by the JIT + /// engine, and optionally recorded by the memory manager to access a loaded + /// section. virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; - /// allocateDataSection - Allocate a memory block of (at least) the given - /// size suitable for data. The SectionID is a unique identifier - /// assigned by the JIT engine, and optionally recorded by the memory manager - /// to access a loaded section. + /// Allocate a memory block of (at least) the given size suitable for data. + /// The SectionID is a unique identifier assigned by the JIT engine, and + /// optionally recorded by the memory manager to access a loaded section. virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) = 0; + unsigned SectionID, bool IsReadOnly) = 0; - /// getPointerToNamedFunction - This method returns the address of the - /// specified function. As such it is only useful for resolving library - /// symbols, not code generated symbols. + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. /// /// If AbortOnFailure is false and no function with the given name is /// found, this function returns a null pointer. Otherwise, it prints a /// message to stderr and aborts. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; + + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. + /// + /// Returns true if an error occurred, false otherwise. + virtual bool applyPermissions(std::string *ErrMsg = 0) = 0; }; class RuntimeDyld { @@ -77,10 +84,10 @@ public: RuntimeDyld(RTDyldMemoryManager *); ~RuntimeDyld(); - /// loadObject - prepare the object contained in the input buffer for - /// execution. Ownership of the input buffer is transferred to the - /// ObjectImage instance returned from this function if successful. - /// In the case of load failure, the input buffer will be deleted. + /// Prepare the object contained in the input buffer for execution. + /// Ownership of the input buffer is transferred to the ObjectImage + /// instance returned from this function if successful. In the case of load + /// failure, the input buffer will be deleted. ObjectImage *loadObject(ObjectBuffer *InputBuffer); /// Get the address of our local copy of the symbol. This may or may not @@ -95,7 +102,7 @@ public: /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); - /// mapSectionAddress - map a section to its target address space value. + /// Map a section to its target address space value. /// Map the address of a JIT section as returned from the memory manager /// to the address in the target process as the running code will see it. /// This is the address which will be used for relocation resolution. diff --git a/contrib/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h b/contrib/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h new file mode 100644 index 0000000..ae5004e1 --- /dev/null +++ b/contrib/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -0,0 +1,176 @@ +//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of a section-based memory manager used by +// the MCJIT execution engine and RuntimeDyld. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H +#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Memory.h" + +namespace llvm { + +/// This is a simple memory manager which implements the methods called by +/// the RuntimeDyld class to allocate memory for section-based loading of +/// objects, usually those generated by the MCJIT execution engine. +/// +/// This memory manager allocates all section memory as read-write. The +/// RuntimeDyld will copy JITed section memory into these allocated blocks +/// and perform any necessary linking and relocations. +/// +/// Any client using this memory manager MUST ensure that section-specific +/// page permissions have been applied before attempting to execute functions +/// in the JITed object. Permissions can be applied either by calling +/// MCJIT::finalizeObject or by calling SectionMemoryManager::applyPermissions +/// directly. Clients of MCJIT should call MCJIT::finalizeObject. +class SectionMemoryManager : public JITMemoryManager { + SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION; + +public: + SectionMemoryManager() { } + virtual ~SectionMemoryManager(); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID); + + /// \brief Allocates a memory block of (at least) the given size suitable for + /// executable code. + /// + /// The value of \p Alignment must be a power of two. If \p Alignment is zero + /// a default alignment of 16 will be used. + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + bool isReadOnly); + + /// \brief Applies section-specific memory permissions. + /// + /// This method is called when object loading is complete and section page + /// permissions can be applied. It is up to the memory manager implementation + /// to decide whether or not to act on this method. The memory manager will + /// typically allocate all sections as read-write and then apply specific + /// permissions when this method is called. Code sections cannot be executed + /// until this function has been called. + /// + /// \returns true if an error occurred, false otherwise. + virtual bool applyPermissions(std::string *ErrMsg = 0); + + /// This method returns the address of the specified function. As such it is + /// only useful for resolving library symbols, not code generated symbols. + /// + /// If \p AbortOnFailure is false and no function with the given name is + /// found, this function returns a null pointer. Otherwise, it prints a + /// message to stderr and aborts. + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true); + + /// \brief Invalidate instruction cache for code sections. + /// + /// Some platforms with separate data cache and instruction cache require + /// explicit cache flush, otherwise JIT code manipulations (like resolved + /// relocations) will get to the data cache but not to the instruction cache. + /// + /// This method is not called by RuntimeDyld or MCJIT during the load + /// process. Clients may call this function when needed. See the lli + /// tool for example use. + virtual void invalidateInstructionCache(); + +private: + struct MemoryGroup { + SmallVector<sys::MemoryBlock, 16> AllocatedMem; + SmallVector<sys::MemoryBlock, 16> FreeMem; + sys::MemoryBlock Near; + }; + + uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size, + unsigned Alignment); + + error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions); + + MemoryGroup CodeMem; + MemoryGroup RWDataMem; + MemoryGroup RODataMem; + +public: + /// + /// Functions below are not used by MCJIT or RuntimeDyld, but must be + /// implemented because they are declared as pure virtuals in the base class. + /// + + virtual void setMemoryWritable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setMemoryExecutable() { + llvm_unreachable("Unexpected call!"); + } + virtual void setPoisonMemory(bool poison) { + llvm_unreachable("Unexpected call!"); + } + virtual void AllocateGOT() { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *getGOTBase() const { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *startFunctionBody(const Function *F, + uintptr_t &ActualSize){ + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize, + unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void deallocateFunctionBody(void *Body) { + llvm_unreachable("Unexpected call!"); + } + virtual uint8_t *startExceptionTable(const Function *F, + uintptr_t &ActualSize) { + llvm_unreachable("Unexpected call!"); + return 0; + } + virtual void endExceptionTable(const Function *F, uint8_t *TableStart, + uint8_t *TableEnd, uint8_t *FrameRegister) { + llvm_unreachable("Unexpected call!"); + } + virtual void deallocateExceptionTable(void *ET) { + llvm_unreachable("Unexpected call!"); + } +}; + +} + +#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H + diff --git a/contrib/llvm/include/llvm/GVMaterializer.h b/contrib/llvm/include/llvm/GVMaterializer.h index c143552..1e5c426 100644 --- a/contrib/llvm/include/llvm/GVMaterializer.h +++ b/contrib/llvm/include/llvm/GVMaterializer.h @@ -15,8 +15,8 @@ // //===----------------------------------------------------------------------===// -#ifndef GVMATERIALIZER_H -#define GVMATERIALIZER_H +#ifndef LLVM_GVMATERIALIZER_H +#define LLVM_GVMATERIALIZER_H #include <string> diff --git a/contrib/llvm/include/llvm/IR/Argument.h b/contrib/llvm/include/llvm/IR/Argument.h new file mode 100644 index 0000000..ef4e4fc --- /dev/null +++ b/contrib/llvm/include/llvm/IR/Argument.h @@ -0,0 +1,96 @@ +//===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the Argument class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_ARGUMENT_H +#define LLVM_IR_ARGUMENT_H + +#include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Value.h" + +namespace llvm { + +template<typename ValueSubClass, typename ItemParentClass> + class SymbolTableListTraits; + +/// \brief LLVM Argument representation +/// +/// This class represents an incoming formal argument to a Function. A formal +/// argument, since it is ``formal'', does not contain an actual value but +/// instead represents the type, argument number, and attributes of an argument +/// for a specific function. When used in the body of said function, the +/// argument of course represents the value of the actual argument that the +/// function was called with. +class Argument : public Value, public ilist_node<Argument> { + virtual void anchor(); + Function *Parent; + + friend class SymbolTableListTraits<Argument, Function>; + void setParent(Function *parent); + +public: + /// \brief Constructor. + /// + /// If \p F is specified, the argument is inserted at the end of the argument + /// list for \p F. + explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0); + + inline const Function *getParent() const { return Parent; } + inline Function *getParent() { return Parent; } + + /// \brief Return the index of this formal argument in its containing + /// function. + /// + /// For example in "void foo(int a, float b)" a is 0 and b is 1. + unsigned getArgNo() const; + + /// \brief Return true if this argument has the byval attribute on it in its + /// containing function. + bool hasByValAttr() const; + + /// \brief If this is a byval argument, return its alignment. + unsigned getParamAlignment() const; + + /// \brief Return true if this argument has the nest attribute on it in its + /// containing function. + bool hasNestAttr() const; + + /// \brief Return true if this argument has the noalias attribute on it in its + /// containing function. + bool hasNoAliasAttr() const; + + /// \brief Return true if this argument has the nocapture attribute on it in + /// its containing function. + bool hasNoCaptureAttr() const; + + /// \brief Return true if this argument has the sret attribute on it in its + /// containing function. + bool hasStructRetAttr() const; + + /// \brief Add a Attribute to an argument. + void addAttr(AttributeSet AS); + + /// \brief Remove a Attribute from an argument. + void removeAttr(AttributeSet AS); + + /// \brief Method for support type inquiry through isa, cast, and + /// dyn_cast. + static inline bool classof(const Value *V) { + return V->getValueID() == ArgumentVal; + } +}; + +} // End llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/IR/Attributes.h b/contrib/llvm/include/llvm/IR/Attributes.h new file mode 100644 index 0000000..074b387 --- /dev/null +++ b/contrib/llvm/include/llvm/IR/Attributes.h @@ -0,0 +1,499 @@ +//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file contains the simple types necessary to represent the +/// attributes associated with functions and their calls. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_ATTRIBUTES_H +#define LLVM_IR_ATTRIBUTES_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <bitset> +#include <cassert> +#include <map> +#include <string> + +namespace llvm { + +class AttrBuilder; +class AttributeImpl; +class AttributeSetImpl; +class AttributeSetNode; +class Constant; +template<typename T> struct DenseMapInfo; +class LLVMContext; +class Type; + +//===----------------------------------------------------------------------===// +/// \class +/// \brief Functions, function parameters, and return types can have attributes +/// to indicate how they should be treated by optimizations and code +/// generation. This class represents one of those attributes. It's light-weight +/// and should be passed around by-value. +class Attribute { +public: + /// This enumeration lists the attributes that can be associated with + /// parameters, function results, or the function itself. + /// + /// Note: The `uwtable' attribute is about the ABI or the user mandating an + /// entry in the unwind table. The `nounwind' attribute is about an exception + /// passing by the function. + /// + /// In a theoretical system that uses tables for profiling and SjLj for + /// exceptions, they would be fully independent. In a normal system that uses + /// tables for both, the semantics are: + /// + /// nil = Needs an entry because an exception might pass by. + /// nounwind = No need for an entry + /// uwtable = Needs an entry because the ABI says so and because + /// an exception might pass by. + /// uwtable + nounwind = Needs an entry because the ABI says so. + + enum AttrKind { + // IR-Level Attributes + None, ///< No attributes have been set + Alignment, ///< Alignment of parameter (5 bits) + ///< stored as log2 of alignment with +1 bias + ///< 0 means unaligned (different from align(1)) + AlwaysInline, ///< inline=always + ByVal, ///< Pass structure by value + InlineHint, ///< Source said inlining was desirable + InReg, ///< Force argument to be passed in register + MinSize, ///< Function must be optimized for size first + Naked, ///< Naked function + Nest, ///< Nested function static chain + NoAlias, ///< Considered to not alias after call + NoBuiltin, ///< Callee isn't recognized as a builtin + NoCapture, ///< Function creates no aliases of pointer + NoDuplicate, ///< Call cannot be duplicated + NoImplicitFloat, ///< Disable implicit floating point insts + NoInline, ///< inline=never + NonLazyBind, ///< Function is called early and/or + ///< often, so lazy binding isn't worthwhile + NoRedZone, ///< Disable redzone + NoReturn, ///< Mark the function as not returning + NoUnwind, ///< Function doesn't unwind stack + OptimizeForSize, ///< opt_size + ReadNone, ///< Function does not access memory + ReadOnly, ///< Function only reads from memory + ReturnsTwice, ///< Function can return twice + SExt, ///< Sign extended before/after call + StackAlignment, ///< Alignment of stack for function (3 bits) + ///< stored as log2 of alignment with +1 bias 0 + ///< means unaligned (different from + ///< alignstack=(1)) + StackProtect, ///< Stack protection. + StackProtectReq, ///< Stack protection required. + StackProtectStrong, ///< Strong Stack protection. + StructRet, ///< Hidden pointer to structure to return + SanitizeAddress, ///< AddressSanitizer is on. + SanitizeThread, ///< ThreadSanitizer is on. + SanitizeMemory, ///< MemorySanitizer is on. + UWTable, ///< Function must be in a unwind table + ZExt, ///< Zero extended before/after call + + EndAttrKinds ///< Sentinal value useful for loops + }; +private: + AttributeImpl *pImpl; + Attribute(AttributeImpl *A) : pImpl(A) {} +public: + Attribute() : pImpl(0) {} + + //===--------------------------------------------------------------------===// + // Attribute Construction + //===--------------------------------------------------------------------===// + + /// \brief Return a uniquified Attribute object. + static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); + static Attribute get(LLVMContext &Context, StringRef Kind, + StringRef Val = StringRef()); + + /// \brief Return a uniquified Attribute object that has the specific + /// alignment set. + static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align); + static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align); + + //===--------------------------------------------------------------------===// + // Attribute Accessors + //===--------------------------------------------------------------------===// + + /// \brief Return true if the attribute is an Attribute::AttrKind type. + bool isEnumAttribute() const; + + /// \brief Return true if the attribute is an alignment attribute. + bool isAlignAttribute() const; + + /// \brief Return true if the attribute is a string (target-dependent) + /// attribute. + bool isStringAttribute() const; + + /// \brief Return true if the attribute is present. + bool hasAttribute(AttrKind Val) const; + + /// \brief Return true if the target-dependent attribute is present. + bool hasAttribute(StringRef Val) const; + + /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). This + /// requires the attribute to be an enum or alignment attribute. + Attribute::AttrKind getKindAsEnum() const; + + /// \brief Return the attribute's value as an integer. This requires that the + /// attribute be an alignment attribute. + uint64_t getValueAsInt() const; + + /// \brief Return the attribute's kind as a string. This requires the + /// attribute to be a string attribute. + StringRef getKindAsString() const; + + /// \brief Return the attribute's value as a string. This requires the + /// attribute to be a string attribute. + StringRef getValueAsString() const; + + /// \brief Returns the alignment field of an attribute as a byte alignment + /// value. + unsigned getAlignment() const; + + /// \brief Returns the stack alignment field of an attribute as a byte + /// alignment value. + unsigned getStackAlignment() const; + + /// \brief The Attribute is converted to a string of equivalent mnemonic. This + /// is, presumably, for writing out the mnemonics for the assembly writer. + std::string getAsString(bool InAttrGrp = false) const; + + /// \brief Equality and non-equality operators. + bool operator==(Attribute A) const { return pImpl == A.pImpl; } + bool operator!=(Attribute A) const { return pImpl != A.pImpl; } + + /// \brief Less-than operator. Useful for sorting the attributes list. + bool operator<(Attribute A) const; + + void Profile(FoldingSetNodeID &ID) const { + ID.AddPointer(pImpl); + } +}; + +//===----------------------------------------------------------------------===// +/// \class +/// \brief This class holds the attributes for a function, its return value, and +/// its parameters. You access the attributes for each of them via an index into +/// the AttributeSet object. The function attributes are at index +/// `AttributeSet::FunctionIndex', the return value is at index +/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at +/// index `1'. +class AttributeSet { +public: + enum AttrIndex { + ReturnIndex = 0U, + FunctionIndex = ~0U + }; +private: + friend class AttrBuilder; + friend class AttributeSetImpl; + template <typename Ty> friend struct DenseMapInfo; + + /// \brief The attributes that we are managing. This can be null to represent + /// the empty attributes list. + AttributeSetImpl *pImpl; + + /// \brief The attributes for the specified index are returned. + AttributeSetNode *getAttributes(unsigned Idx) const; + + /// \brief Create an AttributeSet with the specified parameters in it. + static AttributeSet get(LLVMContext &C, + ArrayRef<std::pair<unsigned, Attribute> > Attrs); + static AttributeSet get(LLVMContext &C, + ArrayRef<std::pair<unsigned, + AttributeSetNode*> > Attrs); + + static AttributeSet getImpl(LLVMContext &C, + ArrayRef<std::pair<unsigned, + AttributeSetNode*> > Attrs); + + + explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {} +public: + AttributeSet() : pImpl(0) {} + + //===--------------------------------------------------------------------===// + // AttributeSet Construction and Mutation + //===--------------------------------------------------------------------===// + + /// \brief Return an AttributeSet with the specified parameters in it. + static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs); + static AttributeSet get(LLVMContext &C, unsigned Idx, + ArrayRef<Attribute::AttrKind> Kind); + static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B); + + /// \brief Add an attribute to the attribute set at the given index. Since + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttribute(LLVMContext &C, unsigned Idx, + Attribute::AttrKind Attr) const; + + /// \brief Add an attribute to the attribute set at the given index. Since + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttribute(LLVMContext &C, unsigned Idx, + StringRef Kind) const; + + /// \brief Add attributes to the attribute set at the given index. Since + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttributes(LLVMContext &C, unsigned Idx, + AttributeSet Attrs) const; + + /// \brief Remove the specified attribute at the specified index from this + /// attribute list. Since attribute lists are immutable, this returns the new + /// list. + AttributeSet removeAttribute(LLVMContext &C, unsigned Idx, + Attribute::AttrKind Attr) const; + + /// \brief Remove the specified attributes at the specified index from this + /// attribute list. Since attribute lists are immutable, this returns the new + /// list. + AttributeSet removeAttributes(LLVMContext &C, unsigned Idx, + AttributeSet Attrs) const; + + //===--------------------------------------------------------------------===// + // AttributeSet Accessors + //===--------------------------------------------------------------------===// + + /// \brief Retrieve the LLVM context. + LLVMContext &getContext() const; + + /// \brief The attributes for the specified index are returned. + AttributeSet getParamAttributes(unsigned Idx) const; + + /// \brief The attributes for the ret value are returned. + AttributeSet getRetAttributes() const; + + /// \brief The function attributes are returned. + AttributeSet getFnAttributes() const; + + /// \brief Return true if the attribute exists at the given index. + bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const; + + /// \brief Return true if the attribute exists at the given index. + bool hasAttribute(unsigned Index, StringRef Kind) const; + + /// \brief Return true if attribute exists at the given index. + bool hasAttributes(unsigned Index) const; + + /// \brief Return true if the specified attribute is set for at least one + /// parameter or for the return value. + bool hasAttrSomewhere(Attribute::AttrKind Attr) const; + + /// \brief Return the attribute object that exists at the given index. + Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; + + /// \brief Return the attribute object that exists at the given index. + Attribute getAttribute(unsigned Index, StringRef Kind) const; + + /// \brief Return the alignment for the specified function parameter. + unsigned getParamAlignment(unsigned Idx) const; + + /// \brief Get the stack alignment. + unsigned getStackAlignment(unsigned Index) const; + + /// \brief Return the attributes at the index as a string. + std::string getAsString(unsigned Index, bool InAttrGrp = false) const; + + typedef ArrayRef<Attribute>::iterator iterator; + + iterator begin(unsigned Idx) const; + iterator end(unsigned Idx) const; + + /// operator==/!= - Provide equality predicates. + bool operator==(const AttributeSet &RHS) const { + return pImpl == RHS.pImpl; + } + bool operator!=(const AttributeSet &RHS) const { + return pImpl != RHS.pImpl; + } + + //===--------------------------------------------------------------------===// + // AttributeSet Introspection + //===--------------------------------------------------------------------===// + + // FIXME: Remove this. + uint64_t Raw(unsigned Index) const; + + /// \brief Return a raw pointer that uniquely identifies this attribute list. + void *getRawPointer() const { + return pImpl; + } + + /// \brief Return true if there are no attributes. + bool isEmpty() const { + return getNumSlots() == 0; + } + + /// \brief Return the number of slots used in this attribute list. This is + /// the number of arguments that have an attribute set on them (including the + /// function itself). + unsigned getNumSlots() const; + + /// \brief Return the index for the given slot. + uint64_t getSlotIndex(unsigned Slot) const; + + /// \brief Return the attributes at the given slot. + AttributeSet getSlotAttributes(unsigned Slot) const; + + void dump() const; +}; + +//===----------------------------------------------------------------------===// +/// \class +/// \brief Provide DenseMapInfo for AttributeSet. +template<> struct DenseMapInfo<AttributeSet> { + static inline AttributeSet getEmptyKey() { + uintptr_t Val = static_cast<uintptr_t>(-1); + Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; + return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); + } + static inline AttributeSet getTombstoneKey() { + uintptr_t Val = static_cast<uintptr_t>(-2); + Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; + return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); + } + static unsigned getHashValue(AttributeSet AS) { + return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ + (unsigned((uintptr_t)AS.pImpl) >> 9); + } + static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } +}; + +//===----------------------------------------------------------------------===// +/// \class +/// \brief This class is used in conjunction with the Attribute::get method to +/// create an Attribute object. The object itself is uniquified. The Builder's +/// value, however, is not. So this can be used as a quick way to test for +/// equality, presence of attributes, etc. +class AttrBuilder { + std::bitset<Attribute::EndAttrKinds> Attrs; + std::map<std::string, std::string> TargetDepAttrs; + uint64_t Alignment; + uint64_t StackAlignment; +public: + AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {} + explicit AttrBuilder(uint64_t Val) + : Attrs(0), Alignment(0), StackAlignment(0) { + addRawValue(Val); + } + AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment(0) { + addAttribute(A); + } + AttrBuilder(AttributeSet AS, unsigned Idx); + AttrBuilder(const AttrBuilder &B) + : Attrs(B.Attrs), + TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()), + Alignment(B.Alignment), StackAlignment(B.StackAlignment) {} + + void clear(); + + /// \brief Add an attribute to the builder. + AttrBuilder &addAttribute(Attribute::AttrKind Val); + + /// \brief Add the Attribute object to the builder. + AttrBuilder &addAttribute(Attribute A); + + /// \brief Add the target-dependent attribute to the builder. + AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); + + /// \brief Remove an attribute from the builder. + AttrBuilder &removeAttribute(Attribute::AttrKind Val); + + /// \brief Remove the attributes from the builder. + AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index); + + /// \brief Remove the target-dependent attribute to the builder. + AttrBuilder &removeAttribute(StringRef A); + + /// \brief Add the attributes from the builder. + AttrBuilder &merge(const AttrBuilder &B); + + /// \brief Return true if the builder has the specified attribute. + bool contains(Attribute::AttrKind A) const { + assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!"); + return Attrs[A]; + } + + /// \brief Return true if the builder has the specified target-dependent + /// attribute. + bool contains(StringRef A) const; + + /// \brief Return true if the builder has IR-level attributes. + bool hasAttributes() const; + + /// \brief Return true if the builder has any attribute that's in the + /// specified attribute. + bool hasAttributes(AttributeSet A, uint64_t Index) const; + + /// \brief Return true if the builder has an alignment attribute. + bool hasAlignmentAttr() const; + + /// \brief Retrieve the alignment attribute, if it exists. + uint64_t getAlignment() const { return Alignment; } + + /// \brief Retrieve the stack alignment attribute, if it exists. + uint64_t getStackAlignment() const { return StackAlignment; } + + /// \brief This turns an int alignment (which must be a power of 2) into the + /// form used internally in Attribute. + AttrBuilder &addAlignmentAttr(unsigned Align); + + /// \brief This turns an int stack alignment (which must be a power of 2) into + /// the form used internally in Attribute. + AttrBuilder &addStackAlignmentAttr(unsigned Align); + + /// \brief Return true if the builder contains no target-independent + /// attributes. + bool empty() const { return Attrs.none(); } + + // Iterators for target-dependent attributes. + typedef std::pair<std::string, std::string> td_type; + typedef std::map<std::string, std::string>::iterator td_iterator; + typedef std::map<std::string, std::string>::const_iterator td_const_iterator; + + td_iterator td_begin() { return TargetDepAttrs.begin(); } + td_iterator td_end() { return TargetDepAttrs.end(); } + + td_const_iterator td_begin() const { return TargetDepAttrs.begin(); } + td_const_iterator td_end() const { return TargetDepAttrs.end(); } + + bool td_empty() const { return TargetDepAttrs.empty(); } + + /// \brief Remove attributes that are used on functions only. + void removeFunctionOnlyAttrs(); + + bool operator==(const AttrBuilder &B); + bool operator!=(const AttrBuilder &B) { + return !(*this == B); + } + + // FIXME: Remove this in 4.0. + + /// \brief Add the raw value to the internal representation. + AttrBuilder &addRawValue(uint64_t Val); +}; + +namespace AttributeFuncs { + +/// \brief Which attributes cannot be applied to a type. +AttributeSet typeIncompatible(Type *Ty, uint64_t Index); + +} // end AttributeFuncs namespace + +} // end llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/BasicBlock.h b/contrib/llvm/include/llvm/IR/BasicBlock.h index 02c2a96..ea5695a 100644 --- a/contrib/llvm/include/llvm/BasicBlock.h +++ b/contrib/llvm/include/llvm/IR/BasicBlock.h @@ -11,13 +11,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_BASICBLOCK_H -#define LLVM_BASICBLOCK_H +#ifndef LLVM_IR_BASICBLOCK_H +#define LLVM_IR_BASICBLOCK_H -#include "llvm/Instruction.h" -#include "llvm/SymbolTableListTraits.h" -#include "llvm/ADT/ilist.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/SymbolTableListTraits.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -29,19 +29,19 @@ class BlockAddress; template<> struct ilist_traits<Instruction> : public SymbolTableListTraits<Instruction, BasicBlock> { - // createSentinel is used to get hold of a node that marks the end of - // the list... - // The sentinel is relative to this instance, so we use a non-static - // method. + + /// \brief Return a node that marks the end of a list. + /// + /// The sentinel is relative to this instance, so we use a non-static + /// method. Instruction *createSentinel() const { - // since i(p)lists always publicly derive from the corresponding - // traits, placing a data member in this class will augment i(p)list. - // But since the NodeTy is expected to publicly derive from - // ilist_node<NodeTy>, there is a legal viable downcast from it - // to NodeTy. We use this trick to superpose i(p)list with a "ghostly" - // NodeTy, which becomes the sentinel. Dereferencing the sentinel is - // forbidden (save the ilist_node<NodeTy>) so no one will ever notice - // the superposition. + // Since i(p)lists always publicly derive from their corresponding traits, + // placing a data member in this class will augment the i(p)list. But since + // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>, + // there is a legal viable downcast from it to NodeTy. We use this trick to + // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the + // sentinel. Dereferencing the sentinel is forbidden (save the + // ilist_node<NodeTy>), so no one will ever notice the superposition. return static_cast<Instruction*>(&Sentinel); } static void destroySentinel(Instruction*) {} @@ -53,6 +53,8 @@ private: mutable ilist_half_node<Instruction> Sentinel; }; +/// \brief LLVM Basic Block Representation +/// /// This represents a single basic block in LLVM. A basic block is simply a /// container of instructions that execute sequentially. Basic blocks are Values /// because they are referenced by instructions such as branches and switch @@ -66,7 +68,6 @@ private: /// occur because it may be useful in the intermediate stage of constructing or /// modifying a program. However, the verifier will ensure that basic blocks /// are "well formed". -/// @brief LLVM Basic Block Representation class BasicBlock : public Value, // Basic blocks are data objects also public ilist_node<BasicBlock> { friend class BlockAddress; @@ -82,102 +83,104 @@ private: BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION; void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION; - /// BasicBlock ctor - If the function parameter is specified, the basic block - /// is automatically inserted at either the end of the function (if - /// InsertBefore is null), or before the specified basic block. + /// \brief Constructor. /// + /// If the function parameter is specified, the basic block is automatically + /// inserted at either the end of the function (if InsertBefore is null), or + /// before the specified basic block. explicit BasicBlock(LLVMContext &C, const Twine &Name = "", Function *Parent = 0, BasicBlock *InsertBefore = 0); public: - /// getContext - Get the context in which this basic block lives. + /// \brief Get the context in which this basic block lives. LLVMContext &getContext() const; /// Instruction iterators... - typedef InstListType::iterator iterator; - typedef InstListType::const_iterator const_iterator; + typedef InstListType::iterator iterator; + typedef InstListType::const_iterator const_iterator; + typedef InstListType::reverse_iterator reverse_iterator; + typedef InstListType::const_reverse_iterator const_reverse_iterator; - /// Create - Creates a new BasicBlock. If the Parent parameter is specified, - /// the basic block is automatically inserted at either the end of the - /// function (if InsertBefore is 0), or before the specified basic block. + /// \brief Creates a new BasicBlock. + /// + /// If the Parent parameter is specified, the basic block is automatically + /// inserted at either the end of the function (if InsertBefore is 0), or + /// before the specified basic block. static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "", Function *Parent = 0,BasicBlock *InsertBefore = 0) { return new BasicBlock(Context, Name, Parent, InsertBefore); } ~BasicBlock(); - /// getParent - Return the enclosing method, or null if none - /// + /// \brief Return the enclosing method, or null if none. const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } - /// getTerminator() - If this is a well formed basic block, then this returns - /// a pointer to the terminator instruction. If it is not, then you get a - /// null pointer back. - /// + /// \brief Returns the terminator instruction if the block is well formed or + /// null if the block is not well formed. TerminatorInst *getTerminator(); const TerminatorInst *getTerminator() const; - /// Returns a pointer to the first instructon in this block that is not a - /// PHINode instruction. When adding instruction to the beginning of the - /// basic block, they should be added before the returned value, not before - /// the first instruction, which might be PHI. - /// Returns 0 is there's no non-PHI instruction. + /// \brief Returns a pointer to the first instruction in this block that is + /// not a PHINode instruction. + /// + /// When adding instructions to the beginning of the basic block, they should + /// be added before the returned value, not before the first instruction, + /// which might be PHI. Returns 0 is there's no non-PHI instruction. Instruction* getFirstNonPHI(); const Instruction* getFirstNonPHI() const { return const_cast<BasicBlock*>(this)->getFirstNonPHI(); } - // Same as above, but also skip debug intrinsics. + /// \brief Returns a pointer to the first instruction in this block that is not + /// a PHINode or a debug intrinsic. Instruction* getFirstNonPHIOrDbg(); const Instruction* getFirstNonPHIOrDbg() const { return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg(); } - // Same as above, but also skip lifetime intrinsics. + /// \brief Returns a pointer to the first instruction in this block that is not + /// a PHINode, a debug intrinsic, or a lifetime intrinsic. Instruction* getFirstNonPHIOrDbgOrLifetime(); const Instruction* getFirstNonPHIOrDbgOrLifetime() const { return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime(); } - /// getFirstInsertionPt - Returns an iterator to the first instruction in this - /// block that is suitable for inserting a non-PHI instruction. In particular, - /// it skips all PHIs and LandingPad instructions. + /// \brief Returns an iterator to the first instruction in this block that is + /// suitable for inserting a non-PHI instruction. + /// + /// In particular, it skips all PHIs and LandingPad instructions. iterator getFirstInsertionPt(); const_iterator getFirstInsertionPt() const { return const_cast<BasicBlock*>(this)->getFirstInsertionPt(); } - /// removeFromParent - This method unlinks 'this' from the containing - /// function, but does not delete it. - /// + /// \brief Unlink 'this' from the containing function, but do not delete it. void removeFromParent(); - /// eraseFromParent - This method unlinks 'this' from the containing function - /// and deletes it. - /// + /// \brief Unlink 'this' from the containing function and delete it. void eraseFromParent(); - /// moveBefore - Unlink this basic block from its current function and - /// insert it into the function that MovePos lives in, right before MovePos. + /// \brief Unlink this basic block from its current function and insert it + /// into the function that \p MovePos lives in, right before \p MovePos. void moveBefore(BasicBlock *MovePos); - /// moveAfter - Unlink this basic block from its current function and - /// insert it into the function that MovePos lives in, right after MovePos. + /// \brief Unlink this basic block from its current function and insert it + /// right after \p MovePos in the function \p MovePos lives in. void moveAfter(BasicBlock *MovePos); - /// getSinglePredecessor - If this basic block has a single predecessor block, - /// return the block, otherwise return a null pointer. + /// \brief Return this block if it has a single predecessor block. Otherwise + /// return a null pointer. BasicBlock *getSinglePredecessor(); const BasicBlock *getSinglePredecessor() const { return const_cast<BasicBlock*>(this)->getSinglePredecessor(); } - /// getUniquePredecessor - If this basic block has a unique predecessor block, - /// return the block, otherwise return a null pointer. + /// \brief Return this block if it has a unique predecessor block. Otherwise return a null pointer. + /// /// Note that unique predecessor doesn't mean single edge, there can be - /// multiple edges from the unique predecessor to this block (for example - /// a switch statement with multiple cases having the same destination). + /// multiple edges from the unique predecessor to this block (for example a + /// switch statement with multiple cases having the same destination). BasicBlock *getUniquePredecessor(); const BasicBlock *getUniquePredecessor() const { return const_cast<BasicBlock*>(this)->getUniquePredecessor(); @@ -191,6 +194,11 @@ public: inline iterator end () { return InstList.end(); } inline const_iterator end () const { return InstList.end(); } + inline reverse_iterator rbegin() { return InstList.rbegin(); } + inline const_reverse_iterator rbegin() const { return InstList.rbegin(); } + inline reverse_iterator rend () { return InstList.rend(); } + inline const_reverse_iterator rend () const { return InstList.rend(); } + inline size_t size() const { return InstList.size(); } inline bool empty() const { return InstList.empty(); } inline const Instruction &front() const { return InstList.front(); } @@ -198,49 +206,52 @@ public: inline const Instruction &back() const { return InstList.back(); } inline Instruction &back() { return InstList.back(); } - /// getInstList() - Return the underlying instruction list container. You - /// need to access it directly if you want to modify it currently. + /// \brief Return the underlying instruction list container. /// + /// Currently you need to access the underlying instruction list container + /// directly if you want to modify it. const InstListType &getInstList() const { return InstList; } InstListType &getInstList() { return InstList; } - /// getSublistAccess() - returns pointer to member of instruction list + /// \brief Returns a pointer to a member of the instruction list. static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) { return &BasicBlock::InstList; } - /// getValueSymbolTable() - returns pointer to symbol table (if any) + /// \brief Returns a pointer to the symbol table if one exists. ValueSymbolTable *getValueSymbolTable(); - /// Methods for support type inquiry through isa, cast, and dyn_cast: + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Value *V) { return V->getValueID() == Value::BasicBlockVal; } - /// dropAllReferences() - This function causes all the subinstructions to "let - /// go" of all references that they are maintaining. This allows one to - /// 'delete' a whole class at a time, even though there may be circular - /// references... first all references are dropped, and all use counts go to - /// zero. Then everything is delete'd for real. Note that no operations are - /// valid on an object that has "dropped all references", except operator - /// delete. + /// \brief Cause all subinstructions to "let go" of all the references that + /// said subinstructions are maintaining. /// + /// This allows one to 'delete' a whole class at a time, even though there may + /// be circular references... first all references are dropped, and all use + /// counts go to zero. Then everything is delete'd for real. Note that no + /// operations are valid on an object that has "dropped all references", + /// except operator delete. void dropAllReferences(); - /// removePredecessor - This method is used to notify a BasicBlock that the - /// specified Predecessor of the block is no longer able to reach it. This is - /// actually not used to update the Predecessor list, but is actually used to - /// update the PHI nodes that reside in the block. Note that this should be - /// called while the predecessor still refers to this block. + /// \brief Notify the BasicBlock that the predecessor \p Pred is no longer + /// able to reach it. /// + /// This is actually not used to update the Predecessor list, but is actually + /// used to update the PHI nodes that reside in the block. Note that this + /// should be called while the predecessor still refers to this block. void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false); - /// splitBasicBlock - This splits a basic block into two at the specified - /// instruction. Note that all instructions BEFORE the specified iterator - /// stay as part of the original basic block, an unconditional branch is added - /// to the original BB, and the rest of the instructions in the BB are moved - /// to the new BB, including the old terminator. The newly formed BasicBlock - /// is returned. This function invalidates the specified iterator. + /// \brief Split the basic block into two basic blocks at the specified + /// instruction. + /// + /// Note that all instructions BEFORE the specified iterator stay as part of + /// the original basic block, an unconditional branch is added to the original + /// BB, and the rest of the instructions in the BB are moved to the new BB, + /// including the old terminator. The newly formed BasicBlock is returned. + /// This function invalidates the specified iterator. /// /// Note that this only works on well formed basic blocks (must have a /// terminator), and 'I' must not be the end of instruction list (which would @@ -249,37 +260,39 @@ public: /// /// Also note that this doesn't preserve any passes. To split blocks while /// keeping loop information consistent, use the SplitBlock utility function. - /// BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = ""); - /// hasAddressTaken - returns true if there are any uses of this basic block - /// other than direct branches, switches, etc. to it. + /// \brief Returns true if there are any uses of this basic block other than + /// direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } - /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors - /// to refer to basic block New instead of to us. + /// \brief Update all phi nodes in this basic block's successors to refer to + /// basic block \p New instead of to it. void replaceSuccessorsPhiUsesWith(BasicBlock *New); - /// isLandingPad - Return true if this basic block is a landing pad. I.e., - /// it's the destination of the 'unwind' edge of an invoke instruction. + /// \brief Return true if this basic block is a landing pad. + /// + /// Being a ``landing pad'' means that the basic block is the destination of + /// the 'unwind' edge of an invoke instruction. bool isLandingPad() const; - /// getLandingPadInst() - Return the landingpad instruction associated with - /// the landing pad. + /// \brief Return the landingpad instruction associated with the landing pad. LandingPadInst *getLandingPadInst(); const LandingPadInst *getLandingPadInst() const; private: - /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress - /// objects using it. This is almost always 0, sometimes one, possibly but - /// almost never 2, and inconceivably 3 or more. + /// \brief Increment the internal refcount of the number of BlockAddresses + /// referencing this BasicBlock by \p Amt. + /// + /// This is almost always 0, sometimes one possibly, but almost never 2, and + /// inconceivably 3 or more. void AdjustBlockAddressRefCount(int Amt) { setValueSubclassData(getSubclassDataFromValue()+Amt); assert((int)(signed char)getSubclassDataFromValue() >= 0 && "Refcount wrap-around"); } - // Shadow Value::setValueSubclassData with a private forwarding method so that - // any future subclasses cannot accidentally use it. + /// \brief Shadow Value::setValueSubclassData with a private forwarding method + /// so that any future subclasses cannot accidentally use it. void setValueSubclassData(unsigned short D) { Value::setValueSubclassData(D); } diff --git a/contrib/llvm/include/llvm/CallingConv.h b/contrib/llvm/include/llvm/IR/CallingConv.h index 053f4eb..6f3ab20 100644 --- a/contrib/llvm/include/llvm/CallingConv.h +++ b/contrib/llvm/include/llvm/IR/CallingConv.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CALLINGCONV_H -#define LLVM_CALLINGCONV_H +#ifndef LLVM_IR_CALLINGCONV_H +#define LLVM_IR_CALLINGCONV_H namespace llvm { @@ -47,6 +47,10 @@ namespace CallingConv { // GHC - Calling convention used by the Glasgow Haskell Compiler (GHC). GHC = 10, + // HiPE - Calling convention used by the High-Performance Erlang Compiler + // (HiPE). + HiPE = 11, + // Target - This is the start of the target-specific calling conventions, // e.g. fastcall and thiscall on X86. FirstTargetCC = 64, diff --git a/contrib/llvm/include/llvm/Constant.h b/contrib/llvm/include/llvm/IR/Constant.h index 0ddd1db..26bad1d 100644 --- a/contrib/llvm/include/llvm/Constant.h +++ b/contrib/llvm/include/llvm/IR/Constant.h @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CONSTANT_H -#define LLVM_CONSTANT_H +#ifndef LLVM_IR_CONSTANT_H +#define LLVM_IR_CONSTANT_H -#include "llvm/User.h" +#include "llvm/IR/User.h" namespace llvm { class APInt; @@ -61,6 +61,9 @@ public: /// by getZeroValueForNegation. bool isNegativeZeroValue() const; + /// Return true if the value is negative zero or null value. + bool isZeroValue() const; + /// canTrap - Return true if evaluation of this constant could trap. This is /// true for things like constant expressions that could divide by zero. bool canTrap() const; @@ -100,7 +103,15 @@ public: /// 'this' is a constant expr. Constant *getAggregateElement(unsigned Elt) const; Constant *getAggregateElement(Constant *Elt) const; - + + /// getSplatValue - If this is a splat vector constant, meaning that all of + /// the elements have the same value, return that value. Otherwise return 0. + Constant *getSplatValue() const; + + /// If C is a constant integer then return its value, otherwise C must be a + /// vector of constant integers, all equal, and the common value is returned. + const APInt &getUniqueInteger() const; + /// destroyConstant - Called if some element of this constant is no longer /// valid. At this point only other constants may be on the use_list for this /// constant. Any constants on our Use list must also be destroy'd. The diff --git a/contrib/llvm/include/llvm/Constants.h b/contrib/llvm/include/llvm/IR/Constants.h index 7f94ef4..ad258f9 100644 --- a/contrib/llvm/include/llvm/Constants.h +++ b/contrib/llvm/include/llvm/IR/Constants.h @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// // /// @file -/// This file contains the declarations for the subclasses of Constant, +/// This file contains the declarations for the subclasses of Constant, /// which represent the different flavors of constant values that live in LLVM. -/// Note that Constants are immutable (once created they never change) and are +/// Note that Constants are immutable (once created they never change) and are /// fully shared by structural equivalence. This means that two structurally /// equivalent constants will always have the same address. Constant's are /// created on demand as needed and never deleted: thus clients don't have to @@ -18,14 +18,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CONSTANTS_H -#define LLVM_CONSTANTS_H +#ifndef LLVM_IR_CONSTANTS_H +#define LLVM_IR_CONSTANTS_H -#include "llvm/Constant.h" -#include "llvm/OperandTraits.h" -#include "llvm/ADT/APInt.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/OperandTraits.h" namespace llvm { @@ -44,7 +44,7 @@ template<class ConstantClass, class TypeClass> struct ConvertConstantType; //===----------------------------------------------------------------------===// -/// This is the shared class of boolean and integer constants. This class +/// This is the shared class of boolean and integer constants. This class /// represents both boolean and integral constants. /// @brief Class for constant integers. class ConstantInt : public Constant { @@ -63,11 +63,11 @@ public: static ConstantInt *getFalse(LLVMContext &Context); static Constant *getTrue(Type *Ty); static Constant *getFalse(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. static Constant *get(Type *Ty, uint64_t V, bool isSigned = false); - + /// Return a ConstantInt with the specified integer value for the specified /// type. If the type is wider than 64 bits, the value will be zero-extended /// to fit the type, unless isSigned is true, in which case the value will @@ -84,27 +84,27 @@ public: /// @brief Get a ConstantInt for a specific signed value. static ConstantInt *getSigned(IntegerType *Ty, int64_t V); static Constant *getSigned(Type *Ty, int64_t V); - + /// Return a ConstantInt with the specified value and an implied Type. The /// type is the integer type that corresponds to the bit width of the value. static ConstantInt *get(LLVMContext &Context, const APInt &V); /// Return a ConstantInt constructed from the string strStart with the given - /// radix. + /// radix. static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t radix); - + /// If Ty is a vector type, return a Constant with a splat of the given /// value. Otherwise return a ConstantInt for the given value. static Constant *get(Type* Ty, const APInt& V); - + /// Return the constant as an APInt value reference. This allows clients to /// obtain a copy of the value, with all its precision in tact. /// @brief Return the constant's value. inline const APInt &getValue() const { return Val; } - + /// getBitWidth - Return the bitwidth of this constant. unsigned getBitWidth() const { return Val.getBitWidth(); } @@ -126,8 +126,8 @@ public: return Val.getSExtValue(); } - /// A helper method that can be used to determine if the constant contained - /// within is equal to a constant. This only works for very small values, + /// A helper method that can be used to determine if the constant contained + /// within is equal to a constant. This only works for very small values, /// because this is all that can be represented with all types. /// @brief Determine if this constant's value is same as an unsigned char. bool equalsInt(uint64_t V) const { @@ -141,11 +141,11 @@ public: return reinterpret_cast<IntegerType*>(Value::getType()); } - /// This static method returns true if the type Ty is big enough to - /// represent the value V. This can be used to avoid having the get method + /// This static method returns true if the type Ty is big enough to + /// represent the value V. This can be used to avoid having the get method /// assert when V is larger than Ty can represent. Note that there are two /// versions of this method, one for unsigned and one for signed integers. - /// Although ConstantInt canonicalizes everything to an unsigned integer, + /// Although ConstantInt canonicalizes everything to an unsigned integer, /// the signed version avoids callers having to convert a signed quantity /// to the appropriate unsigned type before calling the method. /// @returns true if V is a valid value for type Ty @@ -162,7 +162,7 @@ public: return Val == 0; } - /// This is just a convenience method to make client code smaller for a + /// This is just a convenience method to make client code smaller for a /// common case. It also correctly performs the comparison without the /// potential for an assertion from getZExtValue(). /// @brief Determine if the value is one. @@ -174,17 +174,17 @@ public: /// to true. /// @returns true iff this constant's bits are all set to true. /// @brief Determine if the value is all ones. - bool isMinusOne() const { + bool isMinusOne() const { return Val.isAllOnesValue(); } /// This function will return true iff this constant represents the largest /// value that may be represented by the constant's type. - /// @returns true iff this is the largest value that may be represented + /// @returns true iff this is the largest value that may be represented /// by this type. /// @brief Determine if the value is maximal. bool isMaxValue(bool isSigned) const { - if (isSigned) + if (isSigned) return Val.isMaxSignedValue(); else return Val.isMaxValue(); @@ -192,11 +192,11 @@ public: /// This function will return true iff this constant represents the smallest /// value that may be represented by this constant's type. - /// @returns true if this is the smallest value that may be represented by + /// @returns true if this is the smallest value that may be represented by /// this type. /// @brief Determine if the value is minimal. bool isMinValue(bool isSigned) const { - if (isSigned) + if (isSigned) return Val.isMinSignedValue(); else return Val.isMinValue(); @@ -248,7 +248,7 @@ public: /// method returns the negative zero constant for floating point or vector /// floating point types; for all other types, it returns the null value. static Constant *getZeroValueForNegation(Type *Ty); - + /// get() - This returns a ConstantFP, or a vector containing a splat of a /// ConstantFP, for the specified value in the specified type. This should /// only be used for simple constant values like 2.0/1.0 etc, that are @@ -258,7 +258,7 @@ public: static ConstantFP *get(LLVMContext &Context, const APFloat &V); static ConstantFP *getNegativeZero(Type* Ty); static ConstantFP *getInfinity(Type *Ty, bool Negative = false); - + /// isValueValidForType - return true if Ty is big enough to represent V. static bool isValueValidForType(Type *Ty, const APFloat &V); inline const APFloat &getValueAPF() const { return Val; } @@ -308,7 +308,7 @@ protected: } public: static ConstantAggregateZero *get(Type *Ty); - + virtual void destroyConstant(); /// getSequentialElement - If this CAZ has array or vector type, return a zero @@ -346,7 +346,7 @@ protected: public: // ConstantArray accessors static Constant *get(ArrayType *T, ArrayRef<Constant*> V); - + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -392,7 +392,7 @@ public: static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) { return get(getTypeForElements(V, Packed), V); } - static Constant *getAnon(LLVMContext &Ctx, + static Constant *getAnon(LLVMContext &Ctx, ArrayRef<Constant*> V, bool Packed = false) { return get(getTypeForElements(Ctx, V, Packed), V); } @@ -405,7 +405,7 @@ public: static StructType *getTypeForElements(LLVMContext &Ctx, ArrayRef<Constant*> V, bool Packed = false); - + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -443,11 +443,11 @@ protected: public: // ConstantVector accessors static Constant *get(ArrayRef<Constant*> V); - + /// getSplat - Return a ConstantVector with the specified constant in each /// element. static Constant *getSplat(unsigned NumElts, Constant *Elt); - + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -512,7 +512,7 @@ public: return V->getValueID() == ConstantPointerNullVal; } }; - + //===----------------------------------------------------------------------===// /// ConstantDataSequential - A vector or array constant whose element type is a /// simple 1/2/4/8-byte integer or float/double, and whose elements are just @@ -527,7 +527,7 @@ class ConstantDataSequential : public Constant { /// DataElements - A pointer to the bytes underlying this constant (which is /// owned by the uniquing StringMap). const char *DataElements; - + /// Next - This forms a link list of ConstantDataSequential nodes that have /// the same value but different type. For example, 0,0,0,1 could be a 4 /// element array of i8, or a 1-element array of i32. They'll both end up in @@ -539,7 +539,7 @@ protected: explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data) : Constant(ty, VT, 0, 0), DataElements(Data), Next(0) {} ~ConstantDataSequential() { delete Next; } - + static Constant *getImpl(StringRef Bytes, Type *Ty); protected: @@ -548,13 +548,13 @@ protected: return User::operator new(s, 0); } public: - + /// isElementTypeCompatible - Return true if a ConstantDataSequential can be /// formed with a vector or array of the specified element type. /// ConstantDataArray only works with normal float and int types that are /// stored densely in memory, not with things like i42 or x86_f80. static bool isElementTypeCompatible(const Type *Ty); - + /// getElementAsInteger - If this is a sequential container of integers (of /// any size), return the specified element in the low bits of a uint64_t. uint64_t getElementAsInteger(unsigned i) const; @@ -566,26 +566,26 @@ public: /// getElementAsFloat - If this is an sequential container of floats, return /// the specified element as a float. float getElementAsFloat(unsigned i) const; - + /// getElementAsDouble - If this is an sequential container of doubles, return /// the specified element as a double. double getElementAsDouble(unsigned i) const; - + /// getElementAsConstant - Return a Constant for a specified index's element. /// Note that this has to compute a new constant to return, so it isn't as /// efficient as getElementAsInteger/Float/Double. Constant *getElementAsConstant(unsigned i) const; - + /// getType - Specialize the getType() method to always return a /// SequentialType, which reduces the amount of casting needed in parts of the /// compiler. inline SequentialType *getType() const { return reinterpret_cast<SequentialType*>(Value::getType()); } - + /// getElementType - Return the element type of the array/vector. Type *getElementType() const; - + /// getNumElements - Return the number of elements in the array or vector. unsigned getNumElements() const; @@ -594,14 +594,14 @@ public: /// byte. uint64_t getElementByteSize() const; - + /// isString - This method returns true if this is an array of i8. bool isString() const; - + /// isCString - This method returns true if the array "isString", ends with a /// nul byte, and does not contains any other nul bytes. bool isCString() const; - + /// getAsString - If this array is isString(), then this method returns the /// array as a StringRef. Otherwise, it asserts out. /// @@ -609,7 +609,7 @@ public: assert(isString() && "Not a string"); return getRawDataValues(); } - + /// getAsCString - If this array is isCString(), then this method returns the /// array (without the trailing null byte) as a StringRef. Otherwise, it /// asserts out. @@ -619,14 +619,14 @@ public: StringRef Str = getAsString(); return Str.substr(0, Str.size()-1); } - + /// getRawDataValues - Return the raw, underlying, bytes of this data. Note /// that this is an extremely tricky thing to work with, as it exposes the /// host endianness of the data elements. StringRef getRawDataValues() const; - + virtual void destroyConstant(); - + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const Value *V) { @@ -656,7 +656,7 @@ protected: return User::operator new(s, 0); } public: - + /// get() constructors - Return a constant with array type with an element /// count and element type matching the ArrayRef passed in. Note that this /// can return a ConstantAggregateZero object. @@ -666,7 +666,7 @@ public: static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts); static Constant *get(LLVMContext &Context, ArrayRef<float> Elts); static Constant *get(LLVMContext &Context, ArrayRef<double> Elts); - + /// getString - This method constructs a CDS and initializes it with a text /// string. The default behavior (AddNull==true) causes a null terminator to /// be placed at the end of the array (increasing the length of the string by @@ -681,14 +681,14 @@ public: inline ArrayType *getType() const { return reinterpret_cast<ArrayType*>(Value::getType()); } - + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const Value *V) { return V->getValueID() == ConstantDataArrayVal; } }; - + //===----------------------------------------------------------------------===// /// ConstantDataVector - A vector constant whose element type is a simple /// 1/2/4/8-byte integer or float/double, and whose elements are just simple @@ -708,7 +708,7 @@ protected: return User::operator new(s, 0); } public: - + /// get() constructors - Return a constant with vector type with an element /// count and element type matching the ArrayRef passed in. Note that this /// can return a ConstantAggregateZero object. @@ -718,7 +718,7 @@ public: static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts); static Constant *get(LLVMContext &Context, ArrayRef<float> Elts); static Constant *get(LLVMContext &Context, ArrayRef<double> Elts); - + /// getSplat - Return a ConstantVector with the specified constant in each /// element. The specified constant has to be a of a compatible type (i8/i16/ /// i32/i64/float/double) and must be a ConstantFP or ConstantInt. @@ -727,14 +727,14 @@ public: /// getSplatValue - If this is a splat constant, meaning that all of the /// elements have the same value, return that value. Otherwise return NULL. Constant *getSplatValue() const; - + /// getType - Specialize the getType() method to always return a VectorType, /// which reduces the amount of casting needed in parts of the compiler. /// inline VectorType *getType() const { return reinterpret_cast<VectorType*>(Value::getType()); } - + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const Value *V) { @@ -753,20 +753,20 @@ class BlockAddress : public Constant { public: /// get - Return a BlockAddress for the specified function and basic block. static BlockAddress *get(Function *F, BasicBlock *BB); - + /// get - Return a BlockAddress for the specified basic block. The basic /// block must be embedded into a function. static BlockAddress *get(BasicBlock *BB); - + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - + Function *getFunction() const { return (Function*)Op<0>().get(); } BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } - + virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); - + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == BlockAddressVal; @@ -779,7 +779,7 @@ struct OperandTraits<BlockAddress> : }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value) - + //===----------------------------------------------------------------------===// /// ConstantExpr - a constant value that is initialized with an expression using @@ -809,14 +809,14 @@ public: /// getAlignOf constant expr - computes the alignment of a type in a target /// independent way (Note: the return type is an i64). static Constant *getAlignOf(Type *Ty); - + /// getSizeOf constant expr - computes the (alloc) size of a type (in /// address-units, not bits) in a target independent way (Note: the return /// type is an i64). /// static Constant *getSizeOf(Type *Ty); - /// getOffsetOf constant expr - computes the offset of a struct field in a + /// getOffsetOf constant expr - computes the offset of a struct field in a /// target independent way (Note: the return type is an i64). /// static Constant *getOffsetOf(StructType *STy, unsigned FieldNo); @@ -825,7 +825,7 @@ public: /// which supports any aggregate type, and any Constant index. /// static Constant *getOffsetOf(Type *Ty, Constant *FieldNo); - + static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false); static Constant *getFNeg(Constant *C); static Constant *getNot(Constant *C); @@ -931,7 +931,7 @@ public: Type *Ty ///< The type to zext or bitcast C to ); - // @brief Create a SExt or BitCast cast constant expression + // @brief Create a SExt or BitCast cast constant expression static Constant *getSExtOrBitCast( Constant *C, ///< The constant to sext or bitcast Type *Ty ///< The type to sext or bitcast C to @@ -951,14 +951,14 @@ public: /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts static Constant *getIntegerCast( - Constant *C, ///< The integer constant to be casted + Constant *C, ///< The integer constant to be casted Type *Ty, ///< The integer type to cast to bool isSigned ///< Whether C should be treated as signed or not ); /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts static Constant *getFPCast( - Constant *C, ///< The integer constant to be casted + Constant *C, ///< The integer constant to be casted Type *Ty ///< The integer type to cast to ); @@ -1062,7 +1062,7 @@ public: /// getWithOperandReplaced - Return a constant expression identical to this /// one, but with the specified operand set to the specified value. Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const; - + /// getWithOperands - This returns the current constant expression with the /// operands replaced with the specified values. The specified array must /// have the same number of operands as our current one. @@ -1076,6 +1076,15 @@ public: /// current one. Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const; + /// getAsInstruction - Returns an Instruction which implements the same operation + /// as this ConstantExpr. The instruction is not linked to any basic block. + /// + /// A better approach to this could be to have a constructor for Instruction + /// which would take a ConstantExpr parameter, but that would have spread + /// implementation details of ConstantExpr outside of Constants.cpp, which + /// would make it harder to remove ConstantExprs altogether. + Instruction *getAsInstruction(); + virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -1083,7 +1092,7 @@ public: static inline bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; } - + private: // Shadow Value::setValueSubclassData with a private forwarding method so that // subclasses cannot accidentally use it. @@ -1128,11 +1137,11 @@ public: /// getSequentialElement - If this Undef has array or vector type, return a /// undef with the right element type. UndefValue *getSequentialElement() const; - + /// getStructElement - If this undef has struct type, return a undef with the /// right element type for the specified element. UndefValue *getStructElement(unsigned Elt) const; - + /// getElementValue - Return an undef of the right value for the specified GEP /// index. UndefValue *getElementValue(Constant *C) const; diff --git a/contrib/llvm/include/llvm/DataLayout.h b/contrib/llvm/include/llvm/IR/DataLayout.h index 24ad05f..547d857 100644 --- a/contrib/llvm/include/llvm/DataLayout.h +++ b/contrib/llvm/include/llvm/IR/DataLayout.h @@ -17,12 +17,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DATALAYOUT_H -#define LLVM_DATALAYOUT_H +#ifndef LLVM_IR_DATALAYOUT_H +#define LLVM_IR_DATALAYOUT_H -#include "llvm/Pass.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -39,6 +41,7 @@ class ArrayRef; /// Enum used to categorize the alignment types stored by LayoutAlignElem enum AlignTypeEnum { + INVALID_ALIGN = 0, ///< An invalid alignment INTEGER_ALIGN = 'i', ///< Integer type alignment VECTOR_ALIGN = 'v', ///< Vector type alignment FLOAT_ALIGN = 'f', ///< Floating point type alignment @@ -99,7 +102,7 @@ private: SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. - /// Alignments- Where the primitive type alignment data is stored. + /// Alignments - Where the primitive type alignment data is stored. /// /// @sa init(). /// @note Could support multiple size pointer alignments, e.g., 32-bit @@ -148,9 +151,9 @@ private: return &align != &InvalidPointerElem; } - /// Initialise a DataLayout object with default values, ensure that the - /// target data pass is registered. - void init(); + /// Parses a target data specification string. Assert if the string is + /// malformed. + void parseSpecifier(StringRef LayoutDescription); public: /// Default ctor. @@ -162,23 +165,16 @@ public: /// Constructs a DataLayout from a specification string. See init(). explicit DataLayout(StringRef LayoutDescription) : ImmutablePass(ID) { - std::string errMsg = parseSpecifier(LayoutDescription, this); - assert(errMsg == "" && "Invalid target data layout string."); - (void)errMsg; + init(LayoutDescription); } - /// Parses a target data specification string. Returns an error message - /// if the string is malformed, or the empty string on success. Optionally - /// initialises a DataLayout object if passed a non-null pointer. - static std::string parseSpecifier(StringRef LayoutDescription, - DataLayout* td = 0); - /// Initialize target data from properties stored in the module. explicit DataLayout(const Module *M); DataLayout(const DataLayout &TD) : ImmutablePass(ID), LittleEndian(TD.isLittleEndian()), + StackNaturalAlign(TD.StackNaturalAlign), LegalIntWidths(TD.LegalIntWidths), Alignments(TD.Alignments), Pointers(TD.Pointers), @@ -187,6 +183,14 @@ public: ~DataLayout(); // Not virtual, do not subclass this class + /// DataLayout is an immutable pass, but holds state. This allows the pass + /// manager to clear its mutable state. + bool doFinalization(Module &M); + + /// Parse a data layout string (with fallback to default values). Ensure that + /// the data layout pass is registered. + void init(StringRef LayoutDescription); + /// Layout endianness... bool isLittleEndian() const { return LittleEndian; } bool isBigEndian() const { return !LittleEndian; } @@ -285,7 +289,8 @@ public: /// getTypeSizeInBits - Return the number of bits necessary to hold the /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. - uint64_t getTypeSizeInBits(Type* Ty) const; + /// The type passed must have a size (Type::isSized() must return true). + uint64_t getTypeSizeInBits(Type *Ty) const; /// getTypeStoreSize - Return the maximum number of bytes that may be /// overwritten by storing the specified type. For example, returns 5 @@ -305,7 +310,7 @@ public: /// of the specified type, including alignment padding. This is the amount /// that alloca reserves for this type. For example, returns 12 or 16 for /// x86_fp80, depending on alignment. - uint64_t getTypeAllocSize(Type* Ty) const { + uint64_t getTypeAllocSize(Type *Ty) const { // Round up to the next alignment boundary. return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); } @@ -314,7 +319,7 @@ public: /// objects of the specified type, including alignment padding; always a /// multiple of 8. This is the amount that alloca reserves for this type. /// For example, returns 96 or 128 for x86_fp80, depending on alignment. - uint64_t getTypeAllocSizeInBits(Type* Ty) const { + uint64_t getTypeAllocSizeInBits(Type *Ty) const { return 8*getTypeAllocSize(Ty); } @@ -326,19 +331,16 @@ public: /// an integer type of the specified bitwidth. unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; - /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment /// for the specified type when it is part of a call frame. unsigned getCallFrameTypeAlignment(Type *Ty) const; - /// getPrefTypeAlignment - Return the preferred stack/global alignment for /// the specified type. This is always at least as good as the ABI alignment. unsigned getPrefTypeAlignment(Type *Ty) const; /// getPreferredTypeAlignmentShift - Return the preferred alignment for the /// specified type, returned as log2 of the value (a shift amount). - /// unsigned getPreferredTypeAlignmentShift(Type *Ty) const; /// getIntPtrType - Return an integer type with size at least as big as that @@ -350,9 +352,12 @@ public: /// type. Type *getIntPtrType(Type *) const; + /// getSmallestLegalIntType - Return the smallest integer type with size at + /// least as big as Width bits. + Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; + /// getIndexedOffset - return the offset from the beginning of the type for /// the specified indices. This is used to implement getelementptr. - /// uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const; /// getStructLayout - Return a StructLayout object, indicating the alignment @@ -424,6 +429,49 @@ private: StructLayout(StructType *ST, const DataLayout &TD); }; + +// The implementation of this method is provided inline as it is particularly +// well suited to constant folding when called on a specific Type subclass. +inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const { + assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); + switch (Ty->getTypeID()) { + case Type::LabelTyID: + return getPointerSizeInBits(0); + case Type::PointerTyID: + return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); + case Type::ArrayTyID: { + ArrayType *ATy = cast<ArrayType>(Ty); + return ATy->getNumElements() * + getTypeAllocSizeInBits(ATy->getElementType()); + } + case Type::StructTyID: + // Get the layout annotation... which is lazily created on demand. + return getStructLayout(cast<StructType>(Ty))->getSizeInBits(); + case Type::IntegerTyID: + return cast<IntegerType>(Ty)->getBitWidth(); + case Type::HalfTyID: + return 16; + case Type::FloatTyID: + return 32; + case Type::DoubleTyID: + case Type::X86_MMXTyID: + return 64; + case Type::PPC_FP128TyID: + case Type::FP128TyID: + return 128; + // In memory objects this is always aligned to a higher boundary, but + // only 80 bits contain information. + case Type::X86_FP80TyID: + return 80; + case Type::VectorTyID: { + VectorType *VTy = cast<VectorType>(Ty); + return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType()); + } + default: + llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type"); + } +} + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/DerivedTypes.h b/contrib/llvm/include/llvm/IR/DerivedTypes.h index c862c2c..6c00f596 100644 --- a/contrib/llvm/include/llvm/DerivedTypes.h +++ b/contrib/llvm/include/llvm/IR/DerivedTypes.h @@ -15,12 +15,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DERIVED_TYPES_H -#define LLVM_DERIVED_TYPES_H +#ifndef LLVM_IR_DERIVEDTYPES_H +#define LLVM_IR_DERIVEDTYPES_H -#include "llvm/Type.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/IR/Type.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/DataTypes.h" namespace llvm { @@ -84,7 +84,7 @@ public: /// @brief Is this a power-of-2 byte-width IntegerType ? bool isPowerOf2ByteWidth() const; - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == IntegerTyID; } @@ -124,7 +124,7 @@ public: param_iterator param_begin() const { return ContainedTys + 1; } param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } - // Parameter type accessors. + /// Parameter type accessors. Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } /// getNumParams - Return the number of fixed parameters this function type @@ -132,7 +132,7 @@ public: /// unsigned getNumParams() const { return NumContainedTys - 1; } - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == FunctionTyID; } @@ -154,7 +154,7 @@ public: bool indexValid(const Value *V) const; bool indexValid(unsigned Idx) const; - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || @@ -190,7 +190,7 @@ class StructType : public CompositeType { StructType(LLVMContext &C) : CompositeType(C, StructTyID), SymbolTableEntry(0) {} enum { - // This is the contents of the SubClassData field. + /// This is the contents of the SubClassData field. SCDB_HasBody = 1, SCDB_Packed = 2, SCDB_IsLiteral = 4, @@ -282,14 +282,14 @@ public: /// specified struct. bool isLayoutIdentical(StructType *Other) const; - // Random access to the elements + /// Random access to the elements unsigned getNumElements() const { return NumContainedTys; } Type *getElementType(unsigned N) const { assert(N < NumContainedTys && "Element number out of range!"); return ContainedTys[N]; } - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == StructTyID; } @@ -318,7 +318,7 @@ protected: public: Type *getElementType() const { return ContainedTys[0]; } - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == PointerTyID || @@ -347,7 +347,7 @@ public: uint64_t getNumElements() const { return NumElements; } - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID; } @@ -413,7 +413,7 @@ public: return NumElements * getElementType()->getPrimitiveSizeInBits(); } - // Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == VectorTyID; } @@ -444,7 +444,7 @@ public: /// @brief Return the address space of the Pointer type. inline unsigned getAddressSpace() const { return getSubclassData(); } - // Implement support type inquiry through isa, cast, and dyn_cast. + /// Implement support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == PointerTyID; } diff --git a/contrib/llvm/include/llvm/Function.h b/contrib/llvm/include/llvm/IR/Function.h index e211e9a..f97929f 100644 --- a/contrib/llvm/include/llvm/Function.h +++ b/contrib/llvm/include/llvm/IR/Function.h @@ -15,14 +15,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_FUNCTION_H -#define LLVM_FUNCTION_H - -#include "llvm/GlobalValue.h" -#include "llvm/CallingConv.h" -#include "llvm/BasicBlock.h" -#include "llvm/Argument.h" -#include "llvm/Attributes.h" +#ifndef LLVM_IR_FUNCTION_H +#define LLVM_IR_FUNCTION_H + +#include "llvm/IR/Argument.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -85,11 +85,11 @@ private: BasicBlockListType BasicBlocks; ///< The basic blocks mutable ArgumentListType ArgumentList; ///< The formal arguments ValueSymbolTable *SymTab; ///< Symbol table of args/instructions - AttrListPtr AttributeList; ///< Parameter attributes + AttributeSet AttributeSets; ///< Parameter attributes // HasLazyArguments is stored in Value::SubclassData. /*bool HasLazyArguments;*/ - + // The Calling Convention is stored in Value::SubclassData. /*CallingConv::ID CallingConvention;*/ @@ -113,6 +113,10 @@ private: Function(const Function&) LLVM_DELETED_FUNCTION; void operator=(const Function&) LLVM_DELETED_FUNCTION; + /// Do the actual lookup of an intrinsic ID when the query could not be + /// answered from the cache. + unsigned lookupIntrinsicID() const LLVM_READONLY; + /// Function ctor - If the (optional) Module argument is specified, the /// function is automatically inserted into the end of the function list for /// the module. @@ -131,7 +135,7 @@ public: Type *getReturnType() const; // Return the type of the ret val FunctionType *getFunctionType() const; // Return the FunctionType for me - /// getContext - Return a pointer to the LLVMContext associated with this + /// getContext - Return a pointer to the LLVMContext associated with this /// function, or NULL if this function is not bound to a context yet. LLVMContext &getContext() const; @@ -141,13 +145,15 @@ public: /// getIntrinsicID - This method returns the ID number of the specified /// function, or Intrinsic::not_intrinsic if the function is not an - /// instrinsic, or if the pointer is null. This value is always defined to be + /// intrinsic, or if the pointer is null. This value is always defined to be /// zero to allow easy checking for whether a function is intrinsic or not. /// The particular intrinsic functions which correspond to this value are - /// defined in llvm/Intrinsics.h. + /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context, + /// subsequent requests for the same ID return results much faster from the + /// cache. /// unsigned getIntrinsicID() const LLVM_READONLY; - bool isIntrinsic() const { return getIntrinsicID() != 0; } + bool isIntrinsic() const { return getName().startswith("llvm."); } /// getCallingConv()/setCallingConv(CC) - These method get and set the /// calling convention of this function. The enum values for the known @@ -159,33 +165,36 @@ public: setValueSubclassData((getSubclassDataFromValue() & 1) | (static_cast<unsigned>(CC) << 1)); } - + /// getAttributes - Return the attribute list for this Function. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + AttributeSet getAttributes() const { return AttributeSets; } /// setAttributes - Set the attribute list for this Function. /// - void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; } + void setAttributes(AttributeSet attrs) { AttributeSets = attrs; } - /// getFnAttributes - Return the function attributes for querying. + /// addFnAttr - Add function attributes to this function. /// - Attributes getFnAttributes() const { - return AttributeList.getFnAttributes(); + void addFnAttr(Attribute::AttrKind N) { + setAttributes(AttributeSets.addAttribute(getContext(), + AttributeSet::FunctionIndex, N)); } /// addFnAttr - Add function attributes to this function. /// - void addFnAttr(Attributes::AttrVal N) { - // Function Attributes are stored at ~0 index - addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), N)); + void addFnAttr(StringRef Kind) { + setAttributes( + AttributeSets.addAttribute(getContext(), + AttributeSet::FunctionIndex, Kind)); } - /// removeFnAttr - Remove function attributes from this function. - /// - void removeFnAttr(Attributes N) { - // Function Attributes are stored at ~0 index - removeAttribute(~0U, N); + /// \brief Return true if the function has the attribute. + bool hasFnAttribute(Attribute::AttrKind Kind) const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind); + } + bool hasFnAttribute(StringRef Kind) const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind); } /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm @@ -195,68 +204,74 @@ public: void setGC(const char *Str); void clearGC(); + /// @brief adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attribute::AttrKind attr); - /// getRetAttributes - Return the return attributes for querying. - Attributes getRetAttributes() const { - return AttributeList.getRetAttributes(); - } - - /// getParamAttributes - Return the parameter attributes for querying. - Attributes getParamAttributes(unsigned Idx) const { - return AttributeList.getParamAttributes(Idx); - } + /// @brief adds the attributes to the list of attributes. + void addAttributes(unsigned i, AttributeSet attrs); - /// addAttribute - adds the attribute to the list of attributes. - void addAttribute(unsigned i, Attributes attr); - - /// removeAttribute - removes the attribute from the list of attributes. - void removeAttribute(unsigned i, Attributes attr); + /// @brief removes the attributes from the list of attributes. + void removeAttributes(unsigned i, AttributeSet attr); /// @brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { - return AttributeList.getParamAlignment(i); + return AttributeSets.getParamAlignment(i); } /// @brief Determine if the function does not access memory. bool doesNotAccessMemory() const { - return getFnAttributes().hasAttribute(Attributes::ReadNone); + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::ReadNone); } void setDoesNotAccessMemory() { - addFnAttr(Attributes::ReadNone); + addFnAttr(Attribute::ReadNone); } /// @brief Determine if the function does not access or only reads memory. bool onlyReadsMemory() const { return doesNotAccessMemory() || - getFnAttributes().hasAttribute(Attributes::ReadOnly); + AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::ReadOnly); } void setOnlyReadsMemory() { - addFnAttr(Attributes::ReadOnly); + addFnAttr(Attribute::ReadOnly); } /// @brief Determine if the function cannot return. bool doesNotReturn() const { - return getFnAttributes().hasAttribute(Attributes::NoReturn); + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoReturn); } void setDoesNotReturn() { - addFnAttr(Attributes::NoReturn); + addFnAttr(Attribute::NoReturn); } /// @brief Determine if the function cannot unwind. bool doesNotThrow() const { - return getFnAttributes().hasAttribute(Attributes::NoUnwind); + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoUnwind); } void setDoesNotThrow() { - addFnAttr(Attributes::NoUnwind); + addFnAttr(Attribute::NoUnwind); + } + + /// @brief Determine if the call cannot be duplicated. + bool cannotDuplicate() const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::NoDuplicate); + } + void setCannotDuplicate() { + addFnAttr(Attribute::NoDuplicate); } /// @brief True if the ABI mandates (or the user requested) that this /// function be in a unwind table. bool hasUWTable() const { - return getFnAttributes().hasAttribute(Attributes::UWTable); + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::UWTable); } void setHasUWTable() { - addFnAttr(Attributes::UWTable); + addFnAttr(Attribute::UWTable); } /// @brief True if this function needs an unwind table. @@ -264,28 +279,28 @@ public: return hasUWTable() || !doesNotThrow(); } - /// @brief Determine if the function returns a structure through first + /// @brief Determine if the function returns a structure through first /// pointer argument. bool hasStructRetAttr() const { - return getParamAttributes(1).hasAttribute(Attributes::StructRet); + return AttributeSets.hasAttribute(1, Attribute::StructRet); } /// @brief Determine if the parameter does not alias other parameters. /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool doesNotAlias(unsigned n) const { - return getParamAttributes(n).hasAttribute(Attributes::NoAlias); + return AttributeSets.hasAttribute(n, Attribute::NoAlias); } void setDoesNotAlias(unsigned n) { - addAttribute(n, Attributes::get(getContext(), Attributes::NoAlias)); + addAttribute(n, Attribute::NoAlias); } /// @brief Determine if the parameter can be captured. /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool doesNotCapture(unsigned n) const { - return getParamAttributes(n).hasAttribute(Attributes::NoCapture); + return AttributeSets.hasAttribute(n, Attribute::NoCapture); } void setDoesNotCapture(unsigned n) { - addAttribute(n, Attributes::get(getContext(), Attributes::NoCapture)); + addAttribute(n, Attribute::NoCapture); } /// copyAttributesFrom - copy all additional attributes (those not needed to diff --git a/contrib/llvm/include/llvm/GlobalAlias.h b/contrib/llvm/include/llvm/IR/GlobalAlias.h index d0f0147..883814a 100644 --- a/contrib/llvm/include/llvm/GlobalAlias.h +++ b/contrib/llvm/include/llvm/IR/GlobalAlias.h @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_GLOBAL_ALIAS_H -#define LLVM_GLOBAL_ALIAS_H +#ifndef LLVM_IR_GLOBALALIAS_H +#define LLVM_IR_GLOBALALIAS_H -#include "llvm/GlobalValue.h" -#include "llvm/OperandTraits.h" -#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/OperandTraits.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/GlobalValue.h b/contrib/llvm/include/llvm/IR/GlobalValue.h index 7f7f74b..f398bc1 100644 --- a/contrib/llvm/include/llvm/GlobalValue.h +++ b/contrib/llvm/include/llvm/IR/GlobalValue.h @@ -15,10 +15,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_GLOBALVALUE_H -#define LLVM_GLOBALVALUE_H +#ifndef LLVM_IR_GLOBALVALUE_H +#define LLVM_IR_GLOBALVALUE_H -#include "llvm/Constant.h" +#include "llvm/IR/Constant.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/GlobalVariable.h b/contrib/llvm/include/llvm/IR/GlobalVariable.h index b9d3f68..bfed507 100644 --- a/contrib/llvm/include/llvm/GlobalVariable.h +++ b/contrib/llvm/include/llvm/IR/GlobalVariable.h @@ -17,13 +17,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_GLOBAL_VARIABLE_H -#define LLVM_GLOBAL_VARIABLE_H +#ifndef LLVM_IR_GLOBALVARIABLE_H +#define LLVM_IR_GLOBALVARIABLE_H -#include "llvm/GlobalValue.h" -#include "llvm/OperandTraits.h" -#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/OperandTraits.h" namespace llvm { @@ -40,9 +40,14 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> { void setParent(Module *parent); - bool isConstantGlobal : 1; // Is this a global constant? - unsigned threadLocalMode : 3; // Is this symbol "Thread Local", - // if so, what is the desired model? + bool isConstantGlobal : 1; // Is this a global constant? + unsigned threadLocalMode : 3; // Is this symbol "Thread Local", + // if so, what is the desired + // model? + bool isExternallyInitializedConstant : 1; // Is this a global whose value + // can change from its initial + // value before global + // initializers are run? public: // allocate space for exactly one operand @@ -62,15 +67,15 @@ public: /// automatically inserted into the end of the specified modules global list. GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer = 0, const Twine &Name = "", - ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0); + ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, + bool isExternallyInitialized = false); /// GlobalVariable ctor - This creates a global and inserts it before the /// specified other global. GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer, - const Twine &Name = "", - GlobalVariable *InsertBefore = 0, - ThreadLocalMode = NotThreadLocal, - unsigned AddressSpace = 0); + const Twine &Name = "", GlobalVariable *InsertBefore = 0, + ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, + bool isExternallyInitialized = false); ~GlobalVariable() { NumOperands = 1; // FIXME: needed by operator delete @@ -105,7 +110,10 @@ public: return hasInitializer() && // The initializer of a global variable with weak linkage may change at // link time. - !mayBeOverridden(); + !mayBeOverridden() && + // The initializer of a global variable with the externally_initialized + // marker may change at runtime before C++ initializers are evaluated. + !isExternallyInitialized(); } /// hasUniqueInitializer - Whether the global variable has an initializer, and @@ -118,7 +126,11 @@ public: // instead. It is wrong to modify the initializer of a global variable // with *_odr linkage because then different instances of the global may // have different initializers, breaking the One Definition Rule. - !isWeakForLinker(); + !isWeakForLinker() && + // It is not safe to modify initializers of global variables with the + // external_initializer marker since the value may be changed at runtime + // before C++ initializers are evaluated. + !isExternallyInitialized(); } /// getInitializer - Return the initializer for this global variable. It is @@ -155,6 +167,13 @@ public: return static_cast<ThreadLocalMode>(threadLocalMode); } + bool isExternallyInitialized() const { + return isExternallyInitializedConstant; + } + void setExternallyInitialized(bool Val) { + isExternallyInitializedConstant = Val; + } + /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalVariable) from the GlobalVariable Src to this one. void copyAttributesFrom(const GlobalValue *Src); diff --git a/contrib/llvm/include/llvm/IRBuilder.h b/contrib/llvm/include/llvm/IR/IRBuilder.h index f63a160..1c71d0a 100644 --- a/contrib/llvm/include/llvm/IRBuilder.h +++ b/contrib/llvm/include/llvm/IR/IRBuilder.h @@ -12,25 +12,27 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_IRBUILDER_H -#define LLVM_IRBUILDER_H +#ifndef LLVM_IR_IRBUILDER_H +#define LLVM_IR_IRBUILDER_H -#include "llvm/Instructions.h" -#include "llvm/BasicBlock.h" -#include "llvm/DataLayout.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/ConstantFolder.h" namespace llvm { class MDNode; -/// IRBuilderDefaultInserter - This provides the default implementation of the -/// IRBuilder 'InsertHelper' method that is called whenever an instruction is -/// created by IRBuilder and needs to be inserted. By default, this inserts the -/// instruction at the insertion point. +/// \brief This provides the default implementation of the IRBuilder +/// 'InsertHelper' method that is called whenever an instruction is created by +/// IRBuilder and needs to be inserted. +/// +/// By default, this inserts the instruction at the insertion point. template <bool preserveNames = true> class IRBuilderDefaultInserter { protected: @@ -42,7 +44,7 @@ protected: } }; -/// IRBuilderBase - Common base class shared among various IRBuilders. +/// \brief Common base class shared among various IRBuilders. class IRBuilderBase { DebugLoc CurDbgLocation; protected: @@ -60,8 +62,8 @@ public: // Builder configuration methods //===--------------------------------------------------------------------===// - /// ClearInsertionPoint - Clear the insertion point: created instructions will - /// not be inserted into a block. + /// \brief Clear the insertion point: created instructions will not be + /// inserted into a block. void ClearInsertionPoint() { BB = 0; } @@ -70,30 +72,30 @@ public: BasicBlock::iterator GetInsertPoint() const { return InsertPt; } LLVMContext &getContext() const { return Context; } - /// SetInsertPoint - This specifies that created instructions should be - /// appended to the end of the specified block. + /// \brief This specifies that created instructions should be appended to the + /// end of the specified block. void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } - /// SetInsertPoint - This specifies that created instructions should be - /// inserted before the specified instruction. + /// \brief This specifies that created instructions should be inserted before + /// the specified instruction. void SetInsertPoint(Instruction *I) { BB = I->getParent(); InsertPt = I; SetCurrentDebugLocation(I->getDebugLoc()); } - /// SetInsertPoint - This specifies that created instructions should be - /// inserted at the specified point. + /// \brief This specifies that created instructions should be inserted at the + /// specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; } - /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and - /// specify that created instructions should be inserted at this point. + /// \brief Find the nearest point that dominates this use, and specify that + /// created instructions should be inserted at this point. void SetInsertPoint(Use &U) { Instruction *UseInst = cast<Instruction>(U.getUser()); if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) { @@ -105,25 +107,23 @@ public: SetInsertPoint(UseInst); } - /// SetCurrentDebugLocation - Set location information used by debugging - /// information. + /// \brief Set location information used by debugging information. void SetCurrentDebugLocation(const DebugLoc &L) { CurDbgLocation = L; } - /// getCurrentDebugLocation - Get location information used by debugging - /// information. + /// \brief Get location information used by debugging information. DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; } - /// SetInstDebugLocation - If this builder has a current debug location, set - /// it on the specified instruction. + /// \brief If this builder has a current debug location, set it on the + /// specified instruction. void SetInstDebugLocation(Instruction *I) const { if (!CurDbgLocation.isUnknown()) I->setDebugLoc(CurDbgLocation); } - /// getCurrentFunctionReturnType - Get the return type of the current function - /// that we're emitting into. + /// \brief Get the return type of the current function that we're emitting + /// into. Type *getCurrentFunctionReturnType() const; /// InsertPoint - A saved insertion point. @@ -132,35 +132,33 @@ public: BasicBlock::iterator Point; public: - /// Creates a new insertion point which doesn't point to anything. + /// \brief Creates a new insertion point which doesn't point to anything. InsertPoint() : Block(0) {} - /// Creates a new insertion point at the given location. + /// \brief Creates a new insertion point at the given location. InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) : Block(InsertBlock), Point(InsertPoint) {} - /// isSet - Returns true if this insert point is set. + /// \brief Returns true if this insert point is set. bool isSet() const { return (Block != 0); } llvm::BasicBlock *getBlock() const { return Block; } llvm::BasicBlock::iterator getPoint() const { return Point; } }; - /// saveIP - Returns the current insert point. + /// \brief Returns the current insert point. InsertPoint saveIP() const { return InsertPoint(GetInsertBlock(), GetInsertPoint()); } - /// saveAndClearIP - Returns the current insert point, clearing it - /// in the process. + /// \brief Returns the current insert point, clearing it in the process. InsertPoint saveAndClearIP() { InsertPoint IP(GetInsertBlock(), GetInsertPoint()); ClearInsertionPoint(); return IP; } - /// restoreIP - Sets the current insert point to a previously-saved - /// location. + /// \brief Sets the current insert point to a previously-saved location. void restoreIP(InsertPoint IP) { if (IP.isSet()) SetInsertPoint(IP.getBlock(), IP.getPoint()); @@ -172,49 +170,50 @@ public: // Miscellaneous creation methods. //===--------------------------------------------------------------------===// - /// CreateGlobalString - Make a new global variable with an initializer that - /// has array of i8 type filled in with the nul terminated string value - /// specified. The new global variable will be marked mergable with any - /// others of the same contents. If Name is specified, it is the name of the - /// global variable created. + /// \brief Make a new global variable with initializer type i8* + /// + /// Make a new global variable with an initializer that has array of i8 type + /// filled in with the null terminated string value specified. The new global + /// variable will be marked mergable with any others of the same contents. If + /// Name is specified, it is the name of the global variable created. Value *CreateGlobalString(StringRef Str, const Twine &Name = ""); - /// getInt1 - Get a constant value representing either true or false. + /// \brief Get a constant value representing either true or false. ConstantInt *getInt1(bool V) { return ConstantInt::get(getInt1Ty(), V); } - /// getTrue - Get the constant value for i1 true. + /// \brief Get the constant value for i1 true. ConstantInt *getTrue() { return ConstantInt::getTrue(Context); } - /// getFalse - Get the constant value for i1 false. + /// \brief Get the constant value for i1 false. ConstantInt *getFalse() { return ConstantInt::getFalse(Context); } - /// getInt8 - Get a constant 8-bit value. + /// \brief Get a constant 8-bit value. ConstantInt *getInt8(uint8_t C) { return ConstantInt::get(getInt8Ty(), C); } - /// getInt16 - Get a constant 16-bit value. + /// \brief Get a constant 16-bit value. ConstantInt *getInt16(uint16_t C) { return ConstantInt::get(getInt16Ty(), C); } - /// getInt32 - Get a constant 32-bit value. + /// \brief Get a constant 32-bit value. ConstantInt *getInt32(uint32_t C) { return ConstantInt::get(getInt32Ty(), C); } - /// getInt64 - Get a constant 64-bit value. + /// \brief Get a constant 64-bit value. ConstantInt *getInt64(uint64_t C) { return ConstantInt::get(getInt64Ty(), C); } - /// getInt - Get a constant integer value. + /// \brief Get a constant integer value. ConstantInt *getInt(const APInt &AI) { return ConstantInt::get(Context, AI); } @@ -223,50 +222,52 @@ public: // Type creation methods //===--------------------------------------------------------------------===// - /// getInt1Ty - Fetch the type representing a single bit + /// \brief Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); } - /// getInt8Ty - Fetch the type representing an 8-bit integer. + /// \brief Fetch the type representing an 8-bit integer. IntegerType *getInt8Ty() { return Type::getInt8Ty(Context); } - /// getInt16Ty - Fetch the type representing a 16-bit integer. + /// \brief Fetch the type representing a 16-bit integer. IntegerType *getInt16Ty() { return Type::getInt16Ty(Context); } - /// getInt32Ty - Fetch the type resepresenting a 32-bit integer. + /// \brief Fetch the type representing a 32-bit integer. IntegerType *getInt32Ty() { return Type::getInt32Ty(Context); } - /// getInt64Ty - Fetch the type representing a 64-bit integer. + /// \brief Fetch the type representing a 64-bit integer. IntegerType *getInt64Ty() { return Type::getInt64Ty(Context); } - /// getFloatTy - Fetch the type representing a 32-bit floating point value. + /// \brief Fetch the type representing a 32-bit floating point value. Type *getFloatTy() { return Type::getFloatTy(Context); } - /// getDoubleTy - Fetch the type representing a 64-bit floating point value. + /// \brief Fetch the type representing a 64-bit floating point value. Type *getDoubleTy() { return Type::getDoubleTy(Context); } - /// getVoidTy - Fetch the type representing void. + /// \brief Fetch the type representing void. Type *getVoidTy() { return Type::getVoidTy(Context); } + /// \brief Fetch the type representing a pointer to an 8-bit integer value. PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { return Type::getInt8PtrTy(Context, AddrSpace); } + /// \brief Fetch the type representing a pointer to an integer value. IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) { return DL->getIntPtrType(Context, AddrSpace); } @@ -275,9 +276,11 @@ public: // Intrinsic creation methods //===--------------------------------------------------------------------===// - /// CreateMemSet - Create and insert a memset to the specified pointer and the - /// specified value. If the pointer isn't an i8*, it will be converted. If a - /// TBAA tag is specified, it will be added to the instruction. + /// \brief Create and insert a memset to the specified pointer and the + /// specified value. + /// + /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0) { return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag); @@ -286,7 +289,8 @@ public: CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0); - /// CreateMemCpy - Create and insert a memcpy between the specified pointers. + /// \brief Create and insert a memcpy between the specified pointers. + /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align, @@ -300,9 +304,11 @@ public: bool isVolatile = false, MDNode *TBAATag = 0, MDNode *TBAAStructTag = 0); - /// CreateMemMove - Create and insert a memmove between the specified - /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA - /// tag is specified, it will be added to the instruction. + /// \brief Create and insert a memmove between the specified + /// pointers. + /// + /// If the pointers aren't i8*, they will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0) { return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag); @@ -311,25 +317,30 @@ public: CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0); - /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer - /// isn't i8* it will be converted. + /// \brief Create a lifetime.start intrinsic. + /// + /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0); - /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't - /// i8* it will be converted. + /// \brief Create a lifetime.end intrinsic. + /// + /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0); private: Value *getCastedInt8PtrValue(Value *Ptr); }; -/// IRBuilder - This provides a uniform API for creating instructions and -/// inserting them into a basic block: either at the end of a BasicBlock, or -/// at a specific iterator location in a block. +/// \brief This provides a uniform API for creating instructions and inserting +/// them into a basic block: either at the end of a BasicBlock, or at a specific +/// iterator location in a block. /// /// Note that the builder does not expose the full generality of LLVM /// instructions. For access to extra instruction properties, use the mutators -/// (e.g. setVolatile) on the instructions after they have been created. +/// (e.g. setVolatile) on the instructions after they have been +/// created. Convenience state exists to specify fast-math flags and fp-math +/// tags. +/// /// The first template argument handles whether or not to preserve names in the /// final instruction output. This defaults to on. The second template argument /// specifies a class to use for creating constants. This defaults to creating @@ -341,36 +352,40 @@ template<bool preserveNames = true, typename T = ConstantFolder, class IRBuilder : public IRBuilderBase, public Inserter { T Folder; MDNode *DefaultFPMathTag; + FastMathFlags FMF; public: IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), MDNode *FPMathTag = 0) - : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag), + FMF() { } - explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C), - Folder(), DefaultFPMathTag(FPMathTag) { + explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) + : IRBuilderBase(C), Folder(), DefaultFPMathTag(FPMathTag), FMF() { } explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(F), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB); } explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB); } explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) - : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag), + FMF() { SetInsertPoint(IP); SetCurrentDebugLocation(IP->getDebugLoc()); } explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) - : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { + : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag), + FMF() { SetInsertPoint(U); SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); } @@ -378,39 +393,47 @@ public: IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(F), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB, IP); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) : IRBuilderBase(TheBB->getContext()), Folder(), - DefaultFPMathTag(FPMathTag) { + DefaultFPMathTag(FPMathTag), FMF() { SetInsertPoint(TheBB, IP); } - /// getFolder - Get the constant folder being used. + /// \brief Get the constant folder being used. const T &getFolder() { return Folder; } - /// getDefaultFPMathTag - Get the floating point math metadata being used. + /// \brief Get the floating point math metadata being used. MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } - /// SetDefaultFPMathTag - Set the floating point math metadata to be used. + /// \brief Get the flags to be applied to created floating point ops + FastMathFlags getFastMathFlags() const { return FMF; } + + /// \brief Clear the fast-math flags. + void clearFastMathFlags() { FMF.clear(); } + + /// \brief SetDefaultFPMathTag - Set the floating point math metadata to be used. void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } - /// isNamePreserving - Return true if this builder is configured to actually - /// add the requested names to IR created through it. + /// \brief Set the fast-math flags to be used with generated fp-math operators + void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } + + /// \brief Return true if this builder is configured to actually add the + /// requested names to IR created through it. bool isNamePreserving() const { return preserveNames; } - /// Insert - Insert and return the specified instruction. + /// \brief Insert and return the specified instruction. template<typename InstTy> InstTy *Insert(InstTy *I, const Twine &Name = "") const { this->InsertHelper(I, Name, BB, InsertPt); - if (!getCurrentDebugLocation().isUnknown()) - this->SetInstDebugLocation(I); + this->SetInstDebugLocation(I); return I; } - /// Insert - No-op overload to handle constants. + /// \brief No-op overload to handle constants. Constant *Insert(Constant *C, const Twine& = "") const { return C; } @@ -430,25 +453,23 @@ private: } public: - /// CreateRetVoid - Create a 'ret void' instruction. + /// \brief Create a 'ret void' instruction. ReturnInst *CreateRetVoid() { return Insert(ReturnInst::Create(Context)); } - /// @verbatim - /// CreateRet - Create a 'ret <val>' instruction. - /// @endverbatim + /// \brief Create a 'ret <val>' instruction. ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(Context, V)); } - /// CreateAggregateRet - Create a sequence of N insertvalue instructions, + /// \brief Create a sequence of N insertvalue instructions, /// with one Value from the retVals array each, that build a aggregate /// return value one value at a time, and a ret instruction to return - /// the resulting aggregate value. This is a convenience function for - /// code that uses aggregate return values as a vehicle for having - /// multiple return values. + /// the resulting aggregate value. /// + /// This is a convenience function for code that uses aggregate return values + /// as a vehicle for having multiple return values. ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { Value *V = UndefValue::get(getCurrentFunctionReturnType()); for (unsigned i = 0; i != N; ++i) @@ -456,12 +477,12 @@ public: return Insert(ReturnInst::Create(Context, V)); } - /// CreateBr - Create an unconditional 'br label X' instruction. + /// \brief Create an unconditional 'br label X' instruction. BranchInst *CreateBr(BasicBlock *Dest) { return Insert(BranchInst::Create(Dest)); } - /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest' + /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights = 0) { @@ -469,18 +490,18 @@ public: BranchWeights)); } - /// CreateSwitch - Create a switch instruction with the specified value, - /// default dest, and with a hint for the number of cases that will be added - /// (for efficient allocation). + /// \brief Create a switch instruction with the specified value, default dest, + /// and with a hint for the number of cases that will be added (for efficient + /// allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, MDNode *BranchWeights = 0) { return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases), BranchWeights)); } - /// CreateIndirectBr - Create an indirect branch instruction with the - /// specified address operand, with an optional hint for the number of - /// destinations that will be added (for efficient allocation). + /// \brief Create an indirect branch instruction with the specified address + /// operand, with an optional hint for the number of destinations that will be + /// added (for efficient allocation). IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { return Insert(IndirectBrInst::Create(Addr, NumDests)); } @@ -505,7 +526,7 @@ public: return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), Name); } - /// CreateInvoke - Create an invoke instruction. + /// \brief Create an invoke instruction. InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Value *> Args, const Twine &Name = "") { @@ -535,11 +556,14 @@ private: return BO; } - Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const { + Instruction *AddFPMathAttributes(Instruction *I, + MDNode *FPMathTag, + FastMathFlags FMF) const { if (!FPMathTag) FPMathTag = DefaultFPMathTag; if (FPMathTag) I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); + I->setFastMathFlags(FMF); return I; } public: @@ -562,8 +586,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFAdd(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -584,8 +608,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFSub(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -606,8 +630,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFMul(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { @@ -638,8 +662,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFDiv(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) @@ -658,8 +682,8 @@ public: if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFRem(LC, RC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS), - FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS), + FPMathTag, FMF), Name); } Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", @@ -788,7 +812,8 @@ public: Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) { if (Constant *VC = dyn_cast<Constant>(V)) return Insert(Folder.CreateFNeg(VC), Name); - return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name); + return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V), + FPMathTag, FMF), Name); } Value *CreateNot(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) @@ -804,7 +829,7 @@ public: const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } - // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of + // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. LoadInst *CreateLoad(Value *Ptr, const char *Name) { return Insert(new LoadInst(Ptr), Name); @@ -818,8 +843,9 @@ public: StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } - // Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' correctly, - // instead of converting the string to 'bool' for the isVolatile parameter. + // \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' + // correctly, instead of converting the string to 'bool' for the isVolatile + // parameter. LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { LoadInst *LI = CreateLoad(Ptr, Name); LI->setAlignment(Align); @@ -981,8 +1007,8 @@ public: return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); } - /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer - /// with "i8*" type instead of a pointer to array of i8. + /// \brief Same as CreateGlobalString, but return a pointer with "i8*" type + /// instead of a pointer to array of i8. Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") { Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); @@ -1003,27 +1029,31 @@ public: Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } - /// CreateZExtOrTrunc - Create a ZExt or Trunc from the integer value V to - /// DestTy. Return the value untouched if the type of V is already DestTy. - Value *CreateZExtOrTrunc(Value *V, IntegerType *DestTy, + /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Return + /// the value untouched if the type of V is already DestTy. + Value *CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { - assert(isa<IntegerType>(V->getType()) && "Can only zero extend integers!"); - IntegerType *IntTy = cast<IntegerType>(V->getType()); - if (IntTy->getBitWidth() < DestTy->getBitWidth()) + assert(V->getType()->isIntOrIntVectorTy() && + DestTy->isIntOrIntVectorTy() && + "Can only zero extend/truncate integers!"); + Type *VTy = V->getType(); + if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) return CreateZExt(V, DestTy, Name); - if (IntTy->getBitWidth() > DestTy->getBitWidth()) + if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) return CreateTrunc(V, DestTy, Name); return V; } - /// CreateSExtOrTrunc - Create a SExt or Trunc from the integer value V to - /// DestTy. Return the value untouched if the type of V is already DestTy. - Value *CreateSExtOrTrunc(Value *V, IntegerType *DestTy, + /// \brief Create a SExt or Trunc from the integer value V to DestTy. Return + /// the value untouched if the type of V is already DestTy. + Value *CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { - assert(isa<IntegerType>(V->getType()) && "Can only sign extend integers!"); - IntegerType *IntTy = cast<IntegerType>(V->getType()); - if (IntTy->getBitWidth() < DestTy->getBitWidth()) + assert(V->getType()->isIntOrIntVectorTy() && + DestTy->isIntOrIntVectorTy() && + "Can only sign extend/truncate integers!"); + Type *VTy = V->getType(); + if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) return CreateSExt(V, DestTy, Name); - if (IntTy->getBitWidth() > DestTy->getBitWidth()) + if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) return CreateTrunc(V, DestTy, Name); return V; } @@ -1107,8 +1137,9 @@ public: return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); } private: - // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time - // error, instead of converting the string to bool for the isSigned parameter. + // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a + // compile time error, instead of converting the string to bool for the + // isSigned parameter. Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION; public: Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { @@ -1311,30 +1342,31 @@ public: LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses, const Twine &Name = "") { - return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name)); + return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses), Name); } //===--------------------------------------------------------------------===// // Utility creation methods //===--------------------------------------------------------------------===// - /// CreateIsNull - Return an i1 value testing if \p Arg is null. + /// \brief Return an i1 value testing if \p Arg is null. Value *CreateIsNull(Value *Arg, const Twine &Name = "") { return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), Name); } - /// CreateIsNotNull - Return an i1 value testing if \p Arg is not null. + /// \brief Return an i1 value testing if \p Arg is not null. Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), Name); } - /// CreatePtrDiff - Return the i64 difference between two pointer values, - /// dividing out the size of the pointed-to objects. This is intended to - /// implement C-style pointer subtraction. As such, the pointers must be - /// appropriately aligned for their element types and pointing into the - /// same object. + /// \brief Return the i64 difference between two pointer values, dividing out + /// the size of the pointed-to objects. + /// + /// This is intended to implement C-style pointer subtraction. As such, the + /// pointers must be appropriately aligned for their element types and + /// pointing into the same object. Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { assert(LHS->getType() == RHS->getType() && "Pointer subtraction operand types must match!"); @@ -1346,6 +1378,22 @@ public: ConstantExpr::getSizeOf(ArgType->getElementType()), Name); } + + /// \brief Return a vector value that contains \arg V broadcasted to \p + /// NumElts elements. + Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") { + assert(NumElts > 0 && "Cannot splat to an empty vector!"); + + // First insert it into an undef vector so we can shuffle it. + Type *I32Ty = getInt32Ty(); + Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts)); + V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0), + Name + ".splatinsert"); + + // Shuffle the value across the desired number of elements. + Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts)); + return CreateShuffleVector(V, Undef, Zeros, Name + ".splat"); + } }; } diff --git a/contrib/llvm/include/llvm/InlineAsm.h b/contrib/llvm/include/llvm/IR/InlineAsm.h index b5e0fd4..33e4ab8 100644 --- a/contrib/llvm/include/llvm/InlineAsm.h +++ b/contrib/llvm/include/llvm/IR/InlineAsm.h @@ -13,11 +13,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INLINEASM_H -#define LLVM_INLINEASM_H +#ifndef LLVM_IR_INLINEASM_H +#define LLVM_IR_INLINEASM_H -#include "llvm/Value.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/Value.h" #include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/InstrTypes.h b/contrib/llvm/include/llvm/IR/InstrTypes.h index da17f3b..3e6903c 100644 --- a/contrib/llvm/include/llvm/InstrTypes.h +++ b/contrib/llvm/include/llvm/IR/InstrTypes.h @@ -13,13 +13,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INSTRUCTION_TYPES_H -#define LLVM_INSTRUCTION_TYPES_H +#ifndef LLVM_IR_INSTRTYPES_H +#define LLVM_IR_INSTRTYPES_H -#include "llvm/Instruction.h" -#include "llvm/OperandTraits.h" -#include "llvm/DerivedTypes.h" #include "llvm/ADT/Twine.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/OperandTraits.h" namespace llvm { @@ -177,19 +177,19 @@ public: const Twine &Name = "") {\ return Create(Instruction::OPC, V1, V2, Name);\ } -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" #define HANDLE_BINARY_INST(N, OPC, CLASS) \ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ const Twine &Name, BasicBlock *BB) {\ return Create(Instruction::OPC, V1, V2, Name, BB);\ } -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" #define HANDLE_BINARY_INST(N, OPC, CLASS) \ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ const Twine &Name, Instruction *I) {\ return Create(Instruction::OPC, V1, V2, Name, I);\ } -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name = "") { @@ -309,7 +309,7 @@ public: /// NEG, FNeg, or NOT instruction. /// static bool isNeg(const Value *V); - static bool isFNeg(const Value *V); + static bool isFNeg(const Value *V, bool IgnoreZeroSign=false); static bool isNot(const Value *V); /// getNegArgument, getNotArgument - Helper functions to extract the diff --git a/contrib/llvm/include/llvm/Instruction.def b/contrib/llvm/include/llvm/IR/Instruction.def index e59a052..e59a052 100644 --- a/contrib/llvm/include/llvm/Instruction.def +++ b/contrib/llvm/include/llvm/IR/Instruction.def diff --git a/contrib/llvm/include/llvm/Instruction.h b/contrib/llvm/include/llvm/IR/Instruction.h index 8aa8a56..5721d8f 100644 --- a/contrib/llvm/include/llvm/Instruction.h +++ b/contrib/llvm/include/llvm/IR/Instruction.h @@ -12,15 +12,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INSTRUCTION_H -#define LLVM_INSTRUCTION_H +#ifndef LLVM_IR_INSTRUCTION_H +#define LLVM_IR_INSTRUCTION_H -#include "llvm/User.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/IR/User.h" #include "llvm/Support/DebugLoc.h" namespace llvm { +class FastMathFlags; class LLVMContext; class MDNode; @@ -33,7 +34,7 @@ class Instruction : public User, public ilist_node<Instruction> { BasicBlock *Parent; DebugLoc DbgLoc; // 'dbg' Metadata cache. - + enum { /// HasMetadataBit - This is a bit stored in the SubClassData field which /// indicates whether this instruction has metadata attached to it or not. @@ -42,12 +43,12 @@ class Instruction : public User, public ilist_node<Instruction> { public: // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); - + /// use_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. Instruction *use_back() { return cast<Instruction>(*use_begin());} const Instruction *use_back() const { return cast<Instruction>(*use_begin());} - + inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } @@ -77,16 +78,16 @@ public: //===--------------------------------------------------------------------===// // Subclass classification. //===--------------------------------------------------------------------===// - + /// getOpcode() returns a member of one of the enums like Instruction::Add. unsigned getOpcode() const { return getValueID() - InstructionVal; } - + const char *getOpcodeName() const { return getOpcodeName(getOpcode()); } bool isTerminator() const { return isTerminator(getOpcode()); } bool isBinaryOp() const { return isBinaryOp(getOpcode()); } bool isShift() { return isShift(getOpcode()); } bool isCast() const { return isCast(getOpcode()); } - + static const char* getOpcodeName(unsigned OpCode); static inline bool isTerminator(unsigned OpCode) { @@ -121,33 +122,33 @@ public: //===--------------------------------------------------------------------===// // Metadata manipulation. //===--------------------------------------------------------------------===// - + /// hasMetadata() - Return true if this instruction has any metadata attached /// to it. bool hasMetadata() const { return !DbgLoc.isUnknown() || hasMetadataHashEntry(); } - + /// hasMetadataOtherThanDebugLoc - Return true if this instruction has /// metadata attached to it other than a debug location. bool hasMetadataOtherThanDebugLoc() const { return hasMetadataHashEntry(); } - + /// getMetadata - Get the metadata of given kind attached to this Instruction. /// If the metadata is not found then return null. MDNode *getMetadata(unsigned KindID) const { if (!hasMetadata()) return 0; return getMetadataImpl(KindID); } - + /// getMetadata - Get the metadata of given kind attached to this Instruction. /// If the metadata is not found then return null. MDNode *getMetadata(StringRef Kind) const { if (!hasMetadata()) return 0; return getMetadataImpl(Kind); } - + /// getAllMetadata - Get all metadata attached to this Instruction. The first /// element of each pair returned is the KindID, the second element is the /// metadata value. This list is returned sorted by the KindID. @@ -155,7 +156,7 @@ public: if (hasMetadata()) getAllMetadataImpl(MDs); } - + /// getAllMetadataOtherThanDebugLoc - This does the same thing as /// getAllMetadata, except that it filters out the debug location. void getAllMetadataOtherThanDebugLoc(SmallVectorImpl<std::pair<unsigned, @@ -163,7 +164,7 @@ public: if (hasMetadataOtherThanDebugLoc()) getAllMetadataOtherThanDebugLocImpl(MDs); } - + /// setMetadata - Set the metadata of the specified kind to the specified /// node. This updates/replaces metadata if already present, or removes it if /// Node is null. @@ -172,17 +173,70 @@ public: /// setDebugLoc - Set the debug location information for this instruction. void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; } - + /// getDebugLoc - Return the debug location for this node as a DebugLoc. const DebugLoc &getDebugLoc() const { return DbgLoc; } - + + /// Set or clear the unsafe-algebra flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasUnsafeAlgebra(bool B); + + /// Set or clear the no-nans flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoNaNs(bool B); + + /// Set or clear the no-infs flag on this instruction, which must be an + /// operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoInfs(bool B); + + /// Set or clear the no-signed-zeros flag on this instruction, which must be + /// an operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasNoSignedZeros(bool B); + + /// Set or clear the allow-reciprocal flag on this instruction, which must be + /// an operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasAllowReciprocal(bool B); + + /// Convenience function for setting all the fast-math flags on this + /// instruction, which must be an operator which supports these flags. See + /// LangRef.html for the meaning of these flats. + void setFastMathFlags(FastMathFlags FMF); + + /// Determine whether the unsafe-algebra flag is set. + bool hasUnsafeAlgebra() const; + + /// Determine whether the no-NaNs flag is set. + bool hasNoNaNs() const; + + /// Determine whether the no-infs flag is set. + bool hasNoInfs() const; + + /// Determine whether the no-signed-zeros flag is set. + bool hasNoSignedZeros() const; + + /// Determine whether the allow-reciprocal flag is set. + bool hasAllowReciprocal() const; + + /// Convenience function for getting all the fast-math flags, which must be an + /// operator which supports these flags. See LangRef.html for the meaning of + /// these flats. + FastMathFlags getFastMathFlags() const; + + /// Copy I's fast-math flags + void copyFastMathFlags(const Instruction *I); + private: /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side /// metadata hash. bool hasMetadataHashEntry() const { return (getSubclassDataFromValue() & HasMetadataBit) != 0; } - + // These are all implemented in Metadata.cpp. MDNode *getMetadataImpl(unsigned KindID) const; MDNode *getMetadataImpl(StringRef Kind) const; @@ -194,15 +248,15 @@ public: //===--------------------------------------------------------------------===// // Predicates and helper methods. //===--------------------------------------------------------------------===// - - + + /// isAssociative - Return true if the instruction is associative: /// /// Associative operators satisfy: x op (y op z) === (x op y) op z /// /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// - bool isAssociative() const { return isAssociative(getOpcode()); } + bool isAssociative() const; static bool isAssociative(unsigned op); /// isCommutative - Return true if the instruction is commutative: @@ -255,6 +309,12 @@ public: /// bool mayThrow() const; + /// mayReturn - Return true if this is a function that may return. + /// this is true for all normal instructions. The only exception + /// is functions that are marked with the 'noreturn' attribute. + /// + bool mayReturn() const; + /// mayHaveSideEffects - Return true if the instruction may have side effects. /// /// Note that this does not consider malloc and alloca to have side @@ -262,7 +322,7 @@ public: /// instructions which don't used the returned value. For cases where this /// matters, isSafeToSpeculativelyExecute may be more appropriate. bool mayHaveSideEffects() const { - return mayWriteToMemory() || mayThrow(); + return mayWriteToMemory() || mayThrow() || !mayReturn(); } /// clone() - Create a copy of 'this' instruction that is identical in all @@ -271,12 +331,12 @@ public: /// * The instruction has no name /// Instruction *clone() const; - + /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any /// extra information (e.g. load is volatile) agree. bool isIdenticalTo(const Instruction *I) const; - + /// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it /// ignores the SubclassOptionalData flags, which specify conditions /// under which the instruction's result is undefined. @@ -291,7 +351,7 @@ public: /// as equivalent. CompareUsingScalarTypes = 1<<1 }; - + /// This function determines if the specified instruction executes the same /// operation as the current one. This means that the opcodes, type, operand /// types and any other factors affecting the operation must be the same. This @@ -301,14 +361,14 @@ public: /// the current one. /// @brief Determine if one instruction is the same operation as another. bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const; - + /// isUsedOutsideOfBlock - Return true if there are any uses of this /// instruction in blocks other than the specified block. Note that PHI nodes /// are considered to evaluate their operands in the corresponding predecessor /// block. bool isUsedOutsideOfBlock(const BasicBlock *BB) const; - - + + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() >= Value::InstructionVal; @@ -321,35 +381,35 @@ public: #define FIRST_TERM_INST(N) TermOpsBegin = N, #define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N, #define LAST_TERM_INST(N) TermOpsEnd = N+1 -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" }; enum BinaryOps { #define FIRST_BINARY_INST(N) BinaryOpsBegin = N, #define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N, #define LAST_BINARY_INST(N) BinaryOpsEnd = N+1 -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" }; enum MemoryOps { #define FIRST_MEMORY_INST(N) MemoryOpsBegin = N, #define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N, #define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1 -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" }; enum CastOps { #define FIRST_CAST_INST(N) CastOpsBegin = N, #define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N, #define LAST_CAST_INST(N) CastOpsEnd = N+1 -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" }; enum OtherOps { #define FIRST_OTHER_INST(N) OtherOpsBegin = N, #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, #define LAST_OTHER_INST(N) OtherOpsEnd = N+1 -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" }; private: // Shadow Value::setValueSubclassData with a private forwarding method so that @@ -360,34 +420,34 @@ private: unsigned short getSubclassDataFromValue() const { return Value::getSubclassDataFromValue(); } - + void setHasMetadataHashEntry(bool V) { setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) | (V ? HasMetadataBit : 0)); } - + friend class SymbolTableListTraits<Instruction, BasicBlock>; void setParent(BasicBlock *P); protected: // Instruction subclasses can stick up to 15 bits of stuff into the // SubclassData field of instruction with these members. - + // Verify that only the low 15 bits are used. void setInstructionSubclassData(unsigned short D) { assert((D & HasMetadataBit) == 0 && "Out of range value put into field"); setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D); } - + unsigned getSubclassDataFromInstruction() const { return getSubclassDataFromValue() & ~HasMetadataBit; } - + Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, Instruction *InsertBefore = 0); Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); virtual Instruction *clone_impl() const = 0; - + }; // Instruction* is only 4-byte aligned. @@ -401,7 +461,7 @@ public: } enum { NumLowBitsAvailable = 2 }; }; - + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Instructions.h b/contrib/llvm/include/llvm/IR/Instructions.h index 69593b4..7e29699 100644 --- a/contrib/llvm/include/llvm/Instructions.h +++ b/contrib/llvm/include/llvm/IR/Instructions.h @@ -13,25 +13,26 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INSTRUCTIONS_H -#define LLVM_INSTRUCTIONS_H +#ifndef LLVM_IR_INSTRUCTIONS_H +#define LLVM_IR_INSTRUCTIONS_H -#include "llvm/InstrTypes.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Attributes.h" -#include "llvm/CallingConv.h" -#include "llvm/Support/IntegersSubset.h" -#include "llvm/Support/IntegersSubsetMapping.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InstrTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/IntegersSubset.h" +#include "llvm/Support/IntegersSubsetMapping.h" #include <iterator> namespace llvm { +class APInt; class ConstantInt; class ConstantRange; -class APInt; +class DataLayout; class LLVMContext; enum AtomicOrdering { @@ -90,7 +91,7 @@ public: /// getType - Overload to return most specific pointer type /// PointerType *getType() const { - return reinterpret_cast<PointerType*>(Instruction::getType()); + return cast<PointerType>(Instruction::getType()); } /// getAllocatedType - Return the type that is being allocated by the @@ -280,7 +281,7 @@ public: unsigned Align, AtomicOrdering Order, SynchronizationScope SynchScope, BasicBlock *InsertAtEnd); - + /// isVolatile - Return true if this is a store to a volatile memory /// location. @@ -515,15 +516,15 @@ public: Value *getCompareOperand() { return getOperand(1); } const Value *getCompareOperand() const { return getOperand(1); } - + Value *getNewValOperand() { return getOperand(2); } const Value *getNewValOperand() const { return getOperand(2); } - + /// \brief Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } - + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; @@ -761,9 +762,9 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // getType - Overload to return most specific pointer type... - PointerType *getType() const { - return reinterpret_cast<PointerType*>(Instruction::getType()); + // getType - Overload to return most specific sequential type. + SequentialType *getType() const { + return cast<SequentialType>(Instruction::getType()); } /// \brief Returns the address space of this instruction's pointer type. @@ -850,6 +851,16 @@ public: /// isInBounds - Determine whether the GEP has the inbounds flag. bool isInBounds() const; + /// \brief Accumulate the constant address offset of this GEP if possible. + /// + /// This routine accepts an APInt into which it will accumulate the constant + /// offset of this GEP if the GEP is in fact constant. If the GEP is not + /// all-constant, it returns false and the value of the offset APInt is + /// undefined (it is *not* preserved!). The APInt passed into this routine + /// must be at least as wide as the IntPtr type for the address space of + /// the base GEP pointer. + bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); @@ -942,7 +953,7 @@ public: "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type assert((getOperand(0)->getType()->isIntOrIntVectorTy() || - getOperand(0)->getType()->isPointerTy()) && + getOperand(0)->getType()->getScalarType()->isPointerTy()) && "Invalid operand types for ICmp instruction"); } @@ -1156,7 +1167,7 @@ public: /// hold the calling convention of the call. /// class CallInst : public Instruction { - AttrListPtr AttributeList; ///< parameter attributes for call + AttributeSet AttributeList; ///< parameter attributes for call CallInst(const CallInst &CI); void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr); void init(Value *Func, const Twine &NameStr); @@ -1254,23 +1265,23 @@ public: /// getAttributes - Return the parameter attributes for this call. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + const AttributeSet &getAttributes() const { return AttributeList; } /// setAttributes - Set the parameter attributes for this call. /// - void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } /// addAttribute - adds the attribute to the list of attributes. - void addAttribute(unsigned i, Attributes attr); + void addAttribute(unsigned i, Attribute::AttrKind attr); /// removeAttribute - removes the attribute from the list of attributes. - void removeAttribute(unsigned i, Attributes attr); + void removeAttribute(unsigned i, Attribute attr); /// \brief Determine whether this call has the given attribute. - bool hasFnAttr(Attributes::AttrVal A) const; + bool hasFnAttr(Attribute::AttrKind A) const; /// \brief Determine whether the call or the callee has the given attributes. - bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; + bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { @@ -1278,66 +1289,63 @@ public: } /// \brief Return true if the call should not be inlined. - bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } + bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } void setIsNoInline() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoInline)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline); } /// \brief Return true if the call can return twice bool canReturnTwice() const { - return hasFnAttr(Attributes::ReturnsTwice); + return hasFnAttr(Attribute::ReturnsTwice); } void setCanReturnTwice() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::ReturnsTwice)); + addAttribute(AttributeSet::FunctionIndex, Attribute::ReturnsTwice); } /// \brief Determine if the call does not access memory. bool doesNotAccessMemory() const { - return hasFnAttr(Attributes::ReadNone); + return hasFnAttr(Attribute::ReadNone); } void setDoesNotAccessMemory() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::ReadNone)); + addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); } /// \brief Determine if the call does not access or only reads memory. bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); + return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); } void setOnlyReadsMemory() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::ReadOnly)); + addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } /// \brief Determine if the call cannot return. - bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } + bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoReturn)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn); } /// \brief Determine if the call cannot unwind. - bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } + bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } void setDoesNotThrow() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoUnwind)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); + } + + /// \brief Determine if the call cannot be duplicated. + bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); } + void setCannotDuplicate() { + addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate); } /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { // Be friendly and also check the callee. - return paramHasAttr(1, Attributes::StructRet); + return paramHasAttr(1, Attribute::StructRet); } /// \brief Determine if any call argument is an aggregate passed by value. bool hasByValArgument() const { - for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) - if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal)) - return true; - return false; + return AttributeList.hasAttrSomewhere(Attribute::ByVal); } /// getCalledFunction - Return the function called, or null if this is an @@ -1555,7 +1563,7 @@ public: const Value *getIndexOperand() const { return Op<1>(); } VectorType *getVectorOperandType() const { - return reinterpret_cast<VectorType*>(getVectorOperand()->getType()); + return cast<VectorType>(getVectorOperand()->getType()); } @@ -1614,7 +1622,7 @@ public: /// getType - Overload to return most specific vector type. /// VectorType *getType() const { - return reinterpret_cast<VectorType*>(Instruction::getType()); + return cast<VectorType>(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. @@ -1666,16 +1674,16 @@ public: /// getType - Overload to return most specific vector type. /// VectorType *getType() const { - return reinterpret_cast<VectorType*>(Instruction::getType()); + return cast<VectorType>(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Constant *getMask() const { - return reinterpret_cast<Constant*>(getOperand(2)); + return cast<Constant>(getOperand(2)); } - + /// getMaskValue - Return the index from the shuffle mask for the specified /// output result. This is either -1 if the element is undef or a number less /// than 2*numelements. @@ -1684,7 +1692,7 @@ public: int getMaskValue(unsigned i) const { return getMaskValue(getMask(), i); } - + /// getShuffleMask - Return the full mask for this instruction, where each /// element is the element number and undef's are returned as -1. static void getShuffleMask(Constant *Mask, SmallVectorImpl<int> &Result); @@ -2001,7 +2009,7 @@ public: Instruction *InsertBefore = 0) { return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore); } - static PHINode *Create(Type *Ty, unsigned NumReservedValues, + static PHINode *Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } @@ -2440,7 +2448,7 @@ class SwitchInst : public TerminatorInst { // Operand[1] = Default basic block destination // Operand[2n ] = Value to match // Operand[2n+1] = BasicBlock to go to on match - + // Store case values separately from operands list. We needn't User-Use // concept here, since it is just a case value, it will always constant, // and case value couldn't reused with another instructions/values. @@ -2457,9 +2465,9 @@ class SwitchInst : public TerminatorInst { typedef std::list<IntegersSubset> Subsets; typedef Subsets::iterator SubsetsIt; typedef Subsets::const_iterator SubsetsConstIt; - + Subsets TheSubsets; - + SwitchInst(const SwitchInst &SI); void init(Value *Value, BasicBlock *Default, unsigned NumReserved); void growOperands(); @@ -2483,7 +2491,7 @@ class SwitchInst : public TerminatorInst { protected: virtual SwitchInst *clone_impl() const; public: - + // FIXME: Currently there are a lot of unclean template parameters, // we need to make refactoring in future. // All these parameters are used to implement both iterator and const_iterator @@ -2493,16 +2501,16 @@ public: // SubsetsItTy may be SubsetsConstIt or SubsetsIt // BasicBlockTy may be "const BasicBlock" or "BasicBlock" template <class SwitchInstTy, class ConstantIntTy, - class SubsetsItTy, class BasicBlockTy> + class SubsetsItTy, class BasicBlockTy> class CaseIteratorT; typedef CaseIteratorT<const SwitchInst, const ConstantInt, SubsetsConstIt, const BasicBlock> ConstCaseIt; class CaseIt; - + // -2 static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1); - + static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0) { return new SwitchInst(Value, Default, NumCases, InsertBefore); @@ -2511,7 +2519,7 @@ public: unsigned NumCases, BasicBlock *InsertAtEnd) { return new SwitchInst(Value, Default, NumCases, InsertAtEnd); } - + ~SwitchInst(); /// Provide fast operand accessors @@ -2545,7 +2553,7 @@ public: ConstCaseIt case_begin() const { return ConstCaseIt(this, 0, TheSubsets.begin()); } - + /// Returns a read/write iterator that points one past the last /// in the SwitchInst. CaseIt case_end() { @@ -2560,14 +2568,14 @@ public: /// Note: this iterator allows to resolve successor only. Attempt /// to resolve case value causes an assertion. /// Also note, that increment and decrement also causes an assertion and - /// makes iterator invalid. + /// makes iterator invalid. CaseIt case_default() { return CaseIt(this, DefaultPseudoIndex, TheSubsets.end()); } ConstCaseIt case_default() const { return ConstCaseIt(this, DefaultPseudoIndex, TheSubsets.end()); } - + /// findCaseValue - Search all of the case values for the specified constant. /// If it is explicitly handled, return the case iterator of it, otherwise /// return default case iterator to indicate @@ -2583,8 +2591,8 @@ public: if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C))) return i; return case_default(); - } - + } + /// findCaseDest - Finds the unique case value for a given successor. Returns /// null if the successor is not found, not unique, or is the default case. ConstantInt *findCaseDest(BasicBlock *BB) { @@ -2606,7 +2614,7 @@ public: /// This action invalidates case_end(). Old case_end() iterator will /// point to the added case. void addCase(ConstantInt *OnVal, BasicBlock *Dest); - + /// addCase - Add an entry to the switch instruction. /// Note: /// This action invalidates case_end(). Old case_end() iterator will @@ -2630,31 +2638,31 @@ public: assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); setOperand(idx*2+1, (Value*)NewSucc); } - + uint16_t hash() const { uint32_t NumberOfCases = (uint32_t)getNumCases(); uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16); for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i) { - uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems(); + uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems(); Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16); } return Hash; - } - + } + // Case iterators definition. template <class SwitchInstTy, class ConstantIntTy, - class SubsetsItTy, class BasicBlockTy> + class SubsetsItTy, class BasicBlockTy> class CaseIteratorT { protected: - + SwitchInstTy *SI; - unsigned long Index; + unsigned Index; SubsetsItTy SubsetIt; - + /// Initializes case iterator for given SwitchInst and for given - /// case number. + /// case number. friend class SwitchInst; CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex, SubsetsItTy CaseValueIt) { @@ -2662,36 +2670,36 @@ public: Index = SuccessorIndex; this->SubsetIt = CaseValueIt; } - + public: typedef typename SubsetsItTy::reference IntegersSubsetRef; typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, SubsetsItTy, BasicBlockTy> Self; - + CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) { this->SI = SI; Index = CaseNum; SubsetIt = SI->TheSubsets.begin(); std::advance(SubsetIt, CaseNum); } - - + + /// Initializes case iterator for given SwitchInst and for given /// TerminatorInst's successor index. static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) { assert(SuccessorIndex < SI->getNumSuccessors() && - "Successor index # out of range!"); - return SuccessorIndex != 0 ? + "Successor index # out of range!"); + return SuccessorIndex != 0 ? Self(SI, SuccessorIndex - 1) : - Self(SI, DefaultPseudoIndex); + Self(SI, DefaultPseudoIndex); } - + /// Resolves case value for current case. /// @deprecated ConstantIntTy *getCaseValue() { assert(Index < SI->getNumCases() && "Index out the number of cases."); IntegersSubsetRef CaseRanges = *SubsetIt; - + // FIXME: Currently we work with ConstantInt based cases. // So return CaseValue as ConstantInt. return CaseRanges.getSingleNumber(0).toConstantInt(); @@ -2702,25 +2710,25 @@ public: assert(Index < SI->getNumCases() && "Index out the number of cases."); return *SubsetIt; } - + /// Resolves successor for current case. BasicBlockTy *getCaseSuccessor() { assert((Index < SI->getNumCases() || Index == DefaultPseudoIndex) && "Index out the number of cases."); - return SI->getSuccessor(getSuccessorIndex()); + return SI->getSuccessor(getSuccessorIndex()); } - + /// Returns number of current case. unsigned getCaseIndex() const { return Index; } - + /// Returns TerminatorInst's successor index for current case successor. unsigned getSuccessorIndex() const { assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) && "Index out the number of cases."); return Index != DefaultPseudoIndex ? Index + 1 : 0; } - + Self operator++() { // Check index correctness after increment. // Note: Index == getNumCases() means end(). @@ -2737,7 +2745,7 @@ public: ++(*this); return tmp; } - Self operator--() { + Self operator--() { // Check index correctness after decrement. // Note: Index == getNumCases() means end(). // Also allow "-1" iterator here. That will became valid after ++. @@ -2749,10 +2757,10 @@ public: SubsetIt = SI->TheSubsets.end(); return *this; } - - if (Index != -1UL) + + if (Index != -1U) --SubsetIt; - + return *this; } Self operator--(int) { @@ -2774,23 +2782,23 @@ public: SubsetsIt, BasicBlock> { typedef CaseIteratorT<SwitchInst, ConstantInt, SubsetsIt, BasicBlock> ParentTy; - + protected: friend class SwitchInst; CaseIt(SwitchInst *SI, unsigned CaseNum, SubsetsIt SubsetIt) : ParentTy(SI, CaseNum, SubsetIt) {} - + void updateCaseValueOperand(IntegersSubset& V) { - SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V)); + SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V)); } - + public: - CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} - + CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} + CaseIt(const ParentTy& Src) : ParentTy(Src) {} - /// Sets the new value for current case. + /// Sets the new value for current case. /// @deprecated. void setValue(ConstantInt *V) { assert(Index < SI->getNumCases() && "Index out the number of cases."); @@ -2801,17 +2809,17 @@ public: *SubsetIt = Mapping.getCase(); updateCaseValueOperand(*SubsetIt); } - + /// Sets the new value for current case. void setValueEx(IntegersSubset& V) { assert(Index < SI->getNumCases() && "Index out the number of cases."); *SubsetIt = V; - updateCaseValueOperand(*SubsetIt); + updateCaseValueOperand(*SubsetIt); } - + /// Sets the new successor for current case. void setSuccessor(BasicBlock *S) { - SI->setSuccessor(getSuccessorIndex(), S); + SI->setSuccessor(getSuccessorIndex(), S); } }; @@ -2942,7 +2950,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// calling convention of the call. /// class InvokeInst : public TerminatorInst { - AttrListPtr AttributeList; + AttributeSet AttributeList; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr); @@ -3003,23 +3011,23 @@ public: /// getAttributes - Return the parameter attributes for this invoke. /// - const AttrListPtr &getAttributes() const { return AttributeList; } + const AttributeSet &getAttributes() const { return AttributeList; } /// setAttributes - Set the parameter attributes for this invoke. /// - void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; } /// addAttribute - adds the attribute to the list of attributes. - void addAttribute(unsigned i, Attributes attr); + void addAttribute(unsigned i, Attribute::AttrKind attr); /// removeAttribute - removes the attribute from the list of attributes. - void removeAttribute(unsigned i, Attributes attr); + void removeAttribute(unsigned i, Attribute attr); /// \brief Determine whether this call has the NoAlias attribute. - bool hasFnAttr(Attributes::AttrVal A) const; + bool hasFnAttr(Attribute::AttrKind A) const; /// \brief Determine whether the call or the callee has the given attributes. - bool paramHasAttr(unsigned i, Attributes::AttrVal A) const; + bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; /// \brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned i) const { @@ -3027,57 +3035,49 @@ public: } /// \brief Return true if the call should not be inlined. - bool isNoInline() const { return hasFnAttr(Attributes::NoInline); } + bool isNoInline() const { return hasFnAttr(Attribute::NoInline); } void setIsNoInline() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoInline)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline); } /// \brief Determine if the call does not access memory. bool doesNotAccessMemory() const { - return hasFnAttr(Attributes::ReadNone); + return hasFnAttr(Attribute::ReadNone); } void setDoesNotAccessMemory() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::ReadNone)); + addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); } /// \brief Determine if the call does not access or only reads memory. bool onlyReadsMemory() const { - return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly); + return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); } void setOnlyReadsMemory() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::ReadOnly)); + addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } /// \brief Determine if the call cannot return. - bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); } + bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoReturn)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn); } /// \brief Determine if the call cannot unwind. - bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); } + bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } void setDoesNotThrow() { - addAttribute(AttrListPtr::FunctionIndex, - Attributes::get(getContext(), Attributes::NoUnwind)); + addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); } /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { // Be friendly and also check the callee. - return paramHasAttr(1, Attributes::StructRet); + return paramHasAttr(1, Attribute::StructRet); } /// \brief Determine if any call argument is an aggregate passed by value. bool hasByValArgument() const { - for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I) - if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal)) - return true; - return false; + return AttributeList.hasAttrSomewhere(Attribute::ByVal); } /// getCalledFunction - Return the function called, or null if this is an diff --git a/contrib/llvm/include/llvm/IntrinsicInst.h b/contrib/llvm/include/llvm/IR/IntrinsicInst.h index 9b2afd5..8344c56 100644 --- a/contrib/llvm/include/llvm/IntrinsicInst.h +++ b/contrib/llvm/include/llvm/IR/IntrinsicInst.h @@ -21,13 +21,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INTRINSICINST_H -#define LLVM_INTRINSICINST_H +#ifndef LLVM_IR_INTRINSICINST_H +#define LLVM_IR_INTRINSICINST_H -#include "llvm/Constants.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" namespace llvm { /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic @@ -47,14 +47,14 @@ namespace llvm { // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CallInst *I) { if (const Function *CF = I->getCalledFunction()) - return CF->getIntrinsicID() != 0; + return CF->isIntrinsic(); return false; } static inline bool classof(const Value *V) { return isa<CallInst>(V) && classof(cast<CallInst>(V)); } }; - + /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics /// class DbgInfoIntrinsic : public IntrinsicInst { diff --git a/contrib/llvm/include/llvm/Intrinsics.h b/contrib/llvm/include/llvm/IR/Intrinsics.h index 3108a8e..c97cd91 100644 --- a/contrib/llvm/include/llvm/Intrinsics.h +++ b/contrib/llvm/include/llvm/IR/Intrinsics.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_INTRINSICS_H -#define LLVM_INTRINSICS_H +#ifndef LLVM_IR_INTRINSICS_H +#define LLVM_IR_INTRINSICS_H #include "llvm/ADT/ArrayRef.h" #include <string> @@ -26,7 +26,7 @@ class FunctionType; class Function; class LLVMContext; class Module; -class AttrListPtr; +class AttributeSet; /// Intrinsic Namespace - This namespace contains an enum with a value for /// every intrinsic/builtin function known by LLVM. These enum values are @@ -38,7 +38,7 @@ namespace Intrinsic { // Get the intrinsic enums generated from Intrinsics.td #define GET_INTRINSIC_ENUM_VALUES -#include "llvm/Intrinsics.gen" +#include "llvm/IR/Intrinsics.gen" #undef GET_INTRINSIC_ENUM_VALUES , num_intrinsics }; @@ -58,7 +58,7 @@ namespace Intrinsic { /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic. /// - AttrListPtr getAttributes(LLVMContext &C, ID id); + AttributeSet getAttributes(LLVMContext &C, ID id); /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function /// declaration for an intrinsic, and return it. @@ -79,7 +79,7 @@ namespace Intrinsic { /// getIntrinsicInfoTableEntries. struct IITDescriptor { enum IITDescriptorKind { - Void, MMX, Metadata, Float, Double, + Void, MMX, Metadata, Half, Float, Double, Integer, Vector, Pointer, Struct, Argument, ExtendVecArgument, TruncVecArgument } Kind; diff --git a/contrib/llvm/include/llvm/Intrinsics.td b/contrib/llvm/include/llvm/IR/Intrinsics.td index 2e1597f..e252664 100644 --- a/contrib/llvm/include/llvm/Intrinsics.td +++ b/contrib/llvm/include/llvm/IR/Intrinsics.td @@ -106,6 +106,7 @@ def llvm_i8_ty : LLVMType<i8>; def llvm_i16_ty : LLVMType<i16>; def llvm_i32_ty : LLVMType<i32>; def llvm_i64_ty : LLVMType<i64>; +def llvm_half_ty : LLVMType<f16>; def llvm_float_ty : LLVMType<f32>; def llvm_double_ty : LLVMType<f64>; def llvm_f80_ty : LLVMType<f80>; @@ -125,16 +126,22 @@ def llvm_v2i1_ty : LLVMType<v2i1>; // 2 x i1 def llvm_v4i1_ty : LLVMType<v4i1>; // 4 x i1 def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1 def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1 +def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1 +def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1 def llvm_v2i8_ty : LLVMType<v2i8>; // 2 x i8 def llvm_v4i8_ty : LLVMType<v4i8>; // 4 x i8 def llvm_v8i8_ty : LLVMType<v8i8>; // 8 x i8 def llvm_v16i8_ty : LLVMType<v16i8>; // 16 x i8 def llvm_v32i8_ty : LLVMType<v32i8>; // 32 x i8 +def llvm_v64i8_ty : LLVMType<v64i8>; // 64 x i8 + def llvm_v1i16_ty : LLVMType<v1i16>; // 1 x i16 def llvm_v2i16_ty : LLVMType<v2i16>; // 2 x i16 def llvm_v4i16_ty : LLVMType<v4i16>; // 4 x i16 def llvm_v8i16_ty : LLVMType<v8i16>; // 8 x i16 def llvm_v16i16_ty : LLVMType<v16i16>; // 16 x i16 +def llvm_v32i16_ty : LLVMType<v32i16>; // 32 x i16 + def llvm_v1i32_ty : LLVMType<v1i32>; // 1 x i32 def llvm_v2i32_ty : LLVMType<v2i32>; // 2 x i32 def llvm_v4i32_ty : LLVMType<v4i32>; // 4 x i32 @@ -149,8 +156,10 @@ def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64 def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float +def llvm_v16f32_ty : LLVMType<v16f32>; // 16 x float def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double +def llvm_v8f64_ty : LLVMType<v8f64>; // 8 x double def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here @@ -271,6 +280,10 @@ let Properties = [IntrReadMem] in { def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_ceil : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; } let Properties = [IntrNoMem] in { @@ -461,11 +474,11 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty], // Target-specific intrinsics //===----------------------------------------------------------------------===// -include "llvm/IntrinsicsPowerPC.td" -include "llvm/IntrinsicsX86.td" -include "llvm/IntrinsicsARM.td" -include "llvm/IntrinsicsCellSPU.td" -include "llvm/IntrinsicsXCore.td" -include "llvm/IntrinsicsHexagon.td" -include "llvm/IntrinsicsNVVM.td" -include "llvm/IntrinsicsMips.td" +include "llvm/IR/IntrinsicsPowerPC.td" +include "llvm/IR/IntrinsicsX86.td" +include "llvm/IR/IntrinsicsARM.td" +include "llvm/IR/IntrinsicsXCore.td" +include "llvm/IR/IntrinsicsHexagon.td" +include "llvm/IR/IntrinsicsNVVM.td" +include "llvm/IR/IntrinsicsMips.td" +include "llvm/IR/IntrinsicsR600.td" diff --git a/contrib/llvm/include/llvm/IntrinsicsARM.td b/contrib/llvm/include/llvm/IR/IntrinsicsARM.td index 93b1ae1..93b1ae1 100644 --- a/contrib/llvm/include/llvm/IntrinsicsARM.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsARM.td diff --git a/contrib/llvm/include/llvm/IntrinsicsHexagon.td b/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td index 8a88729..8a88729 100644 --- a/contrib/llvm/include/llvm/IntrinsicsHexagon.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsHexagon.td diff --git a/contrib/llvm/include/llvm/IntrinsicsMips.td b/contrib/llvm/include/llvm/IR/IntrinsicsMips.td index e40e162..e40e162 100644 --- a/contrib/llvm/include/llvm/IntrinsicsMips.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsMips.td diff --git a/contrib/llvm/include/llvm/IntrinsicsNVVM.td b/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td index 1853c99..ebfd03e 100644 --- a/contrib/llvm/include/llvm/IntrinsicsNVVM.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsNVVM.td @@ -805,6 +805,16 @@ def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty], [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], "llvm.nvvm.ldu.global.p">; +// Generated within nvvm. Use for ldg on sm_35 or later +def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty], + [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], + "llvm.nvvm.ldg.global.i">; +def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty], + [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], + "llvm.nvvm.ldg.global.f">; +def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty], + [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>], + "llvm.nvvm.ldg.global.p">; // Use for generic pointers // - These intrinsics are used to convert address spaces. @@ -815,36 +825,36 @@ def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty], // of pointer to another type of pointer, while the address space remains // the same. def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.local.to.gen">; def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.shared.to.gen">; def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.global.to.gen">; def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.constant.to.gen">; def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.gen.to.global">; def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.gen.to.shared">; def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.gen.to.local">; def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty], - [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>], + [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.ptr.gen.to.constant">; // Used in nvvm internally to help address space opt and ptx code generation // This is for params that are passed to kernel functions by pointer by-val. def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty], - [IntrNoMem, NoCapture<0>], + [IntrNoMem], "llvm.nvvm.ptr.gen.to.param">; // Move intrinsics, used in nvvm internally diff --git a/contrib/llvm/include/llvm/IntrinsicsPowerPC.td b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td index da85bfb..cde39cc 100644 --- a/contrib/llvm/include/llvm/IntrinsicsPowerPC.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -22,7 +22,8 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], + [IntrReadWriteArgMem, NoCapture<0>]>; def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>; diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsR600.td b/contrib/llvm/include/llvm/IR/IntrinsicsR600.td new file mode 100644 index 0000000..ecb5668 --- /dev/null +++ b/contrib/llvm/include/llvm/IR/IntrinsicsR600.td @@ -0,0 +1,36 @@ +//===- IntrinsicsR600.td - Defines R600 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 R600-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "r600" in { + +class R600ReadPreloadRegisterIntrinsic<string name> + : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<name>; + +multiclass R600ReadPreloadRegisterIntrinsic_xyz<string prefix> { + def _x : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_x")>; + def _y : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_y")>; + def _z : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_z")>; +} + +defm int_r600_read_global_size : R600ReadPreloadRegisterIntrinsic_xyz < + "__builtin_r600_read_global_size">; +defm int_r600_read_local_size : R600ReadPreloadRegisterIntrinsic_xyz < + "__builtin_r600_read_local_size">; +defm int_r600_read_ngroups : R600ReadPreloadRegisterIntrinsic_xyz < + "__builtin_r600_read_ngroups">; +defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz < + "__builtin_r600_read_tgid">; +defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz < + "__builtin_r600_read_tidig">; +} // End TargetPrefix = "r600" diff --git a/contrib/llvm/include/llvm/IntrinsicsX86.td b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td index d2463c0..69e0ab4 100644 --- a/contrib/llvm/include/llvm/IntrinsicsX86.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td @@ -2550,7 +2550,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } //===----------------------------------------------------------------------===// -// RDRAND intrinsics. Return a random value and whether it is valid. +// RDRAND intrinsics - Return a random value and whether it is valid. +// RDSEED intrinsics - Return a NIST SP800-90B & C compliant random value and +// whether it is valid. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // These are declared side-effecting so they don't get eliminated by CSE or @@ -2558,6 +2560,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_rdrand_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>; def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; + def int_x86_rdseed_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>; + def int_x86_rdseed_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>; + def int_x86_rdseed_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>; } //===----------------------------------------------------------------------===// @@ -2570,4 +2575,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[], [], []>; def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">, Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>; + def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">, + Intrinsic<[llvm_i32_ty], [], []>; } diff --git a/contrib/llvm/include/llvm/IntrinsicsXCore.td b/contrib/llvm/include/llvm/IR/IntrinsicsXCore.td index a481313..a481313 100644 --- a/contrib/llvm/include/llvm/IntrinsicsXCore.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsXCore.td diff --git a/contrib/llvm/include/llvm/LLVMContext.h b/contrib/llvm/include/llvm/IR/LLVMContext.h index 5903e2e..ae81e5b 100644 --- a/contrib/llvm/include/llvm/LLVMContext.h +++ b/contrib/llvm/include/llvm/IR/LLVMContext.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LLVMCONTEXT_H -#define LLVM_LLVMCONTEXT_H +#ifndef LLVM_IR_LLVMCONTEXT_H +#define LLVM_IR_LLVMCONTEXT_H #include "llvm/Support/Compiler.h" @@ -46,7 +46,8 @@ public: MD_prof = 2, // "prof" MD_fpmath = 3, // "fpmath" MD_range = 4, // "range" - MD_tbaa_struct = 5 // "tbaa.struct" + MD_tbaa_struct = 5, // "tbaa.struct" + MD_invariant_load = 6 // "invariant.load" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/contrib/llvm/include/llvm/IR/MDBuilder.h b/contrib/llvm/include/llvm/IR/MDBuilder.h new file mode 100644 index 0000000..a1e3fb1 --- /dev/null +++ b/contrib/llvm/include/llvm/IR/MDBuilder.h @@ -0,0 +1,186 @@ +//===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MDBuilder class, which is used as a convenient way to +// create LLVM metadata with a consistent and simplified interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_MDBUILDER_H +#define LLVM_IR_MDBUILDER_H + +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Metadata.h" + +namespace llvm { + +class APInt; +class LLVMContext; + +class MDBuilder { + LLVMContext &Context; + +public: + MDBuilder(LLVMContext &context) : Context(context) {} + + /// \brief Return the given string as metadata. + MDString *createString(StringRef Str) { + return MDString::get(Context, Str); + } + + //===------------------------------------------------------------------===// + // FPMath metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata with the given settings. The special value 0.0 + /// for the Accuracy parameter indicates the default (maximal precision) + /// setting. + MDNode *createFPMath(float Accuracy) { + if (Accuracy == 0.0) + return 0; + assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); + Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); + return MDNode::get(Context, Op); + } + + //===------------------------------------------------------------------===// + // Prof metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata containing two branch weights. + MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) { + uint32_t Weights[] = { TrueWeight, FalseWeight }; + return createBranchWeights(Weights); + } + + /// \brief Return metadata containing a number of branch weights. + MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { + assert(Weights.size() >= 2 && "Need at least two branch weights!"); + + SmallVector<Value *, 4> Vals(Weights.size()+1); + Vals[0] = createString("branch_weights"); + + Type *Int32Ty = Type::getInt32Ty(Context); + for (unsigned i = 0, e = Weights.size(); i != e; ++i) + Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); + + return MDNode::get(Context, Vals); + } + + //===------------------------------------------------------------------===// + // Range metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata describing the range [Lo, Hi). + MDNode *createRange(const APInt &Lo, const APInt &Hi) { + assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); + // If the range is everything then it is useless. + if (Hi == Lo) + return 0; + + // Return the range [Lo, Hi). + Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); + Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; + return MDNode::get(Context, Range); + } + + + //===------------------------------------------------------------------===// + // TBAA metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata appropriate for a TBAA root node. Each returned + /// node is distinct from all other metadata and will never be identified + /// (uniqued) with anything else. + MDNode *createAnonymousTBAARoot() { + // To ensure uniqueness the root node is self-referential. + MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); + MDNode *Root = MDNode::get(Context, Dummy); + // At this point we have + // !0 = metadata !{} <- dummy + // !1 = metadata !{metadata !0} <- root + // Replace the dummy operand with the root node itself and delete the dummy. + Root->replaceOperandWith(0, Root); + MDNode::deleteTemporary(Dummy); + // We now have + // !1 = metadata !{metadata !1} <- self-referential root + return Root; + } + + /// \brief Return metadata appropriate for a TBAA root node with the given + /// name. This may be identified (uniqued) with other roots with the same + /// name. + MDNode *createTBAARoot(StringRef Name) { + return MDNode::get(Context, createString(Name)); + } + + /// \brief Return metadata for a non-root TBAA node with the given name, + /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. + MDNode *createTBAANode(StringRef Name, MDNode *Parent, + bool isConstant = false) { + if (isConstant) { + Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); + Value *Ops[3] = { createString(Name), Parent, Flags }; + return MDNode::get(Context, Ops); + } else { + Value *Ops[2] = { createString(Name), Parent }; + return MDNode::get(Context, Ops); + } + } + + struct TBAAStructField { + uint64_t Offset; + uint64_t Size; + MDNode *TBAA; + TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : + Offset(Offset), Size(Size), TBAA(TBAA) {} + }; + + /// \brief Return metadata for a tbaa.struct node with the given + /// struct field descriptions. + MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { + SmallVector<Value *, 4> Vals(Fields.size() * 3); + Type *Int64 = IntegerType::get(Context, 64); + for (unsigned i = 0, e = Fields.size(); i != e; ++i) { + Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); + Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); + Vals[i * 3 + 2] = Fields[i].TBAA; + } + return MDNode::get(Context, Vals); + } + + /// \brief Return metadata for a TBAA struct node in the type DAG + /// with the given name, parents in the TBAA DAG. + MDNode *createTBAAStructTypeNode(StringRef Name, + ArrayRef<std::pair<uint64_t, MDNode*> > Fields) { + SmallVector<Value *, 4> Ops(Fields.size() * 2 + 1); + Type *Int64 = IntegerType::get(Context, 64); + Ops[0] = createString(Name); + for (unsigned i = 0, e = Fields.size(); i != e; ++i) { + Ops[i * 2 + 1] = ConstantInt::get(Int64, Fields[i].first); + Ops[i * 2 + 2] = Fields[i].second; + } + return MDNode::get(Context, Ops); + } + + /// \brief Return metadata for a TBAA tag node with the given + /// base type, access type and offset relative to the base type. + MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, + uint64_t Offset) { + Type *Int64 = IntegerType::get(Context, 64); + Value *Ops[3] = { BaseType, AccessType, ConstantInt::get(Int64, Offset) }; + return MDNode::get(Context, Ops); + } + +}; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Metadata.h b/contrib/llvm/include/llvm/IR/Metadata.h index 0fbbb95..8c2cfac 100644 --- a/contrib/llvm/include/llvm/Metadata.h +++ b/contrib/llvm/include/llvm/IR/Metadata.h @@ -13,13 +13,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_METADATA_H -#define LLVM_METADATA_H +#ifndef LLVM_IR_METADATA_H +#define LLVM_IR_METADATA_H -#include "llvm/Value.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/IR/Value.h" namespace llvm { class Constant; @@ -29,8 +29,8 @@ class Module; template <typename T> class SmallVectorImpl; template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; - - + + //===----------------------------------------------------------------------===// /// MDString - a single uniqued string. /// These are used to efficiently contain a byte sequence for metadata. @@ -51,7 +51,7 @@ public: unsigned getLength() const { return (unsigned)getName().size(); } typedef StringRef::iterator iterator; - + /// begin() - Pointer to the first byte of the string. iterator begin() const { return getName().begin(); } @@ -64,9 +64,9 @@ public: } }; - + class MDNodeOperand; - + //===----------------------------------------------------------------------===// /// MDNode - a tuple of other values. class MDNode : public Value, public FoldingSetNode { @@ -82,37 +82,37 @@ class MDNode : public Value, public FoldingSetNode { /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the /// end of this MDNode. unsigned NumOperands; - + // Subclass data enums. enum { /// FunctionLocalBit - This bit is set if this MDNode is function local. /// This is true when it (potentially transitively) contains a reference to /// something in a function, like an argument, basicblock, or instruction. FunctionLocalBit = 1 << 0, - + /// NotUniquedBit - This is set on MDNodes that are not uniqued because they /// have a null operand. NotUniquedBit = 1 << 1, - + /// DestroyFlag - This bit is set by destroy() so the destructor can assert /// that the node isn't being destroyed with a plain 'delete'. DestroyFlag = 1 << 2 }; - + // FunctionLocal enums. enum FunctionLocalness { FL_Unknown = -1, FL_No = 0, FL_Yes = 1 }; - - /// replaceOperand - Replace each instance of F from the operand list of this + + /// replaceOperand - Replace each instance of F from the operand list of this /// node with T. void replaceOperand(MDNodeOperand *Op, Value *NewVal); ~MDNode(); MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal); - + static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals, FunctionLocalness FL, bool Insert = true); public: @@ -123,7 +123,7 @@ public: static MDNode *getWhenValsUnresolved(LLVMContext &Context, ArrayRef<Value*> Vals, bool isFunctionLocal); - + static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals); /// getTemporary - Return a temporary MDNode, for use in constructing @@ -137,22 +137,22 @@ public: /// replaceOperandWith - Replace a specific operand. void replaceOperandWith(unsigned i, Value *NewVal); - + /// getOperand - Return specified operand. Value *getOperand(unsigned i) const; - + /// getNumOperands - Return number of MDNode operands. unsigned getNumOperands() const { return NumOperands; } - + /// isFunctionLocal - Return whether MDNode is local to a function. bool isFunctionLocal() const { return (getSubclassDataFromValue() & FunctionLocalBit) != 0; } - + // getFunction - If this metadata is function-local and recursively has a // function-local operand, return the first such operand's parent function. // Otherwise, return null. getFunction() should not be used for performance- - // critical code because it recursively visits all the MDNode's operands. + // critical code because it recursively visits all the MDNode's operands. const Function *getFunction() const; /// Profile - calculate a unique identifier for this MDNode to collapse @@ -172,11 +172,11 @@ private: // destroy - Delete this node. Only when there are no uses. void destroy(); - bool isNotUniqued() const { + bool isNotUniqued() const { return (getSubclassDataFromValue() & NotUniquedBit) != 0; } void setIsNotUniqued(); - + // Shadow Value::setValueSubclassData with a private forwarding method so that // any future subclasses cannot accidentally use it. void setValueSubclassData(unsigned short D) { @@ -220,7 +220,7 @@ public: /// getOperand - Return specified operand. MDNode *getOperand(unsigned i) const; - + /// getNumOperands - Return the number of NamedMDNode operands. unsigned getNumOperands() const; diff --git a/contrib/llvm/include/llvm/Module.h b/contrib/llvm/include/llvm/IR/Module.h index e6303ac..4460aa4 100644 --- a/contrib/llvm/include/llvm/Module.h +++ b/contrib/llvm/include/llvm/IR/Module.h @@ -12,16 +12,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MODULE_H -#define LLVM_MODULE_H +#ifndef LLVM_IR_MODULE_H +#define LLVM_IR_MODULE_H -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" -#include "llvm/GlobalAlias.h" -#include "llvm/Metadata.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/DataTypes.h" -#include <vector> namespace llvm { @@ -122,9 +121,6 @@ public: /// The type for the list of named metadata. typedef ilist<NamedMDNode> NamedMDListType; - /// The type for the list of dependent libraries. - typedef std::vector<std::string> LibraryListType; - /// The Global Variable iterator. typedef GlobalListType::iterator global_iterator; /// The Global Variable constant iterator. @@ -144,8 +140,6 @@ public: typedef NamedMDListType::iterator named_metadata_iterator; /// The named metadata constant interators. typedef NamedMDListType::const_iterator const_named_metadata_iterator; - /// The Library list iterator. - typedef LibraryListType::const_iterator lib_iterator; /// An enumeration for describing the endianess of the target machine. enum Endianness { AnyEndianness, LittleEndian, BigEndian }; @@ -153,30 +147,38 @@ public: /// An enumeration for describing the size of a pointer on the target machine. enum PointerSize { AnyPointerSize, Pointer32, Pointer64 }; - /// An enumeration for the supported behaviors of module flags. The following - /// module flags behavior values are supported: - /// - /// Value Behavior - /// ----- -------- - /// 1 Error - /// Emits an error if two values disagree. - /// - /// 2 Warning - /// Emits a warning if two values disagree. - /// - /// 3 Require - /// Emits an error when the specified value is not present - /// or doesn't have the specified value. It is an error for - /// two (or more) llvm.module.flags with the same ID to have - /// the Require behavior but different values. There may be - /// multiple Require flags per ID. - /// - /// 4 Override - /// Uses the specified value if the two values disagree. It - /// is an error for two (or more) llvm.module.flags with the - /// same ID to have the Override behavior but different - /// values. - enum ModFlagBehavior { Error = 1, Warning = 2, Require = 3, Override = 4 }; + /// This enumeration defines the supported behaviors of module flags. + enum ModFlagBehavior { + /// Emits an error if two values disagree, otherwise the resulting value is + /// that of the operands. + Error = 1, + + /// Emits a warning if two values disagree. The result value will be the + /// operand for the flag from the first module being linked. + Warning = 2, + + /// Adds a requirement that another module flag be present and have a + /// specified value after linking is performed. The value must be a metadata + /// pair, where the first element of the pair is the ID of the module flag + /// to be restricted, and the second element of the pair is the value the + /// module flag should be restricted to. This behavior can be used to + /// restrict the allowable results (via triggering of an error) of linking + /// IDs with the **Override** behavior. + Require = 3, + + /// Uses the specified value, regardless of the behavior or value of the + /// other module. If both modules specify **Override**, but the values + /// differ, an error will be emitted. + Override = 4, + + /// Appends the two values, which are required to be metadata nodes. + Append = 5, + + /// Appends the two values, which are required to be metadata + /// nodes. However, duplicate entries in the second list are dropped + /// during the append operation. + AppendUnique = 6 + }; struct ModuleFlagEntry { ModFlagBehavior Behavior; @@ -195,7 +197,6 @@ private: GlobalListType GlobalList; ///< The Global Variables in the module FunctionListType FunctionList; ///< The Functions in the module AliasListType AliasList; ///< The Aliases in the module - LibraryListType LibraryList; ///< The Libraries needed by the module NamedMDListType NamedMDList; ///< The named metadata in the module std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values @@ -319,7 +320,7 @@ public: /// 4. Finally, the function exists but has the wrong prototype: return the /// function with a constantexpr cast to the right prototype. Constant *getOrInsertFunction(StringRef Name, FunctionType *T, - AttrListPtr AttributeList); + AttributeSet AttributeList); Constant *getOrInsertFunction(StringRef Name, FunctionType *T); @@ -331,7 +332,7 @@ public: /// null terminated list of function arguments, which makes it easier for /// clients to use. Constant *getOrInsertFunction(StringRef Name, - AttrListPtr AttributeList, + AttributeSet AttributeList, Type *RetTy, ...) END_WITH_NULL; /// getOrInsertFunction - Same as above, but without the attributes. @@ -340,7 +341,7 @@ public: Constant *getOrInsertTargetIntrinsic(StringRef Name, FunctionType *Ty, - AttrListPtr AttributeList); + AttributeSet AttributeList); /// getFunction - Look up the specified function in the module symbol table. /// If it does not exist, return null. @@ -527,23 +528,6 @@ public: bool empty() const { return FunctionList.empty(); } /// @} -/// @name Dependent Library Iteration -/// @{ - - /// @brief Get a constant iterator to beginning of dependent library list. - inline lib_iterator lib_begin() const { return LibraryList.begin(); } - /// @brief Get a constant iterator to end of dependent library list. - inline lib_iterator lib_end() const { return LibraryList.end(); } - /// @brief Returns the number of items in the list of libraries. - inline size_t lib_size() const { return LibraryList.size(); } - /// @brief Add a library to the list of dependent libraries - void addLibrary(StringRef Lib); - /// @brief Remove a library from the list of dependent libraries - void removeLibrary(StringRef Lib); - /// @brief Get all the libraries - inline const LibraryListType& getLibraries() const { return LibraryList; } - -/// @} /// @name Alias Iteration /// @{ diff --git a/contrib/llvm/include/llvm/OperandTraits.h b/contrib/llvm/include/llvm/IR/OperandTraits.h index 3d8dc32..0e4b195 100644 --- a/contrib/llvm/include/llvm/OperandTraits.h +++ b/contrib/llvm/include/llvm/IR/OperandTraits.h @@ -12,10 +12,10 @@ // the operands in the most efficient manner. // -#ifndef LLVM_OPERAND_TRAITS_H -#define LLVM_OPERAND_TRAITS_H +#ifndef LLVM_IR_OPERANDTRAITS_H +#define LLVM_IR_OPERANDTRAITS_H -#include "llvm/User.h" +#include "llvm/IR/User.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Operator.h b/contrib/llvm/include/llvm/IR/Operator.h index b326c11..13ab72c 100644 --- a/contrib/llvm/include/llvm/Operator.h +++ b/contrib/llvm/include/llvm/IR/Operator.h @@ -12,13 +12,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OPERATOR_H -#define LLVM_OPERATOR_H +#ifndef LLVM_IR_OPERATOR_H +#define LLVM_IR_OPERATOR_H -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instruction.h" -#include "llvm/Type.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" namespace llvm { @@ -31,8 +33,8 @@ class ConstantExpr; /// class Operator : public User { private: - // Do not implement any of these. The Operator class is intended to be used - // as a utility, and is never itself instantiated. + // The Operator class is intended to be used as a utility, and is never itself + // instantiated. void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; void *operator new(size_t s) LLVM_DELETED_FUNCTION; Operator() LLVM_DELETED_FUNCTION; @@ -131,21 +133,21 @@ public: enum { IsExact = (1 << 0) }; - + private: friend class BinaryOperator; friend class ConstantExpr; void setIsExact(bool B) { SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); } - + public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. bool isExact() const { return SubclassOptionalData & IsExact; } - + static bool isPossiblyExactOpcode(unsigned OpC) { return OpC == Instruction::SDiv || OpC == Instruction::UDiv || @@ -164,10 +166,133 @@ public: } }; +/// Convenience struct for specifying and reasoning about fast-math flags. +class FastMathFlags { +private: + friend class FPMathOperator; + unsigned Flags; + FastMathFlags(unsigned F) : Flags(F) { } + +public: + enum { + UnsafeAlgebra = (1 << 0), + NoNaNs = (1 << 1), + NoInfs = (1 << 2), + NoSignedZeros = (1 << 3), + AllowReciprocal = (1 << 4) + }; + + FastMathFlags() : Flags(0) + { } + + /// Whether any flag is set + bool any() { return Flags != 0; } + + /// Set all the flags to false + void clear() { Flags = 0; } + + /// Flag queries + bool noNaNs() { return 0 != (Flags & NoNaNs); } + bool noInfs() { return 0 != (Flags & NoInfs); } + bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); } + bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); } + bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); } + + /// Flag setters + void setNoNaNs() { Flags |= NoNaNs; } + void setNoInfs() { Flags |= NoInfs; } + void setNoSignedZeros() { Flags |= NoSignedZeros; } + void setAllowReciprocal() { Flags |= AllowReciprocal; } + void setUnsafeAlgebra() { + Flags |= UnsafeAlgebra; + setNoNaNs(); + setNoInfs(); + setNoSignedZeros(); + setAllowReciprocal(); + } +}; + + /// FPMathOperator - Utility class for floating point operations which can have /// information about relaxed accuracy requirements attached to them. class FPMathOperator : public Operator { +private: + friend class Instruction; + + void setHasUnsafeAlgebra(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) | + (B * FastMathFlags::UnsafeAlgebra); + + // Unsafe algebra implies all the others + if (B) { + setHasNoNaNs(true); + setHasNoInfs(true); + setHasNoSignedZeros(true); + setHasAllowReciprocal(true); + } + } + void setHasNoNaNs(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoNaNs) | + (B * FastMathFlags::NoNaNs); + } + void setHasNoInfs(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoInfs) | + (B * FastMathFlags::NoInfs); + } + void setHasNoSignedZeros(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | + (B * FastMathFlags::NoSignedZeros); + } + void setHasAllowReciprocal(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | + (B * FastMathFlags::AllowReciprocal); + } + + /// Convenience function for setting all the fast-math flags + void setFastMathFlags(FastMathFlags FMF) { + SubclassOptionalData |= FMF.Flags; + } + public: + /// Test whether this operation is permitted to be + /// algebraically transformed, aka the 'A' fast-math property. + bool hasUnsafeAlgebra() const { + return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0; + } + + /// Test whether this operation's arguments and results are to be + /// treated as non-NaN, aka the 'N' fast-math property. + bool hasNoNaNs() const { + return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; + } + + /// Test whether this operation's arguments and results are to be + /// treated as NoN-Inf, aka the 'I' fast-math property. + bool hasNoInfs() const { + return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; + } + + /// Test whether this operation can treat the sign of zero + /// as insignificant, aka the 'S' fast-math property. + bool hasNoSignedZeros() const { + return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; + } + + /// Test whether this operation is permitted to use + /// reciprocal instead of division, aka the 'R' fast-math property. + bool hasAllowReciprocal() const { + return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; + } + + /// Convenience function for getting all the fast-math flags + FastMathFlags getFastMathFlags() const { + return FastMathFlags(SubclassOptionalData); + } /// \brief Get the maximum error permitted by this operation in ULPs. An /// accuracy of 0.0 means that the operation should be performed with the @@ -182,7 +307,7 @@ public: } }; - + /// ConcreteOperator - A helper template for defining operators for individual /// opcodes. template<typename SuperClass, unsigned Opc> @@ -307,6 +432,45 @@ public: } return true; } + + /// \brief Accumulate the constant address offset of this GEP if possible. + /// + /// This routine accepts an APInt into which it will accumulate the constant + /// offset of this GEP if the GEP is in fact constant. If the GEP is not + /// all-constant, it returns false and the value of the offset APInt is + /// undefined (it is *not* preserved!). The APInt passed into this routine + /// must be at least as wide as the IntPtr type for the address space of + /// the base GEP pointer. + bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { + assert(Offset.getBitWidth() == + DL.getPointerSizeInBits(getPointerAddressSpace()) && + "The offset must have exactly as many bits as our pointer."); + + for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); + GTI != GTE; ++GTI) { + ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); + if (!OpC) + return false; + if (OpC->isZero()) + continue; + + // Handle a struct index, which adds its field offset to the pointer. + if (StructType *STy = dyn_cast<StructType>(*GTI)) { + unsigned ElementIdx = OpC->getZExtValue(); + const StructLayout *SL = DL.getStructLayout(STy); + Offset += APInt(Offset.getBitWidth(), + SL->getElementOffset(ElementIdx)); + continue; + } + + // For array or vector indices, scale the index by the size of the type. + APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); + Offset += Index * APInt(Offset.getBitWidth(), + DL.getTypeAllocSize(GTI.getIndexedType())); + } + return true; + } + }; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/SymbolTableListTraits.h b/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h index ec5c88f..561ce01 100644 --- a/contrib/llvm/include/llvm/SymbolTableListTraits.h +++ b/contrib/llvm/include/llvm/IR/SymbolTableListTraits.h @@ -22,8 +22,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYMBOLTABLELISTTRAITS_H -#define LLVM_SYMBOLTABLELISTTRAITS_H +#ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H +#define LLVM_IR_SYMBOLTABLELISTTRAITS_H #include "llvm/ADT/ilist.h" diff --git a/contrib/llvm/include/llvm/Type.h b/contrib/llvm/include/llvm/IR/Type.h index def4575..d89ae24 100644 --- a/contrib/llvm/include/llvm/Type.h +++ b/contrib/llvm/include/llvm/IR/Type.h @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TYPE_H -#define LLVM_TYPE_H +#ifndef LLVM_IR_TYPE_H +#define LLVM_IR_TYPE_H +#include "llvm/ADT/APFloat.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -162,6 +164,18 @@ public: getTypeID() == PPC_FP128TyID; } + const fltSemantics &getFltSemantics() const { + switch (getTypeID()) { + case HalfTyID: return APFloat::IEEEhalf; + case FloatTyID: return APFloat::IEEEsingle; + case DoubleTyID: return APFloat::IEEEdouble; + case X86_FP80TyID: return APFloat::x87DoubleExtended; + case FP128TyID: return APFloat::IEEEquad; + case PPC_FP128TyID: return APFloat::PPCDoubleDouble; + default: llvm_unreachable("Invalid floating type"); + } + } + /// isX86_MMXTy - Return true if this is X86 MMX. bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; } diff --git a/contrib/llvm/include/llvm/TypeBuilder.h b/contrib/llvm/include/llvm/IR/TypeBuilder.h index 0b56479..80c60a0 100644 --- a/contrib/llvm/include/llvm/TypeBuilder.h +++ b/contrib/llvm/include/llvm/IR/TypeBuilder.h @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TYPEBUILDER_H -#define LLVM_TYPEBUILDER_H +#ifndef LLVM_IR_TYPEBUILDER_H +#define LLVM_IR_TYPEBUILDER_H -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" #include <limits.h> namespace llvm { diff --git a/contrib/llvm/include/llvm/TypeFinder.h b/contrib/llvm/include/llvm/IR/TypeFinder.h index 5d80705..cea66a4 100644 --- a/contrib/llvm/include/llvm/TypeFinder.h +++ b/contrib/llvm/include/llvm/IR/TypeFinder.h @@ -1,4 +1,4 @@ -//===-- llvm/TypeFinder.h - Class for finding used struct types -*- C++ -*-===// +//===-- llvm/IR/TypeFinder.h - Class to find used struct types --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TYPEFINDER_H -#define LLVM_TYPEFINDER_H +#ifndef LLVM_IR_TYPEFINDER_H +#define LLVM_IR_TYPEFINDER_H #include "llvm/ADT/DenseSet.h" #include <vector> diff --git a/contrib/llvm/include/llvm/Use.h b/contrib/llvm/include/llvm/IR/Use.h index 8080445..4bc7ce5 100644 --- a/contrib/llvm/include/llvm/Use.h +++ b/contrib/llvm/include/llvm/IR/Use.h @@ -22,8 +22,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_USE_H -#define LLVM_USE_H +#ifndef LLVM_IR_USE_H +#define LLVM_IR_USE_H #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Compiler.h" @@ -66,7 +66,6 @@ public: typedef PointerIntPair<User*, 1, unsigned> UserRef; private: - /// Copy ctor - do not implement Use(const Use &U) LLVM_DELETED_FUNCTION; /// Destructor - Only for zap() @@ -150,14 +149,14 @@ private: // casting operators. template<> struct simplify_type<Use> { typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const Use &Val) { - return static_cast<SimpleType>(Val.get()); + static SimpleType getSimplifiedValue(Use &Val) { + return Val.get(); } }; template<> struct simplify_type<const Use> { - typedef Value* SimpleType; + typedef /*const*/ Value* SimpleType; static SimpleType getSimplifiedValue(const Use &Val) { - return static_cast<SimpleType>(Val.get()); + return Val.get(); } }; diff --git a/contrib/llvm/include/llvm/User.h b/contrib/llvm/include/llvm/IR/User.h index df303d0..505bdeb 100644 --- a/contrib/llvm/include/llvm/User.h +++ b/contrib/llvm/include/llvm/IR/User.h @@ -16,11 +16,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_USER_H -#define LLVM_USER_H +#ifndef LLVM_IR_USER_H +#define LLVM_IR_USER_H +#include "llvm/IR/Value.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Value.h" namespace llvm { @@ -183,27 +183,17 @@ public: template<> struct simplify_type<User::op_iterator> { typedef Value* SimpleType; - - static SimpleType getSimplifiedValue(const User::op_iterator &Val) { - return static_cast<SimpleType>(Val->get()); + static SimpleType getSimplifiedValue(User::op_iterator &Val) { + return Val->get(); } }; - -template<> struct simplify_type<const User::op_iterator> - : public simplify_type<User::op_iterator> {}; - template<> struct simplify_type<User::const_op_iterator> { - typedef Value* SimpleType; - - static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) { - return static_cast<SimpleType>(Val->get()); + typedef /*const*/ Value* SimpleType; + static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { + return Val->get(); } }; -template<> struct simplify_type<const User::const_op_iterator> - : public simplify_type<User::const_op_iterator> {}; - - // value_use_iterator::getOperandNo - Requires the definition of the User class. template<typename UserTy> unsigned value_use_iterator<UserTy>::getOperandNo() const { diff --git a/contrib/llvm/include/llvm/Value.h b/contrib/llvm/include/llvm/IR/Value.h index 5b19435..a4f7862 100644 --- a/contrib/llvm/include/llvm/Value.h +++ b/contrib/llvm/include/llvm/IR/Value.h @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_VALUE_H -#define LLVM_VALUE_H +#ifndef LLVM_IR_VALUE_H +#define LLVM_IR_VALUE_H -#include "llvm/Use.h" +#include "llvm/IR/Use.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/include/llvm/ValueSymbolTable.h b/contrib/llvm/include/llvm/IR/ValueSymbolTable.h index 1738cc4..bf1fade 100644 --- a/contrib/llvm/include/llvm/ValueSymbolTable.h +++ b/contrib/llvm/include/llvm/IR/ValueSymbolTable.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_VALUE_SYMBOL_TABLE_H -#define LLVM_VALUE_SYMBOL_TABLE_H +#ifndef LLVM_IR_VALUESYMBOLTABLE_H +#define LLVM_IR_VALUESYMBOLTABLE_H -#include "llvm/Value.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/Value.h" #include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/IRReader/IRReader.h b/contrib/llvm/include/llvm/IRReader/IRReader.h new file mode 100644 index 0000000..e2ae5f7 --- /dev/null +++ b/contrib/llvm/include/llvm/IRReader/IRReader.h @@ -0,0 +1,55 @@ +//===---- llvm/IRReader/IRReader.h - Reader for LLVM IR files ---*- 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 functions for reading LLVM IR. They support both +// Bitcode and Assembly, automatically detecting the input format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IRREADER_IRREADER_H +#define LLVM_IRREADER_IRREADER_H + +#include <string> + +namespace llvm { + +class Module; +class MemoryBuffer; +class SMDiagnostic; +class LLVMContext; + +/// If the given MemoryBuffer holds a bitcode image, return a Module for it +/// which does lazy deserialization of function bodies. Otherwise, attempt to +/// parse it as LLVM Assembly and return a fully populated Module. This +/// function *always* takes ownership of the given MemoryBuffer. +Module *getLazyIRModule(MemoryBuffer *Buffer, SMDiagnostic &Err, + LLVMContext &Context); + +/// If the given file holds a bitcode image, return a Module +/// for it which does lazy deserialization of function bodies. Otherwise, +/// attempt to parse it as LLVM Assembly and return a fully populated +/// Module. +Module *getLazyIRFileModule(const std::string &Filename, SMDiagnostic &Err, + LLVMContext &Context); + +/// If the given MemoryBuffer holds a bitcode image, return a Module +/// for it. Otherwise, attempt to parse it as LLVM Assembly and return +/// a Module for it. This function *always* takes ownership of the given +/// MemoryBuffer. +Module *ParseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, LLVMContext &Context); + +/// If the given file holds a bitcode image, return a Module for it. +/// Otherwise, attempt to parse it as LLVM Assembly and return a Module +/// for it. +Module *ParseIRFile(const std::string &Filename, SMDiagnostic &Err, + LLVMContext &Context); + +} + +#endif diff --git a/contrib/llvm/include/llvm/InitializePasses.h b/contrib/llvm/include/llvm/InitializePasses.h index 8c164eb..9cc194b 100644 --- a/contrib/llvm/include/llvm/InitializePasses.h +++ b/contrib/llvm/include/llvm/InitializePasses.h @@ -31,6 +31,10 @@ void initializeTransformUtils(PassRegistry&); /// ScalarOpts library. void initializeScalarOpts(PassRegistry&); +/// initializeObjCARCOpts - Initialize all passes linked into the ObjCARCOpts +/// library. +void initializeObjCARCOpts(PassRegistry&); + /// initializeVectorization - Initialize all passes linked into the /// Vectorize library. void initializeVectorization(PassRegistry&); @@ -69,6 +73,7 @@ void initializeArgPromotionPass(PassRegistry&); void initializeBarrierNoopPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); +void initializeBasicTTIPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockFrequencyInfoPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); @@ -76,6 +81,8 @@ void initializeBoundsCheckingPass(PassRegistry&); void initializeBranchFolderPassPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); +void initializeCallGraphPrinterPass(PassRegistry&); +void initializeCallGraphViewerPass(PassRegistry&); void initializeCFGOnlyPrinterPass(PassRegistry&); void initializeCFGOnlyViewerPass(PassRegistry&); void initializeCFGPrinterPass(PassRegistry&); @@ -84,7 +91,6 @@ void initializeCFGViewerPass(PassRegistry&); void initializeCalculateSpillWeightsPass(PassRegistry&); void initializeCallGraphAnalysisGroup(PassRegistry&); void initializeCodeGenPreparePass(PassRegistry&); -void initializeCodePlacementOptPass(PassRegistry&); void initializeConstantMergePass(PassRegistry&); void initializeConstantPropagationPass(PassRegistry&); void initializeMachineCopyPropagationPass(PassRegistry&); @@ -110,12 +116,13 @@ void initializeExpandPostRAPass(PassRegistry&); void initializePathProfilerPass(PassRegistry&); void initializeGCOVProfilerPass(PassRegistry&); void initializeAddressSanitizerPass(PassRegistry&); +void initializeAddressSanitizerModulePass(PassRegistry&); +void initializeMemorySanitizerPass(PassRegistry&); void initializeThreadSanitizerPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); -void initializeGCInfoDeleterPass(PassRegistry&); void initializeGCMachineCodeAnalysisPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&); void initializeGVNPass(PassRegistry&); @@ -127,6 +134,7 @@ void initializeIPSCCPPass(PassRegistry&); void initializeIVUsersPass(PassRegistry&); void initializeIfConverterPass(PassRegistry&); void initializeIndVarSimplifyPass(PassRegistry&); +void initializeInlineCostAnalysisPass(PassRegistry&); void initializeInstCombinerPass(PassRegistry&); void initializeInstCountPass(PassRegistry&); void initializeInstNamerPass(PassRegistry&); @@ -172,7 +180,6 @@ void initializeMachineDominatorTreePass(PassRegistry&); void initializeMachinePostDominatorTreePass(PassRegistry&); void initializeMachineLICMPass(PassRegistry&); void initializeMachineLoopInfoPass(PassRegistry&); -void initializeMachineLoopRangesPass(PassRegistry&); void initializeMachineModuleInfoPass(PassRegistry&); void initializeMachineSchedulerPass(PassRegistry&); void initializeMachineSinkingPass(PassRegistry&); @@ -205,9 +212,9 @@ void initializePostDomViewerPass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&); void initializePostRASchedulerPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&); -void initializePrintDbgInfoPass(PassRegistry&); void initializePrintFunctionPassPass(PassRegistry&); void initializePrintModulePassPass(PassRegistry&); +void initializePrintBasicBlockPassPass(PassRegistry&); void initializeProcessImplicitDefsPass(PassRegistry&); void initializeProfileEstimatorPassPass(PassRegistry&); void initializeProfileInfoAnalysisGroup(PassRegistry&); @@ -249,7 +256,8 @@ void initializeTailCallElimPass(PassRegistry&); void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); void initializeDataLayoutPass(PassRegistry&); -void initializeTargetTransformInfoPass(PassRegistry&); +void initializeTargetTransformInfoAnalysisGroup(PassRegistry&); +void initializeNoTTIPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); void initializeTypeBasedAliasAnalysisPass(PassRegistry&); diff --git a/contrib/llvm/include/llvm/Support/InstVisitor.h b/contrib/llvm/include/llvm/InstVisitor.h index 6dfb4de..2911703 100644 --- a/contrib/llvm/include/llvm/Support/InstVisitor.h +++ b/contrib/llvm/include/llvm/InstVisitor.h @@ -1,4 +1,4 @@ -//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===// +//===- llvm/InstVisitor.h - Instruction visitor templates -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,14 +8,14 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_INSTVISITOR_H -#define LLVM_SUPPORT_INSTVISITOR_H +#ifndef LLVM_INSTVISITOR_H +#define LLVM_INSTVISITOR_H -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Module.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" @@ -25,7 +25,7 @@ namespace llvm { // types now... // #define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS; -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" #define DELEGATE(CLASS_TO_VISIT) \ return static_cast<SubClass*>(this)-> \ @@ -123,7 +123,7 @@ public: case Instruction::OPCODE: return \ static_cast<SubClass*>(this)-> \ visit##OPCODE(static_cast<CLASS&>(I)); -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" } } @@ -158,7 +158,7 @@ public: else \ DELEGATE(CLASS); \ } -#include "llvm/Instruction.def" +#include "llvm/IR/Instruction.def" // Specific Instruction type classes... note that all of the casts are // necessary because we use the instruction classes as opaque types... diff --git a/contrib/llvm/include/llvm/IntrinsicsCellSPU.td b/contrib/llvm/include/llvm/IntrinsicsCellSPU.td deleted file mode 100644 index 1e311bb..0000000 --- a/contrib/llvm/include/llvm/IntrinsicsCellSPU.td +++ /dev/null @@ -1,242 +0,0 @@ -//==- IntrinsicsCellSPU.td - Cell SDK intrinsics -*- tablegen -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// Department at The Aerospace Corporation and is distributed under the -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Cell SPU Instructions: -//===----------------------------------------------------------------------===// -// TODO Items (not urgent today, but would be nice, low priority) -// -// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by -// concatenating the byte argument b as "bbbb". Could recognize this bit pattern -// in 16-bit and 32-bit constants and reduce instruction count. -//===----------------------------------------------------------------------===// - -// 7-bit integer type, used as an immediate: -def cell_i7_ty: LLVMType<i8>; -def cell_i8_ty: LLVMType<i8>; - -// Keep this here until it's actually supported: -def llvm_i128_ty : LLVMType<i128>; - -class v16i8_u7imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, cell_i7_ty], - [IntrNoMem]>; - -class v16i8_u8imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; - -class v16i8_s10imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v16i8_u16imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v16i8_rr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], - [IntrNoMem]>; - -class v8i16_s10imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v8i16_u16imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v8i16_rr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - -class v4i32_rr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], - [IntrNoMem]>; - -class v4i32_u7imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, cell_i7_ty], - [IntrNoMem]>; - -class v4i32_s10imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v4i32_u16imm<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty], - [IntrNoMem]>; - -class v4f32_rr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - -class v4f32_rrr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - -class v2f64_rr<string builtin_suffix> : - GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - -// All Cell SPU intrinsics start with "llvm.spu.". -let TargetPrefix = "spu" in { - def int_spu_si_fsmbi : v8i16_u16imm<"fsmbi">; - def int_spu_si_ah : v8i16_rr<"ah">; - def int_spu_si_ahi : v8i16_s10imm<"ahi">; - def int_spu_si_a : v4i32_rr<"a">; - def int_spu_si_ai : v4i32_s10imm<"ai">; - def int_spu_si_sfh : v8i16_rr<"sfh">; - def int_spu_si_sfhi : v8i16_s10imm<"sfhi">; - def int_spu_si_sf : v4i32_rr<"sf">; - def int_spu_si_sfi : v4i32_s10imm<"sfi">; - def int_spu_si_addx : v4i32_rr<"addx">; - def int_spu_si_cg : v4i32_rr<"cg">; - def int_spu_si_cgx : v4i32_rr<"cgx">; - def int_spu_si_sfx : v4i32_rr<"sfx">; - def int_spu_si_bg : v4i32_rr<"bg">; - def int_spu_si_bgx : v4i32_rr<"bgx">; - def int_spu_si_mpy : // This is special: - GCCBuiltin<"__builtin_si_mpy">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyu : // This is special: - GCCBuiltin<"__builtin_si_mpyu">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyi : // This is special: - GCCBuiltin<"__builtin_si_mpyi">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyui : // This is special: - GCCBuiltin<"__builtin_si_mpyui">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty], - [IntrNoMem]>; - def int_spu_si_mpya : // This is special: - GCCBuiltin<"__builtin_si_mpya">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyh : // This is special: - GCCBuiltin<"__builtin_si_mpyh">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpys : // This is special: - GCCBuiltin<"__builtin_si_mpys">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyhh : // This is special: - GCCBuiltin<"__builtin_si_mpyhh">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyhha : // This is special: - GCCBuiltin<"__builtin_si_mpyhha">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyhhu : // This is special: - GCCBuiltin<"__builtin_si_mpyhhu">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - def int_spu_si_mpyhhau : // This is special: - GCCBuiltin<"__builtin_si_mpyhhau">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], - [IntrNoMem]>; - - def int_spu_si_shli: v4i32_u7imm<"shli">; - - def int_spu_si_shlqbi: - GCCBuiltin<!strconcat("__builtin_si_", "shlqbi")>, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], - [IntrNoMem]>; - - def int_spu_si_shlqbii: v16i8_u7imm<"shlqbii">; - def int_spu_si_shlqby: - GCCBuiltin<!strconcat("__builtin_si_", "shlqby")>, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_spu_si_shlqbyi: v16i8_u7imm<"shlqbyi">; - - def int_spu_si_ceq: v4i32_rr<"ceq">; - def int_spu_si_ceqi: v4i32_s10imm<"ceqi">; - def int_spu_si_ceqb: v16i8_rr<"ceqb">; - def int_spu_si_ceqbi: v16i8_u8imm<"ceqbi">; - def int_spu_si_ceqh: v8i16_rr<"ceqh">; - def int_spu_si_ceqhi: v8i16_s10imm<"ceqhi">; - def int_spu_si_cgt: v4i32_rr<"cgt">; - def int_spu_si_cgti: v4i32_s10imm<"cgti">; - def int_spu_si_cgtb: v16i8_rr<"cgtb">; - def int_spu_si_cgtbi: v16i8_u8imm<"cgtbi">; - def int_spu_si_cgth: v8i16_rr<"cgth">; - def int_spu_si_cgthi: v8i16_s10imm<"cgthi">; - def int_spu_si_clgtb: v16i8_rr<"clgtb">; - def int_spu_si_clgtbi: v16i8_u8imm<"clgtbi">; - def int_spu_si_clgth: v8i16_rr<"clgth">; - def int_spu_si_clgthi: v8i16_s10imm<"clgthi">; - def int_spu_si_clgt: v4i32_rr<"clgt">; - def int_spu_si_clgti: v4i32_s10imm<"clgti">; - - def int_spu_si_and: v4i32_rr<"and">; - def int_spu_si_andbi: v16i8_u8imm<"andbi">; - def int_spu_si_andc: v4i32_rr<"andc">; - def int_spu_si_andhi: v8i16_s10imm<"andhi">; - def int_spu_si_andi: v4i32_s10imm<"andi">; - - def int_spu_si_or: v4i32_rr<"or">; - def int_spu_si_orbi: v16i8_u8imm<"orbi">; - def int_spu_si_orc: v4i32_rr<"orc">; - def int_spu_si_orhi: v8i16_s10imm<"orhi">; - def int_spu_si_ori: v4i32_s10imm<"ori">; - - def int_spu_si_xor: v4i32_rr<"xor">; - def int_spu_si_xorbi: v16i8_u8imm<"xorbi">; - def int_spu_si_xorhi: v8i16_s10imm<"xorhi">; - def int_spu_si_xori: v4i32_s10imm<"xori">; - - def int_spu_si_nor: v4i32_rr<"nor">; - def int_spu_si_nand: v4i32_rr<"nand">; - - def int_spu_si_fa: v4f32_rr<"fa">; - def int_spu_si_fs: v4f32_rr<"fs">; - def int_spu_si_fm: v4f32_rr<"fm">; - - def int_spu_si_fceq: v4f32_rr<"fceq">; - def int_spu_si_fcmeq: v4f32_rr<"fcmeq">; - def int_spu_si_fcgt: v4f32_rr<"fcgt">; - def int_spu_si_fcmgt: v4f32_rr<"fcmgt">; - - def int_spu_si_fma: v4f32_rrr<"fma">; - def int_spu_si_fnms: v4f32_rrr<"fnms">; - def int_spu_si_fms: v4f32_rrr<"fms">; - - def int_spu_si_dfa: v2f64_rr<"dfa">; - def int_spu_si_dfs: v2f64_rr<"dfs">; - def int_spu_si_dfm: v2f64_rr<"dfm">; - -//def int_spu_si_dfceq: v2f64_rr<"dfceq">; -//def int_spu_si_dfcmeq: v2f64_rr<"dfcmeq">; -//def int_spu_si_dfcgt: v2f64_rr<"dfcgt">; -//def int_spu_si_dfcmgt: v2f64_rr<"dfcmgt">; - - def int_spu_si_dfnma: v2f64_rr<"dfnma">; - def int_spu_si_dfma: v2f64_rr<"dfma">; - def int_spu_si_dfnms: v2f64_rr<"dfnms">; - def int_spu_si_dfms: v2f64_rr<"dfms">; -} diff --git a/contrib/llvm/include/llvm/LinkAllVMCore.h b/contrib/llvm/include/llvm/LinkAllIR.h index 83684c0..4c1aaca 100644 --- a/contrib/llvm/include/llvm/LinkAllVMCore.h +++ b/contrib/llvm/include/llvm/LinkAllIR.h @@ -1,4 +1,4 @@ -//===- LinkAllVMCore.h - Reference All VMCore Code --------------*- C++ -*-===// +//===----- LinkAllIR.h - Reference All VMCore Code --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,16 +13,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LINKALLVMCORE_H -#define LLVM_LINKALLVMCORE_H +#ifndef LLVM_LINKALLIR_H +#define LLVM_LINKALLIR_H -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/InlineAsm.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Memory.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Path.h" @@ -30,8 +32,6 @@ #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TimeValue.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/MathExtras.h" #include <cstdlib> namespace { diff --git a/contrib/llvm/include/llvm/LinkAllPasses.h b/contrib/llvm/include/llvm/LinkAllPasses.h index 806e4b3..1f017e4 100644 --- a/contrib/llvm/include/llvm/LinkAllPasses.h +++ b/contrib/llvm/include/llvm/LinkAllPasses.h @@ -16,23 +16,25 @@ #define LLVM_LINKALLPASSES_H #include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Analysis/CallPrinter.h" #include "llvm/Analysis/DomPrinter.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/IntervalPartition.h" +#include "llvm/Analysis/Lint.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/RegionPass.h" #include "llvm/Analysis/RegionPrinter.h" #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/Lint.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Function.h" -#include "llvm/Transforms/Instrumentation.h" +#include "llvm/IR/Function.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/ObjCARC.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Vectorize.h" #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" +#include "llvm/Transforms/Vectorize.h" #include <cstdlib> namespace { @@ -57,6 +59,8 @@ namespace { (void) llvm::createBlockPlacementPass(); (void) llvm::createBoundsCheckingPass(); (void) llvm::createBreakCriticalEdgesPass(); + (void) llvm::createCallGraphPrinterPass(); + (void) llvm::createCallGraphViewerPass(); (void) llvm::createCFGSimplificationPass(); (void) llvm::createConstantMergePass(); (void) llvm::createConstantPropagationPass(); @@ -147,7 +151,7 @@ namespace { (void) llvm::createMergeFunctionsPass(); (void) llvm::createPrintModulePass(0); (void) llvm::createPrintFunctionPass("", 0); - (void) llvm::createDbgInfoPrinterPass(); + (void) llvm::createPrintBasicBlockPass(0); (void) llvm::createModuleDebugInfoPrinterPass(); (void) llvm::createPartialInliningPass(); (void) llvm::createLintPass(); diff --git a/contrib/llvm/include/llvm/Linker.h b/contrib/llvm/include/llvm/Linker.h index 1ebcd6b..6796384 100644 --- a/contrib/llvm/include/llvm/Linker.h +++ b/contrib/llvm/include/llvm/Linker.h @@ -6,10 +6,6 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the interface to the module/file/archive linker. -// -//===----------------------------------------------------------------------===// #ifndef LLVM_LINKER_H #define LLVM_LINKER_H @@ -19,7 +15,6 @@ #include <vector> namespace llvm { - namespace sys { class Path; } class Module; class LLVMContext; @@ -31,26 +26,17 @@ class StringRef; /// In this case the Linker still retains ownership of the Module. If the /// releaseModule() method is used, the ownership of the Module is transferred /// to the caller and the Linker object is only suitable for destruction. -/// The Linker can link Modules from memory, bitcode files, or bitcode -/// archives. It retains a set of search paths in which to find any libraries -/// presented to it. By default, the linker will generate error and warning -/// messages to stderr but this capability can be turned off with the -/// QuietWarnings and QuietErrors flags. It can also be instructed to verbosely -/// print out the linking actions it is taking with the Verbose flag. +/// The Linker can link Modules from memory. By default, the linker +/// will generate error and warning messages to stderr but this capability can +/// be turned off with the QuietWarnings and QuietErrors flags. It can also be +/// instructed to verbosely print out the linking actions it is taking with +/// the Verbose flag. /// @brief The LLVM Linker. class Linker { /// @name Types /// @{ public: - /// This type is used to pass the linkage items (libraries and files) to - /// the LinkItems function. It is composed of string/bool pairs. The string - /// provides the name of the file or library (as with the -l option). The - /// bool should be true for libraries and false for files, signifying - /// "isLibrary". - /// @brief A list of linkage items - typedef std::vector<std::pair<std::string,bool> > ItemList; - /// This enumeration is used to control various optional features of the /// linker. enum ControlFlags { @@ -58,12 +44,12 @@ class Linker { QuietWarnings = 2, ///< Don't print warnings to stderr. QuietErrors = 4 ///< Don't print errors to stderr. }; - + enum LinkerMode { DestroySource = 0, // Allow source module to be destroyed. PreserveSource = 1 // Preserve the source module. }; - + /// @} /// @name Constructors /// @{ @@ -104,16 +90,10 @@ class Linker { /// must arrange for its destruct. After this method is called, the Linker /// terminates the linking session for the returned Module. It will no /// longer utilize the returned Module but instead resets itself for - /// subsequent linking as if the constructor had been called. The Linker's - /// LibPaths and flags to be reset, and memory will be released. + /// subsequent linking as if the constructor had been called. /// @brief Release the linked/composite module. Module* releaseModule(); - /// This method gets the list of libraries that form the path that the - /// Linker will search when it is presented with a library name. - /// @brief Get the Linkers library path - const std::vector<sys::Path>& getLibPaths() const { return LibPaths; } - /// This method returns an error string suitable for printing to the user. /// The return value will be empty unless an error occurred in one of the /// LinkIn* methods. In those cases, the LinkIn* methods will have returned @@ -128,130 +108,16 @@ class Linker { /// @name Mutators /// @{ public: - /// Add a path to the list of paths that the Linker will search. The Linker - /// accumulates the set of libraries added - /// library paths for the target platform. The standard libraries will - /// always be searched last. The added libraries will be searched in the - /// order added. - /// @brief Add a path. - void addPath(const sys::Path& path); - - /// Add a set of paths to the list of paths that the linker will search. The - /// Linker accumulates the set of libraries added. The \p paths will be - /// added to the end of the Linker's list. Order will be retained. - /// @brief Add a set of paths. - void addPaths(const std::vector<std::string>& paths); - - /// This method augments the Linker's list of library paths with the system - /// paths of the host operating system, include LLVM_LIB_SEARCH_PATH. - /// @brief Add the system paths. - void addSystemPaths(); - - /// Control optional linker behavior by setting a group of flags. The flags - /// are defined in the ControlFlags enumeration. - /// @see ControlFlags - /// @brief Set control flags. - void setFlags(unsigned flags) { Flags = flags; } - - /// This method is the main interface to the linker. It can be used to - /// link a set of linkage items into a module. A linkage item is either a - /// file name with fully qualified path, or a library for which the Linker's - /// LibraryPath will be utilized to locate the library. The bool value in - /// the LinkItemKind should be set to true for libraries. This function - /// allows linking to preserve the order of specification associated with - /// the command line, or for other purposes. Each item will be linked in - /// turn as it occurs in \p Items. - /// @returns true if an error occurred, false otherwise - /// @see LinkItemKind - /// @see getLastError - bool LinkInItems ( - const ItemList& Items, ///< Set of libraries/files to link in - ItemList& NativeItems ///< Output list of native files/libs - ); - - /// This function links the bitcode \p Files into the composite module. - /// Note that this does not do any linking of unresolved symbols. The \p - /// Files are all completely linked into \p HeadModule regardless of - /// unresolved symbols. This function just loads each bitcode file and - /// calls LinkInModule on them. - /// @returns true if an error occurs, false otherwise - /// @see getLastError - /// @brief Link in multiple files. - bool LinkInFiles ( - const std::vector<sys::Path> & Files ///< Files to link in - ); - - /// This function links a single bitcode file, \p File, into the composite - /// module. Note that this does not attempt to resolve symbols. This method - /// just loads the bitcode file and calls LinkInModule on it. If an error - /// occurs, the Linker's error string is set. - /// @returns true if an error occurs, false otherwise - /// @see getLastError - /// @brief Link in a single file. - bool LinkInFile( - const sys::Path& File, ///< File to link in. - bool &is_native ///< Indicates if the file is native object file - ); - - /// This function provides a way to selectively link in a set of modules, - /// found in libraries, based on the unresolved symbols in the composite - /// module. Each item in \p Libraries should be the base name of a library, - /// as if given with the -l option of a linker tool. The Linker's LibPaths - /// are searched for the \p Libraries and any found will be linked in with - /// LinkInArchive. If an error occurs, the Linker's error string is set. - /// @see LinkInArchive - /// @see getLastError - /// @returns true if an error occurs, false otherwise - /// @brief Link libraries into the module - bool LinkInLibraries ( - const std::vector<std::string> & Libraries ///< Libraries to link in - ); - - /// This function provides a way to selectively link in a set of modules, - /// found in one library, based on the unresolved symbols in the composite - /// module.The \p Library should be the base name of a library, as if given - /// with the -l option of a linker tool. The Linker's LibPaths are searched - /// for the \p Library and if found, it will be linked in with via the - /// LinkInArchive method. If an error occurs, the Linker's error string is - /// set. - /// @see LinkInArchive - /// @see getLastError - /// @returns true if an error occurs, false otherwise - /// @brief Link one library into the module - bool LinkInLibrary ( - StringRef Library, ///< The library to link in - bool& is_native ///< Indicates if lib a native library - ); - - /// This function links one bitcode archive, \p Filename, into the module. - /// The archive is searched to resolve outstanding symbols. Any modules in - /// the archive that resolve outstanding symbols will be linked in. The - /// library is searched repeatedly until no more modules that resolve - /// symbols can be found. If an error occurs, the error string is set. - /// To speed up this function, ensure the archive has been processed - /// llvm-ranlib or the S option was given to llvm-ar when the archive was - /// created. These tools add a symbol table to the archive which makes the - /// search for undefined symbols much faster. - /// @see getLastError - /// @returns true if an error occurs, otherwise false. - /// @brief Link in one archive. - bool LinkInArchive( - const sys::Path& Filename, ///< Filename of the archive to link - bool& is_native ///< Indicates if archive is a native archive - ); - /// This method links the \p Src module into the Linker's Composite module - /// by calling LinkModules. All the other LinkIn* methods eventually - /// result in calling this method to link a Module into the Linker's - /// composite. + /// by calling LinkModules. /// @see LinkModules /// @returns True if an error occurs, false otherwise. /// @brief Link in a module. bool LinkInModule( Module* Src, ///< Module linked into \p Dest std::string* ErrorMsg = 0 /// Error/diagnostic string - ) { - return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg ); + ) { + return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg); } /// This is the heart of the linker. This method will take unconditional @@ -268,21 +134,10 @@ class Linker { static bool LinkModules(Module* Dest, Module* Src, unsigned Mode, std::string* ErrorMsg); - /// This function looks through the Linker's LibPaths to find a library with - /// the name \p Filename. If the library cannot be found, the returned path - /// will be empty (i.e. sys::Path::isEmpty() will return true). - /// @returns A sys::Path to the found library - /// @brief Find a library from its short name. - sys::Path FindLib(StringRef Filename); - /// @} /// @name Implementation /// @{ private: - /// Read in and parse the bitcode file named by FN and return the - /// Module it contains (wrapped in an auto_ptr), or 0 if an error occurs. - std::auto_ptr<Module> LoadObject(const sys::Path& FN); - bool warning(StringRef message); bool error(StringRef message); void verbose(StringRef message); @@ -293,7 +148,6 @@ class Linker { private: LLVMContext& Context; ///< The context for global information Module* Composite; ///< The composite module linked together - std::vector<sys::Path> LibPaths; ///< The library search paths unsigned Flags; ///< Flags to control optional behavior. std::string Error; ///< Text of error that occurred. std::string ProgramName; ///< Name of the program being linked diff --git a/contrib/llvm/include/llvm/MC/EDInstInfo.h b/contrib/llvm/include/llvm/MC/EDInstInfo.h deleted file mode 100644 index 5b02467..0000000 --- a/contrib/llvm/include/llvm/MC/EDInstInfo.h +++ /dev/null @@ -1,29 +0,0 @@ -//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef EDINSTINFO_H -#define EDINSTINFO_H - -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -#define EDIS_MAX_OPERANDS 13 -#define EDIS_MAX_SYNTAXES 2 - -struct EDInstInfo { - uint8_t instructionType; - uint8_t numOperands; - uint8_t operandTypes[EDIS_MAX_OPERANDS]; - uint8_t operandFlags[EDIS_MAX_OPERANDS]; - const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; -}; - -} // namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/MC/MCAsmBackend.h b/contrib/llvm/include/llvm/MC/MCAsmBackend.h index 72ed1a3..9a6b703 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmBackend.h +++ b/contrib/llvm/include/llvm/MC/MCAsmBackend.h @@ -22,7 +22,7 @@ class MCELFObjectTargetWriter; struct MCFixupKindInfo; class MCFragment; class MCInst; -class MCInstFragment; +class MCRelaxableFragment; class MCObjectWriter; class MCSection; class MCValue; @@ -41,6 +41,9 @@ protected: // Can only create subclasses. public: virtual ~MCAsmBackend(); + /// lifetime management + virtual void reset() { } + /// createObjectWriter - Create a new MCObjectWriter instance for use by the /// assembler backend to emit the final object file. virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; @@ -127,7 +130,7 @@ public: /// fixup requires the associated instruction to be relaxed. virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCInstFragment *DF, + const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfo.h b/contrib/llvm/include/llvm/MC/MCAsmInfo.h index 97aad71..28256b3 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmInfo.h +++ b/contrib/llvm/include/llvm/MC/MCAsmInfo.h @@ -13,11 +13,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_ASM_INFO_H -#define LLVM_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFO_H +#define LLVM_MC_MCASMINFO_H -#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MachineLocation.h" #include <cassert> #include <vector> @@ -48,6 +48,11 @@ namespace llvm { /// Default is 4. unsigned PointerSize; + /// CalleeSaveStackSlotSize - Size of the stack slot reserved for + /// callee-saved registers, in bytes. + /// Default is same as pointer size. + unsigned CalleeSaveStackSlotSize; + /// IsLittleEndian - True if target is little endian. /// Default is true. bool IsLittleEndian; @@ -102,6 +107,9 @@ namespace llvm { /// LabelSuffix - This is appended to emitted labels. const char *LabelSuffix; // Defaults to ":" + /// LabelSuffix - This is appended to emitted labels. + const char *DebugLabelSuffix; // Defaults to ":" + /// GlobalPrefix - If this is set to a non-empty string, it is prepended /// onto all global symbols. This is often used for "_" or ".". const char *GlobalPrefix; // Defaults to "" @@ -340,7 +348,13 @@ namespace llvm { return PointerSize; } - /// islittleendian - True if the target is little endian. + /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot + /// size in bytes. + unsigned getCalleeSaveStackSlotSize() const { + return CalleeSaveStackSlotSize; + } + + /// isLittleEndian - True if the target is little endian. bool isLittleEndian() const { return IsLittleEndian; } @@ -426,6 +440,11 @@ namespace llvm { const char *getLabelSuffix() const { return LabelSuffix; } + + const char *getDebugLabelSuffix() const { + return DebugLabelSuffix; + } + const char *getGlobalPrefix() const { return GlobalPrefix; } diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h index 0ff3e12..7286151 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h +++ b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_COFF_TARGET_ASM_INFO_H -#define LLVM_COFF_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFOCOFF_H +#define LLVM_MC_MCASMINFOCOFF_H #include "llvm/MC/MCAsmInfo.h" @@ -33,4 +33,4 @@ namespace llvm { } -#endif // LLVM_COFF_TARGET_ASM_INFO_H +#endif // LLVM_MC_MCASMINFOCOFF_H diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h index af552de..3d249f9 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h +++ b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H -#define LLVM_DARWIN_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFODARWIN_H +#define LLVM_MC_MCASMINFODARWIN_H #include "llvm/MC/MCAsmInfo.h" @@ -26,4 +26,4 @@ namespace llvm { } -#endif // LLVM_DARWIN_TARGET_ASM_INFO_H +#endif // LLVM_MC_MCASMINFODARWIN_H diff --git a/contrib/llvm/include/llvm/MC/MCAsmLayout.h b/contrib/llvm/include/llvm/MC/MCAsmLayout.h index cf79216..3058b7b 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmLayout.h +++ b/contrib/llvm/include/llvm/MC/MCAsmLayout.h @@ -21,10 +21,10 @@ class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// -/// Assembly may requiring compute multiple layouts for a particular assembly +/// Assembly may require computing multiple layouts for a particular assembly /// file as part of the relaxation process. This class encapsulates the layout /// at a single point in time in such a way that it is always possible to -/// efficiently compute the exact addresses of any symbol in the assembly file, +/// efficiently compute the exact address of any symbol in the assembly file, /// even during the relaxation process. class MCAsmLayout { public: @@ -39,14 +39,20 @@ private: /// 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; + /// lower ordinal will be valid. + mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment; /// \brief Make sure that the layout for the given fragment is valid, lazily /// computing it if necessary. - void EnsureValid(const MCFragment *F) const; + void ensureValid(const MCFragment *F) const; - bool isFragmentUpToDate(const MCFragment *F) const; + /// \brief Is the layout for this fragment valid? + bool isFragmentValid(const MCFragment *F) const; + + /// \brief Compute the amount of padding required before this fragment to + /// obey bundling restrictions. + uint64_t computeBundlePadding(const MCFragment *F, + uint64_t FOffset, uint64_t FSize); public: MCAsmLayout(MCAssembler &_Assembler); @@ -54,14 +60,15 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Invalidate all following fragments because a fragment has been - /// resized. The fragments size should have already been updated. - void Invalidate(MCFragment *F); + /// \brief Invalidate the fragments starting with F because it has been + /// resized. The fragment's size should have already been updated, but + /// its bundle padding will be recomputed. + void invalidateFragmentsFrom(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous /// fragment has already been laid out correctly, and the parent section has /// been initialized. - void LayoutFragment(MCFragment *Fragment); + void layoutFragment(MCFragment *Fragment); /// @name Section Access (in layout order) /// @{ diff --git a/contrib/llvm/include/llvm/MC/MCAssembler.h b/contrib/llvm/include/llvm/MC/MCAssembler.h index 5771415..43fbdc9 100644 --- a/contrib/llvm/include/llvm/MC/MCAssembler.h +++ b/contrib/llvm/include/llvm/MC/MCAssembler.h @@ -10,13 +10,13 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInst.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -47,8 +47,9 @@ public: enum FragmentType { FT_Align, FT_Data, + FT_CompactEncodedInst, FT_Fill, - FT_Inst, + FT_Relaxable, FT_Org, FT_Dwarf, FT_DwarfFrame, @@ -99,42 +100,139 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } + /// \brief Does this fragment have instructions emitted into it? By default + /// this is false, but specific fragment types may set it to true. + virtual bool hasInstructions() const { return false; } + + /// \brief Should this fragment be placed at the end of an aligned bundle? + virtual bool alignToBundleEnd() const { return false; } + virtual void setAlignToBundleEnd(bool V) { } + + /// \brief Get the padding size that must be inserted before this fragment. + /// Used for bundling. By default, no padding is inserted. + /// Note that padding size is restricted to 8 bits. This is an optimization + /// to reduce the amount of space used for each fragment. In practice, larger + /// padding should never be required. + virtual uint8_t getBundlePadding() const { + return 0; + } + + /// \brief Set the padding size for this fragment. By default it's a no-op, + /// and only some fragments have a meaningful implementation. + virtual void setBundlePadding(uint8_t N) { + } + void dump(); }; -class MCDataFragment : public MCFragment { +/// Interface implemented by fragments that contain encoded instructions and/or +/// data. +/// +class MCEncodedFragment : public MCFragment { virtual void anchor(); - SmallString<32> Contents; - - /// Fixups - The list of fixups in this fragment. - std::vector<MCFixup> Fixups; + uint8_t BundlePadding; public: - typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; - typedef std::vector<MCFixup>::iterator fixup_iterator; + MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) + : MCFragment(FType, SD), BundlePadding(0) + { + } + virtual ~MCEncodedFragment(); + + virtual SmallVectorImpl<char> &getContents() = 0; + virtual const SmallVectorImpl<char> &getContents() const = 0; + + virtual uint8_t getBundlePadding() const { + return BundlePadding; + } + + virtual void setBundlePadding(uint8_t N) { + BundlePadding = N; + } + + static bool classof(const MCFragment *F) { + MCFragment::FragmentType Kind = F->getKind(); + switch (Kind) { + default: + return false; + case MCFragment::FT_Relaxable: + case MCFragment::FT_CompactEncodedInst: + case MCFragment::FT_Data: + return true; + } + } +}; + +/// Interface implemented by fragments that contain encoded instructions and/or +/// data and also have fixups registered. +/// +class MCEncodedFragmentWithFixups : public MCEncodedFragment { + virtual void anchor(); public: - MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} + MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, + MCSectionData *SD = 0) + : MCEncodedFragment(FType, SD) + { + } - /// @name Accessors - /// @{ + virtual ~MCEncodedFragmentWithFixups(); - SmallString<32> &getContents() { return Contents; } - const SmallString<32> &getContents() const { return Contents; } + typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - /// @} - /// @name Fixup Access - /// @{ + virtual SmallVectorImpl<MCFixup> &getFixups() = 0; + virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; + + virtual fixup_iterator fixup_begin() = 0; + virtual const_fixup_iterator fixup_begin() const = 0; + virtual fixup_iterator fixup_end() = 0; + virtual const_fixup_iterator fixup_end() const = 0; + + static bool classof(const MCFragment *F) { + MCFragment::FragmentType Kind = F->getKind(); + return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; + } +}; + +/// Fragment for data and encoded instructions. +/// +class MCDataFragment : public MCEncodedFragmentWithFixups { + virtual void anchor(); + + /// \brief Does this fragment contain encoded instructions anywhere in it? + bool HasInstructions; + + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; + + SmallVector<char, 32> Contents; - void addFixup(MCFixup Fixup) { - // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) && - "Fixups must be added in order!"); - Fixups.push_back(Fixup); + /// Fixups - The list of fixups in this fragment. + SmallVector<MCFixup, 4> Fixups; +public: + MCDataFragment(MCSectionData *SD = 0) + : MCEncodedFragmentWithFixups(FT_Data, SD), + HasInstructions(false), AlignToBundleEnd(false) + { } - std::vector<MCFixup> &getFixups() { return Fixups; } - const std::vector<MCFixup> &getFixups() const { return Fixups; } + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } + + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; + } + + virtual bool hasInstructions() const { return HasInstructions; } + virtual void setHasInstructions(bool V) { HasInstructions = V; } + + virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } + virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -142,60 +240,79 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Data; + } +}; - /// @} +/// This is a compact (memory-size-wise) fragment for holding an encoded +/// instruction (non-relaxable) that has no fixups registered. When applicable, +/// it can be used instead of MCDataFragment and lead to lower memory +/// consumption. +/// +class MCCompactEncodedInstFragment : public MCEncodedFragment { + virtual void anchor(); + + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; + + SmallVector<char, 4> Contents; +public: + MCCompactEncodedInstFragment(MCSectionData *SD = 0) + : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) + { + } + + virtual bool hasInstructions() const { + return true; + } + + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + + virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } + virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Data; + return F->getKind() == MCFragment::FT_CompactEncodedInst; } }; -// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as -// it is almost entirely a duplicate of MCDataFragment. If we decide to stick -// with this approach (as opposed to making MCInstFragment a very light weight -// object with just the MCInst and a code size, then we should just change -// MCDataFragment to have an optional MCInst at its end. -class MCInstFragment : public MCFragment { +/// A relaxable fragment holds on to its MCInst, since it may need to be +/// relaxed during the assembler layout and relaxation stage. +/// +class MCRelaxableFragment : public MCEncodedFragmentWithFixups { virtual void anchor(); /// Inst - The instruction this is a fragment for. MCInst Inst; - /// Code - Binary data for the currently encoded instruction. - SmallString<8> Code; + /// Contents - Binary data for the currently encoded instruction. + SmallVector<char, 8> Contents; /// Fixups - The list of fixups in this fragment. SmallVector<MCFixup, 1> Fixups; public: - typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - -public: - MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCFragment(FT_Inst, SD), Inst(_Inst) { + MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) + : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) { } - /// @name Accessors - /// @{ - - SmallVectorImpl<char> &getCode() { return Code; } - const SmallVectorImpl<char> &getCode() const { return Code; } + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } - unsigned getInstSize() const { return Code.size(); } - - MCInst &getInst() { return Inst; } const MCInst &getInst() const { return Inst; } - void setInst(const MCInst& Value) { Inst = Value; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } + + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; + } - SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } - const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } + virtual bool hasInstructions() const { return true; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -203,12 +320,8 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } - - /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Inst; + return F->getKind() == MCFragment::FT_Relaxable; } }; @@ -442,6 +555,12 @@ public: typedef FragmentListType::const_reverse_iterator const_reverse_iterator; typedef FragmentListType::reverse_iterator reverse_iterator; + /// \brief Express the state of bundle locked groups while emitting code. + enum BundleLockStateType { + NotBundleLocked, + BundleLocked, + BundleLockedAlignToEnd + }; private: FragmentListType Fragments; const MCSection *Section; @@ -455,6 +574,13 @@ private: /// Alignment - The maximum alignment seen in this section. unsigned Alignment; + /// \brief Keeping track of bundle-locked state. + BundleLockStateType BundleLockState; + + /// \brief We've seen a bundle_lock directive but not its first instruction + /// yet. + bool BundleGroupBeforeFirstInst; + /// @name Assembler Backend Data /// @{ // @@ -507,6 +633,26 @@ public: bool empty() const { return Fragments.empty(); } + bool isBundleLocked() const { + return BundleLockState != NotBundleLocked; + } + + BundleLockStateType getBundleLockState() const { + return BundleLockState; + } + + void setBundleLockState(BundleLockStateType NewState) { + BundleLockState = NewState; + } + + bool isBundleGroupBeforeFirstInst() const { + return BundleGroupBeforeFirstInst; + } + + void setBundleGroupBeforeFirstInst(bool IsFirst) { + BundleGroupBeforeFirstInst = IsFirst; + } + void dump(); /// @} @@ -703,6 +849,10 @@ private: std::vector<IndirectSymbolData> IndirectSymbols; std::vector<DataRegionData> DataRegions; + + /// The list of linker options to propagate into the object file. + std::vector<std::vector<std::string> > LinkerOptions; + /// The set of function symbols for which a .thumb_func directive has /// been seen. // @@ -712,10 +862,21 @@ private: // refactoring too. SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; + /// \brief The bundle alignment size currently set in the assembler. + /// + /// By default it's 0, which means bundling is disabled. + unsigned BundleAlignSize; + unsigned RelaxAll : 1; unsigned NoExecStack : 1; unsigned SubsectionsViaSymbols : 1; + /// ELF specific e_header flags + // It would be good if there were an MCELFAssembler class to hold this. + // ELF header flags are used both by the integrated and standalone assemblers. + // Access to the flags is necessary in cases where assembler directives affect + // which flags to be set. + unsigned ELFHeaderEFlags; private: /// Evaluate a fixup to a relocatable expression and the value which should be /// placed into the fixup. @@ -736,20 +897,22 @@ private: /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, + bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. - bool fragmentNeedsRelaxation(const MCInstFragment *IF, + bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, const MCAsmLayout &Layout) const; - /// layoutOnce - Perform one layout iteration and return true if any offsets + /// \brief Perform one layout iteration and return true if any offsets /// were adjusted. bool layoutOnce(MCAsmLayout &Layout); + /// \brief Perform one layout iteration of the given section and return true + /// if any offsets were adjusted. bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); - bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); + bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); @@ -791,6 +954,10 @@ public: /// Flag a function symbol as the target of a .thumb_func directive. void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } + /// ELF e_header flags + unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} + void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} + public: /// Construct a new assembler instance. /// @@ -805,6 +972,10 @@ public: raw_ostream &OS); ~MCAssembler(); + /// Reuse an assembler instance + /// + void reset(); + MCContext &getContext() const { return Context; } MCAsmBackend &getBackend() const { return Backend; } @@ -832,6 +1003,20 @@ public: bool getNoExecStack() const { return NoExecStack; } void setNoExecStack(bool Value) { NoExecStack = Value; } + bool isBundlingEnabled() const { + return BundleAlignSize != 0; + } + + unsigned getBundleAlignSize() const { + return BundleAlignSize; + } + + void setBundleAlignSize(unsigned Size) { + assert((Size == 0 || !(Size & (Size - 1))) && + "Expect a power-of-two bundle align size"); + BundleAlignSize = Size; + } + /// @name Section List Access /// @{ @@ -889,6 +1074,14 @@ public: size_t indirect_symbol_size() const { return IndirectSymbols.size(); } /// @} + /// @name Linker Option List Access + /// @{ + + std::vector<std::vector<std::string> > &getLinkerOptions() { + return LinkerOptions; + } + + /// @} /// @name Data Region List Access /// @{ diff --git a/contrib/llvm/include/llvm/MC/MCAtom.h b/contrib/llvm/include/llvm/MC/MCAtom.h index 682cf7c..ae5bf0b 100644 --- a/contrib/llvm/include/llvm/MC/MCAtom.h +++ b/contrib/llvm/include/llvm/MC/MCAtom.h @@ -46,8 +46,8 @@ class MCAtom { : Type(T), Parent(P), Begin(B), End(E) { } public: - bool isTextAtom() { return Type == TextAtom; } - bool isDataAtom() { return Type == DataAtom; } + bool isTextAtom() const { return Type == TextAtom; } + bool isDataAtom() const { return Type == DataAtom; } void addInst(const MCInst &I, uint64_t Address, unsigned Size); void addData(const MCData &D); diff --git a/contrib/llvm/include/llvm/MC/MCCodeEmitter.h b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h index 0574890..9bfa08e 100644 --- a/contrib/llvm/include/llvm/MC/MCCodeEmitter.h +++ b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h @@ -29,6 +29,9 @@ protected: // Can only create subclasses. public: virtual ~MCCodeEmitter(); + /// Lifetime management + virtual void reset() { } + /// EncodeInstruction - Encode the given \p Inst to bytes on the output /// stream \p OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, diff --git a/contrib/llvm/include/llvm/MC/MCContext.h b/contrib/llvm/include/llvm/MC/MCContext.h index 5a8830c..0db3dee 100644 --- a/contrib/llvm/include/llvm/MC/MCContext.h +++ b/contrib/llvm/include/llvm/MC/MCContext.h @@ -10,13 +10,15 @@ #ifndef LLVM_MC_MCCONTEXT_H #define LLVM_MC_MCCONTEXT_H -#include "llvm/MC/SectionKind.h" -#include "llvm/MC/MCDwarf.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" +#include <map> #include <vector> // FIXME: Shouldn't be needed. namespace llvm { @@ -94,9 +96,19 @@ namespace llvm { /// .secure_log_reset appearing between them. bool SecureLogUsed; + /// The compilation directory to use for DW_AT_comp_dir. + std::string CompilationDir; + + /// The main file name if passed in explicitly. + std::string MainFileName; + /// The dwarf file and directory tables from the dwarf .file directive. - std::vector<MCDwarfFile *> MCDwarfFiles; - std::vector<StringRef> MCDwarfDirs; + /// We now emit a line table for each compile unit. To reduce the prologue + /// size of each line table, the files and directories used by each compile + /// unit are separated. + typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap; + MCDwarfFilesMap MCDwarfFilesCUMap; + std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap; /// The current dwarf line information from the last dwarf .loc directive. MCDwarfLoc CurrentDwarfLoc; @@ -123,6 +135,10 @@ namespace llvm { /// non-empty. StringRef DwarfDebugFlags; + /// The string to embed in as the dwarf AT_producer for the compile unit, if + /// non-empty. + StringRef DwarfDebugProducer; + /// Honor temporary labels, this is useful for debugging semantic /// differences between temporary and non-temporary labels (primarily on /// Darwin). @@ -134,14 +150,22 @@ namespace llvm { /// We need a deterministic iteration order, so we remember the order /// the elements were added. std::vector<const MCSection *> MCLineSectionOrder; + /// The Compile Unit ID that we are currently processing. + unsigned DwarfCompileUnitID; + /// The line table start symbol for each Compile Unit. + DenseMap<unsigned, MCSymbol *> MCLineTableSymbols; void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + /// Do automatic reset in destructor + bool AutoReset; + MCSymbol *CreateSymbol(StringRef Name); public: explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, - const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0); + const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0, + bool DoAutoReset = true); ~MCContext(); const SourceMgr *getSourceManager() const { return SrcMgr; } @@ -154,6 +178,15 @@ namespace llvm { void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } + /// @name Module Lifetime Management + /// @{ + + /// reset - return object to right after construction state to prepare + /// to process a new module + void reset(); + + /// @} + /// @name Symbol Management /// @{ @@ -235,21 +268,45 @@ namespace llvm { /// @name Dwarf Management /// @{ + /// \brief Get the compilation directory for DW_AT_comp_dir + /// This can be overridden by clients which want to control the reported + /// compilation directory and have it be something other than the current + /// working directory. + const std::string &getCompilationDir() const { return CompilationDir; } + + /// \brief Set the compilation directory for DW_AT_comp_dir + /// Override the default (CWD) compilation directory. + void setCompilationDir(StringRef S) { CompilationDir = S.str(); } + + /// \brief Get the main file name for use in error messages and debug + /// info. This can be set to ensure we've got the correct file name + /// after preprocessing or for -save-temps. + const std::string &getMainFileName() const { return MainFileName; } + + /// \brief Set the main file name and override the default. + void setMainFileName(StringRef S) { MainFileName = S.str(); } + /// GetDwarfFile - creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef Directory, StringRef FileName, - unsigned FileNumber); + unsigned FileNumber, unsigned CUID); - bool isValidDwarfFileNumber(unsigned FileNumber); + bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0); bool hasDwarfFiles() const { - return !MCDwarfFiles.empty(); + // Traverse MCDwarfFilesCUMap and check whether each entry is empty. + MCDwarfFilesMap::const_iterator MapB, MapE; + for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end(); + MapB != MapE; MapB++) + if (!MapB->second.empty()) + return true; + return false; } - const std::vector<MCDwarfFile *> &getMCDwarfFiles() { - return MCDwarfFiles; + const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) { + return MCDwarfFilesCUMap[CUID]; } - const std::vector<StringRef> &getMCDwarfDirs() { - return MCDwarfDirs; + const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) { + return MCDwarfDirsCUMap[CUID]; } const DenseMap<const MCSection *, MCLineSection *> @@ -263,6 +320,25 @@ namespace llvm { MCLineSections[Sec] = Line; MCLineSectionOrder.push_back(Sec); } + unsigned getDwarfCompileUnitID() { + return DwarfCompileUnitID; + } + void setDwarfCompileUnitID(unsigned CUIndex) { + DwarfCompileUnitID = CUIndex; + } + const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const { + return MCLineTableSymbols; + } + MCSymbol *getMCLineTableSymbol(unsigned ID) const { + DenseMap<unsigned, MCSymbol *>::const_iterator CIter = + MCLineTableSymbols.find(ID); + if (CIter == MCLineTableSymbols.end()) + return NULL; + return CIter->second; + } + void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) { + MCLineTableSymbols[ID] = Sym; + } /// setCurrentDwarfLoc - saves the information from the currently parsed /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction @@ -309,6 +385,9 @@ namespace llvm { void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; } StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } + void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } + StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } + /// @} char *getSecureLogFile() { return SecureLogFile; } diff --git a/contrib/llvm/include/llvm/MC/MCDisassembler.h b/contrib/llvm/include/llvm/MC/MCDisassembler.h index 53a9ce0..36fbcb0 100644 --- a/contrib/llvm/include/llvm/MC/MCDisassembler.h +++ b/contrib/llvm/include/llvm/MC/MCDisassembler.h @@ -6,11 +6,11 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef MCDISASSEMBLER_H -#define MCDISASSEMBLER_H +#ifndef LLVM_MC_MCDISASSEMBLER_H +#define LLVM_MC_MCDISASSEMBLER_H -#include "llvm/Support/DataTypes.h" #include "llvm-c/Disassembler.h" +#include "llvm/Support/DataTypes.h" namespace llvm { @@ -20,8 +20,6 @@ class MemoryObject; class raw_ostream; class MCContext; -struct EDInstInfo; - /// MCDisassembler - Superclass for all disassemblers. Consumes a memory region /// and provides an array of assembly instructions. class MCDisassembler { @@ -84,14 +82,6 @@ public: raw_ostream &vStream, raw_ostream &cStream) const = 0; - /// 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 const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } - private: // // Hooks for symbolic disassembly via the public 'C' interface. diff --git a/contrib/llvm/include/llvm/MC/MCDwarf.h b/contrib/llvm/include/llvm/MC/MCDwarf.h index 8fc437f..1a392e8 100644 --- a/contrib/llvm/include/llvm/MC/MCDwarf.h +++ b/contrib/llvm/include/llvm/MC/MCDwarf.h @@ -16,10 +16,10 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Dwarf.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/raw_ostream.h" +#include <map> #include <vector> namespace llvm { @@ -187,29 +187,43 @@ namespace llvm { MCLineSection() {} // addLineEntry - adds an entry to this MCLineSection's line entries - void addLineEntry(const MCLineEntry &LineEntry) { - MCLineEntries.push_back(LineEntry); + void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) { + MCLineDivisions[CUID].push_back(LineEntry); } typedef std::vector<MCLineEntry> MCLineEntryCollection; typedef MCLineEntryCollection::iterator iterator; typedef MCLineEntryCollection::const_iterator const_iterator; + typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap; private: - MCLineEntryCollection MCLineEntries; + // A collection of MCLineEntry for each Compile Unit ID. + MCLineDivisionMap MCLineDivisions; public: - const MCLineEntryCollection *getMCLineEntries() const { - return &MCLineEntries; + // Returns whether MCLineSection contains entries for a given Compile + // Unit ID. + bool containEntriesForID(unsigned CUID) const { + return MCLineDivisions.count(CUID); + } + // Returns the collection of MCLineEntry for a given Compile Unit ID. + const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const { + MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID); + assert(CIter != MCLineDivisions.end()); + return CIter->second; } }; class MCDwarfFileTable { public: // - // This emits the Dwarf file and the line tables. + // This emits the Dwarf file and the line tables for all Compile Units. // static const MCSymbol *Emit(MCStreamer *MCOS); + // + // This emits the Dwarf file and the line tables for a given Compile Unit. + // + static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID); }; class MCDwarfLineAddr { @@ -266,42 +280,115 @@ namespace llvm { class MCCFIInstruction { public: - enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape, - Restore}; + enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset, + OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset, + OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined, + OpRegister }; private: OpType Operation; MCSymbol *Label; - // Move to & from location. - MachineLocation Destination; - MachineLocation Source; + unsigned Register; + union { + int Offset; + unsigned Register2; + }; std::vector<char> Values; + + MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) : + Operation(Op), Label(L), Register(R), Offset(O), + Values(V.begin(), V.end()) { + assert(Op != OpRegister); + } + + MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) : + Operation(Op), Label(L), Register(R1), Register2(R2) { + assert(Op == OpRegister); + } + public: - MCCFIInstruction(OpType Op, MCSymbol *L) - : Operation(Op), Label(L) { - assert(Op == RememberState || Op == RestoreState); + static MCCFIInstruction + createOffset(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpOffset, L, Register, Offset, ""); + } + + static MCCFIInstruction + createDefCfaRegister(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); + } + + static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { + return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); + } + + static MCCFIInstruction + createDefCfa(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); + } + + static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpUndefined, L, Register, 0, ""); } - MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) - : Operation(Op), Label(L), Destination(Register) { - assert(Op == SameValue || Op == Restore); + + static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpRestore, L, Register, 0, ""); + } + + static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpSameValue, L, Register, 0, ""); + } + + static MCCFIInstruction createRestoreState(MCSymbol *L) { + return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); } - MCCFIInstruction(MCSymbol *L, const MachineLocation &D, - const MachineLocation &S) - : Operation(Move), Label(L), Destination(D), Source(S) { + + static MCCFIInstruction createRememberState(MCSymbol *L) { + return MCCFIInstruction(OpRememberState, L, 0, 0, ""); + } + + static MCCFIInstruction + createRelOffset(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); + } + + static MCCFIInstruction + createAdjustCfaOffset(MCSymbol *L, int Adjustment) { + return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); } - MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D, - const MachineLocation &S) - : Operation(Op), Label(L), Destination(D), Source(S) { - assert(Op == RelMove); + + static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { + return MCCFIInstruction(OpEscape, L, 0, 0, Vals); } - MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals) - : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) { - assert(Op == Escape); + + static MCCFIInstruction + createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) { + return MCCFIInstruction(OpRegister, L, Register1, Register2); } + OpType getOperation() const { return Operation; } MCSymbol *getLabel() const { return Label; } - const MachineLocation &getDestination() const { return Destination; } - const MachineLocation &getSource() const { return Source; } + + unsigned getRegister() const { + assert(Operation == OpDefCfa || Operation == OpOffset || + Operation == OpRestore || Operation == OpUndefined || + Operation == OpSameValue || Operation == OpDefCfaRegister || + Operation == OpRelOffset || Operation == OpRegister); + return Register; + } + + unsigned getRegister2() const { + assert(Operation == OpRegister); + return Register2; + } + + int getOffset() const { + assert(Operation == OpDefCfa || Operation == OpOffset || + Operation == OpRelOffset || Operation == OpDefCfaOffset || + Operation == OpAdjustCfaOffset); + return Offset; + } + const StringRef getValues() const { + assert(Operation == OpEscape); return StringRef(&Values[0], Values.size()); } }; diff --git a/contrib/llvm/include/llvm/MC/MCELF.h b/contrib/llvm/include/llvm/MC/MCELF.h new file mode 100644 index 0000000..7e59911 --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCELF.h @@ -0,0 +1,37 @@ +//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some support functions used by the ELF Streamer and +// ObjectWriter. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELF_H +#define LLVM_MC_MCELF_H + +#include "llvm/MC/MCExpr.h" + +namespace llvm { +class MCSymbolData; + +class MCELF { + public: + static void SetBinding(MCSymbolData &SD, unsigned Binding); + static unsigned GetBinding(const MCSymbolData &SD); + static void SetType(MCSymbolData &SD, unsigned Type); + static unsigned GetType(const MCSymbolData &SD); + static void SetVisibility(MCSymbolData &SD, unsigned Visibility); + static unsigned GetVisibility(MCSymbolData &SD); + static void setOther(MCSymbolData &SD, unsigned Other); + static unsigned getOther(MCSymbolData &SD); +}; + +} + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h index 38cdc72..a59776d 100644 --- a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -79,7 +79,6 @@ public: virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel, bool IsRelocWithSymbol, int64_t Addend) const = 0; - virtual unsigned getEFlags() const; virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, const MCValue &Target, const MCFragment &F, diff --git a/contrib/llvm/include/llvm/MC/MCELFStreamer.h b/contrib/llvm/include/llvm/MC/MCELFStreamer.h new file mode 100644 index 0000000..6fb2d22 --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCELFStreamer.h @@ -0,0 +1,125 @@ +//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELFSTREAMER_H +#define LLVM_MC_MCELFSTREAMER_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { +class MCAsmBackend; +class MCAssembler; +class MCCodeEmitter; +class MCExpr; +class MCInst; +class MCSymbol; +class MCSymbolData; +class raw_ostream; + +class MCELFStreamer : public MCObjectStreamer { +protected: + MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter) + : MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {} + +public: + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter) + : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {} + + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, MCAssembler *Assembler) + : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter, + Assembler) {} + + virtual ~MCELFStreamer(); + + /// @name MCStreamer Interface + /// @{ + + virtual void InitSections(); + virtual void InitToTextSection(); + virtual void ChangeSection(const MCSection *Section); + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(MCSymbol *Symbol); + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitThumbFunc(MCSymbol *Func); + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); + virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); + virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); + virtual void EmitCOFFSymbolStorageClass(int StorageClass); + virtual void EmitCOFFSymbolType(int Type); + virtual void EndCOFFSymbolDef(); + + virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + + virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + uint64_t Size = 0, unsigned ByteAlignment = 0); + virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + unsigned AddrSpace); + + virtual void EmitFileDirective(StringRef Filename); + + virtual void EmitTCEntry(const MCSymbol &S); + + virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); + + virtual void FinishImpl(); + /// @} + + static bool classof(const MCStreamer *S) { + return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer; + } + +private: + virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitInstToData(const MCInst &Inst); + + virtual void EmitBundleAlignMode(unsigned AlignPow2); + virtual void EmitBundleLock(bool AlignToEnd); + virtual void EmitBundleUnlock(); + + void fixSymbolsInTLSFixups(const MCExpr *expr); + + struct LocalCommon { + MCSymbolData *SD; + uint64_t Size; + unsigned ByteAlignment; + }; + + std::vector<LocalCommon> LocalCommons; + + SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; + + + void SetSection(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); + void SetSectionData(); + void SetSectionText(); + void SetSectionBss(); +}; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCExpr.h b/contrib/llvm/include/llvm/MC/MCExpr.h index 1007aa5..b5bfed1 100644 --- a/contrib/llvm/include/llvm/MC/MCExpr.h +++ b/contrib/llvm/include/llvm/MC/MCExpr.h @@ -160,6 +160,7 @@ public: VK_TLVP, // Mach-O thread local variable relocation VK_SECREL, // FIXME: We'd really like to use the generic Kinds listed above for these. + VK_ARM_NONE, VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF VK_ARM_GOT, @@ -168,15 +169,29 @@ public: VK_ARM_GOTTPOFF, VK_ARM_TARGET1, VK_ARM_TARGET2, + VK_ARM_PREL31, VK_PPC_TOC, // TOC base VK_PPC_TOC_ENTRY, // TOC entry VK_PPC_DARWIN_HA16, // ha16(symbol) VK_PPC_DARWIN_LO16, // lo16(symbol) VK_PPC_GAS_HA16, // symbol@ha - VK_PPC_GAS_LO16, // symbol@l + VK_PPC_GAS_LO16, // symbol@l VK_PPC_TPREL16_HA, // symbol@tprel@ha VK_PPC_TPREL16_LO, // symbol@tprel@l + VK_PPC_DTPREL16_HA, // symbol@dtprel@ha + VK_PPC_DTPREL16_LO, // symbol@dtprel@l + VK_PPC_TOC16_HA, // symbol@toc@ha + VK_PPC_TOC16_LO, // symbol@toc@l + VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha + VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l + VK_PPC_TLS, // symbol@tls + VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha + VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l + VK_PPC_TLSGD, // symbol@tlsgd + VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha + VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l + VK_PPC_TLSLD, // symbol@tlsld VK_Mips_GPREL, VK_Mips_GOT_CALL, @@ -457,6 +472,8 @@ public: virtual void AddValueSymbols(MCAssembler *) const = 0; virtual const MCSection *FindAssociatedSection() const = 0; + virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; + static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; } diff --git a/contrib/llvm/include/llvm/MC/MCFixedLenDisassembler.h b/contrib/llvm/include/llvm/MC/MCFixedLenDisassembler.h index 22b3c32..ad99943 100644 --- a/contrib/llvm/include/llvm/MC/MCFixedLenDisassembler.h +++ b/contrib/llvm/include/llvm/MC/MCFixedLenDisassembler.h @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// // Fixed length disassembler decoder state machine driver. //===----------------------------------------------------------------------===// -#ifndef MCFIXEDLENDISASSEMBLER_H -#define MCFIXEDLENDISASSEMBLER_H +#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H +#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H namespace llvm { diff --git a/contrib/llvm/include/llvm/MC/MCInstBuilder.h b/contrib/llvm/include/llvm/MC/MCInstBuilder.h new file mode 100644 index 0000000..c5acb26 --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCInstBuilder.h @@ -0,0 +1,68 @@ +//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the MCInstBuilder class for convenient creation of +// MCInsts. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCINSTBUILDER_H +#define LLVM_MC_MCINSTBUILDER_H + +#include "llvm/MC/MCInst.h" + +namespace llvm { + +class MCInstBuilder { + MCInst Inst; + +public: + /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode. + MCInstBuilder(unsigned Opcode) { + Inst.setOpcode(Opcode); + } + + /// \brief Add a new register operand. + MCInstBuilder &addReg(unsigned Reg) { + Inst.addOperand(MCOperand::CreateReg(Reg)); + return *this; + } + + /// \brief Add a new integer immediate operand. + MCInstBuilder &addImm(int64_t Val) { + Inst.addOperand(MCOperand::CreateImm(Val)); + return *this; + } + + /// \brief Add a new floating point immediate operand. + MCInstBuilder &addFPImm(double Val) { + Inst.addOperand(MCOperand::CreateFPImm(Val)); + return *this; + } + + /// \brief Add a new MCExpr operand. + MCInstBuilder &addExpr(const MCExpr *Val) { + Inst.addOperand(MCOperand::CreateExpr(Val)); + return *this; + } + + /// \brief Add a new MCInst operand. + MCInstBuilder &addInst(const MCInst *Val) { + Inst.addOperand(MCOperand::CreateInst(Val)); + return *this; + } + + operator MCInst&() { + return Inst; + } +}; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCInstPrinter.h b/contrib/llvm/include/llvm/MC/MCInstPrinter.h index 3b9420a..a18cbd9 100644 --- a/contrib/llvm/include/llvm/MC/MCInstPrinter.h +++ b/contrib/llvm/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,9 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Format.h" + namespace llvm { class MCInst; class raw_ostream; @@ -36,13 +39,16 @@ protected: /// True if we are printing marked up assembly. bool UseMarkup; + /// True if we are printing immediates as hex. + bool PrintImmHex; + /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), - UseMarkup(0) {} + UseMarkup(0), PrintImmHex(0) {} virtual ~MCInstPrinter(); @@ -70,6 +76,12 @@ public: /// Utility functions to make adding mark ups simpler. StringRef markup(StringRef s) const; StringRef markup(StringRef a, StringRef b) const; + + bool getPrintImmHex() const { return PrintImmHex; } + void setPrintImmHex(bool Value) { PrintImmHex = Value; } + + /// Utility function to print immediates in decimal or hex. + format_object1<int64_t> formatImm(const int64_t Value) const; }; } // namespace llvm diff --git a/contrib/llvm/include/llvm/MC/MCInstrDesc.h b/contrib/llvm/include/llvm/MC/MCInstrDesc.h index 02383f8..9b5415a 100644 --- a/contrib/llvm/include/llvm/MC/MCInstrDesc.h +++ b/contrib/llvm/include/llvm/MC/MCInstrDesc.h @@ -15,6 +15,8 @@ #ifndef LLVM_MC_MCINSTRDESC_H #define LLVM_MC_MCINSTRDESC_H +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -144,7 +146,7 @@ public: const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands - /// getOperandConstraint - Returns the value of the specific constraint if + /// \brief Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const { @@ -156,12 +158,12 @@ public: return -1; } - /// getOpcode - Return the opcode number for this descriptor. + /// \brief Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; } - /// getNumOperands - Return the number of declared MachineOperands for this + /// \brief Return the number of declared MachineOperands for this /// MachineInstruction. Note that variadic (isVariadic() returns true) /// instructions may have additional operands at the end of the list, and note /// that the machine instruction may include implicit register def/uses as @@ -170,7 +172,7 @@ public: return NumOperands; } - /// getNumDefs - Return the number of MachineOperands that are register + /// \brief Return the number of MachineOperands that are register /// definitions. Register definitions always occur at the start of the /// machine operand list. This is the number of "outs" in the .td file, /// and does not include implicit defs. @@ -178,11 +180,10 @@ public: return NumDefs; } - /// getFlags - Return flags of this instruction. - /// + /// \brief Return flags of this instruction. unsigned getFlags() const { return Flags; } - /// isVariadic - Return true if this instruction can have a variable number of + /// \brief Return true if this instruction can have a variable number of /// operands. In this case, the variable operands will be after the normal /// operands but before the implicit definitions and uses (if any are /// present). @@ -190,35 +191,37 @@ public: return Flags & (1 << MCID::Variadic); } - /// hasOptionalDef - Set if this instruction has an optional definition, e.g. + /// \brief Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. bool hasOptionalDef() const { return Flags & (1 << MCID::HasOptionalDef); } - /// isPseudo - Return true if this is a pseudo instruction that doesn't + /// \brief Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. /// bool isPseudo() const { return Flags & (1 << MCID::Pseudo); } + /// \brief Return true if the instruction is a return. bool isReturn() const { return Flags & (1 << MCID::Return); } + /// \brief Return true if the instruction is a call. bool isCall() const { return Flags & (1 << MCID::Call); } - /// isBarrier - Returns true if the specified instruction stops control flow + /// \brief Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. bool isBarrier() const { return Flags & (1 << MCID::Barrier); } - /// isTerminator - Returns true if this instruction part of the terminator for + /// \brief Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch /// instructions. /// @@ -228,7 +231,7 @@ public: return Flags & (1 << MCID::Terminator); } - /// isBranch - Returns true if this is a conditional, unconditional, or + /// \brief Returns true if this is a conditional, unconditional, or /// indirect branch. Predicates below can be used to discriminate between /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. @@ -236,13 +239,13 @@ public: return Flags & (1 << MCID::Branch); } - /// isIndirectBranch - Return true if this is an indirect branch, such as a + /// \brief Return true if this is an indirect branch, such as a /// branch through a register. bool isIndirectBranch() const { return Flags & (1 << MCID::IndirectBranch); } - /// isConditionalBranch - Return true if this is a branch which may fall + /// \brief Return true if this is a branch which may fall /// through to the next instruction or may transfer control flow to some other /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more /// information about this branch. @@ -250,7 +253,7 @@ public: return isBranch() & !isBarrier() & !isIndirectBranch(); } - /// isUnconditionalBranch - Return true if this is a branch which always + /// \brief Return true if this is a branch which always /// transfers control flow to some other block. The /// TargetInstrInfo::AnalyzeBranch method can be used to get more information /// about this branch. @@ -258,38 +261,47 @@ public: return isBranch() & isBarrier() & !isIndirectBranch(); } - // isPredicable - Return true if this instruction has a predicate operand that - // controls execution. It may be set to 'always', or may be set to other - /// values. There are various methods in TargetInstrInfo that can be used to + /// \brief Return true if this is a branch or an instruction which directly + /// writes to the program counter. Considered 'may' affect rather than + /// 'does' affect as things like predication are not taken into account. + bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { + if (isBranch() || isCall() || isReturn() || isIndirectBranch()) + return true; + unsigned PC = RI.getProgramCounter(); + if (PC == 0) return false; + return hasDefOfPhysReg(MI, PC, RI); + } + + /// \brief Return true if this instruction has a predicate operand + /// that controls execution. It may be set to 'always', or may be set to other + /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. bool isPredicable() const { return Flags & (1 << MCID::Predicable); } - /// isCompare - Return true if this instruction is a comparison. + /// \brief Return true if this instruction is a comparison. bool isCompare() const { return Flags & (1 << MCID::Compare); } - /// isMoveImmediate - Return true if this instruction is a move immediate + /// \brief Return true if this instruction is a move immediate /// (including conditional moves) instruction. bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); } - /// isBitcast - Return true if this instruction is a bitcast instruction. - /// + /// \brief Return true if this instruction is a bitcast instruction. bool isBitcast() const { return Flags & (1 << MCID::Bitcast); } - /// isSelect - Return true if this is a select instruction. - /// + /// \brief Return true if this is a select instruction. bool isSelect() const { return Flags & (1 << MCID::Select); } - /// isNotDuplicable - Return true if this instruction cannot be safely + /// \brief Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable() const { @@ -318,7 +330,7 @@ public: // Side Effect Analysis //===--------------------------------------------------------------------===// - /// mayLoad - Return true if this instruction could possibly read memory. + /// \brief Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. bool mayLoad() const { @@ -326,7 +338,7 @@ public: } - /// mayStore - Return true if this instruction could possibly modify memory. + /// \brief Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. @@ -459,8 +471,7 @@ public: return ImplicitUses; } - /// getNumImplicitUses - Return the number of implicit uses this instruction - /// has. + /// \brief Return the number of implicit uses this instruction has. unsigned getNumImplicitUses() const { if (ImplicitUses == 0) return 0; unsigned i = 0; @@ -482,8 +493,7 @@ public: return ImplicitDefs; } - /// getNumImplicitDefs - Return the number of implicit defs this instruction - /// has. + /// \brief Return the number of implicit defs this instruct has. unsigned getNumImplicitDefs() const { if (ImplicitDefs == 0) return 0; unsigned i = 0; @@ -491,7 +501,7 @@ public: return i; } - /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly + /// \brief Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { if (const uint16_t *ImpUses = ImplicitUses) @@ -500,31 +510,43 @@ public: return false; } - /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly + /// \brief Return true if this instruction implicitly /// defines the specified physical register. - bool hasImplicitDefOfPhysReg(unsigned Reg) const { + bool hasImplicitDefOfPhysReg(unsigned Reg, + const MCRegisterInfo *MRI = 0) const { if (const uint16_t *ImpDefs = ImplicitDefs) for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg) return true; + if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) + return true; return false; } - /// getSchedClass - Return the scheduling class for this instruction. The + /// \brief Return true if this instruction defines the specified physical + /// register, either explicitly or implicitly. + bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, + const MCRegisterInfo &RI) const { + for (int i = 0, e = NumDefs; i != e; ++i) + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) + return true; + return hasImplicitDefOfPhysReg(Reg, &RI); + } + + /// \brief Return the scheduling class for this instruction. The /// scheduling class is an index into the InstrItineraryData table. This /// returns zero if there is no known scheduling information for the /// instruction. - /// unsigned getSchedClass() const { return SchedClass; } - /// getSize - Return the number of bytes in the encoding of this instruction, + /// \brief Return the number of bytes in the encoding of this instruction, /// or zero if the encoding size cannot be known from the opcode. unsigned getSize() const { return Size; } - /// findFirstPredOperandIdx() - Find the index of the first operand in the + /// \brief Find the index of the first operand in the /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int findFirstPredOperandIdx() const { diff --git a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h index efaabfb..3c9a588 100644 --- a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -45,6 +45,13 @@ protected: public: virtual ~MCMachObjectTargetWriter(); + /// @name Lifetime Management + /// @{ + + virtual void reset() {}; + + /// @} + /// @name Accessors /// @{ @@ -111,6 +118,13 @@ public: : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { } + /// @name Lifetime management Methods + /// @{ + + virtual void reset(); + + /// @} + /// @name Utility Methods /// @{ @@ -182,6 +196,8 @@ public: void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize); + void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options); + // FIXME: We really need to improve the relocation validation. Basically, we // want to implement a separate computation which evaluates the relocation // entry as the linker would, and verifies that the resultant fixup value is @@ -223,8 +239,6 @@ public: /// ComputeSymbolTable - Compute the symbol table data /// /// \param StringTable [out] - The string table data. - /// \param StringIndexMap [out] - Map from symbol names to offsets in the - /// string table. void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, std::vector<MachSymbolData> &LocalSymbolData, std::vector<MachSymbolData> &ExternalSymbolData, diff --git a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h index 23e5513..c8d7484 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -84,15 +84,6 @@ protected: /// this is the section to emit them into. const MCSection *CompactUnwindSection; - /// DwarfAccelNamesSection, DwarfAccelObjCSection, - /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - - /// If we use the DWARF accelerated hash tables then we want toe emit these - /// sections. - const MCSection *DwarfAccelNamesSection; - const MCSection *DwarfAccelObjCSection; - const MCSection *DwarfAccelNamespaceSection; - const MCSection *DwarfAccelTypesSection; - // Dwarf sections for debug info. If a target supports debug info, these must // be set. const MCSection *DwarfAbbrevSection; @@ -106,6 +97,28 @@ protected: const MCSection *DwarfARangesSection; const MCSection *DwarfRangesSection; const MCSection *DwarfMacroInfoSection; + // The pubnames section is no longer generated by default. The generation + // can be enabled by a compiler flag. + const MCSection *DwarfPubNamesSection; + + // DWARF5 Experimental Debug Info Sections + /// DwarfAccelNamesSection, DwarfAccelObjCSection, + /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - + /// If we use the DWARF accelerated hash tables then we want to emit these + /// sections. + const MCSection *DwarfAccelNamesSection; + const MCSection *DwarfAccelObjCSection; + const MCSection *DwarfAccelNamespaceSection; + const MCSection *DwarfAccelTypesSection; + + /// These are used for the Fission separate debug information files. + const MCSection *DwarfInfoDWOSection; + const MCSection *DwarfAbbrevDWOSection; + const MCSection *DwarfStrDWOSection; + const MCSection *DwarfLineDWOSection; + const MCSection *DwarfLocDWOSection; + const MCSection *DwarfStrOffDWOSection; + const MCSection *DwarfAddrSection; // Extra TLS Variable Data section. If the target needs to put additional // information for a TLS variable, it'll go here. @@ -195,22 +208,11 @@ public: const MCSection *getCompactUnwindSection() const{ return CompactUnwindSection; } - const MCSection *getDwarfAccelNamesSection() const { - return DwarfAccelNamesSection; - } - const MCSection *getDwarfAccelObjCSection() const { - return DwarfAccelObjCSection; - } - const MCSection *getDwarfAccelNamespaceSection() const { - return DwarfAccelNamespaceSection; - } - const MCSection *getDwarfAccelTypesSection() const { - return DwarfAccelTypesSection; - } const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } const MCSection *getDwarfLineSection() const { return DwarfLineSection; } const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } + const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;} const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;} const MCSection *getDwarfDebugInlineSection() const { return DwarfDebugInlineSection; @@ -222,6 +224,42 @@ public: const MCSection *getDwarfMacroInfoSection() const { return DwarfMacroInfoSection; } + + // DWARF5 Experimental Debug Info Sections + const MCSection *getDwarfAccelNamesSection() const { + return DwarfAccelNamesSection; + } + const MCSection *getDwarfAccelObjCSection() const { + return DwarfAccelObjCSection; + } + const MCSection *getDwarfAccelNamespaceSection() const { + return DwarfAccelNamespaceSection; + } + const MCSection *getDwarfAccelTypesSection() const { + return DwarfAccelTypesSection; + } + const MCSection *getDwarfInfoDWOSection() const { + return DwarfInfoDWOSection; + } + const MCSection *getDwarfAbbrevDWOSection() const { + return DwarfAbbrevDWOSection; + } + const MCSection *getDwarfStrDWOSection() const { + return DwarfStrDWOSection; + } + const MCSection *getDwarfLineDWOSection() const { + return DwarfLineDWOSection; + } + const MCSection *getDwarfLocDWOSection() const { + return DwarfLocDWOSection; + } + const MCSection *getDwarfStrOffDWOSection() const { + return DwarfStrOffDWOSection; + } + const MCSection *getDwarfAddrSection() const { + return DwarfAddrSection; + } + const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } diff --git a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h index 08b00f1..f06c49f 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h @@ -38,13 +38,18 @@ class MCObjectStreamer : public MCStreamer { virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); protected: - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, + MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, + MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, MCAssembler *_Assembler); ~MCObjectStreamer(); +public: + /// state management + virtual void reset(); + +protected: MCSectionData *getCurrentSectionData() const { return CurSectionData; } @@ -64,6 +69,8 @@ public: /// @{ virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(MCSymbol *Symbol); + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace); virtual void EmitULEB128Value(const MCExpr *Value); @@ -71,8 +78,15 @@ public: virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); + + /// \brief Emit an instruction to a special fragment, because this instruction + /// can change its size during relaxation. virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitBytes(StringRef Data, unsigned AddrSpace); + + virtual void EmitBundleAlignMode(unsigned AlignPow2); + virtual void EmitBundleLock(bool AlignToEnd); + virtual void EmitBundleUnlock(); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0); virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, @@ -89,10 +103,14 @@ public: virtual void EmitGPRel32Value(const MCExpr *Value); virtual void EmitGPRel64Value(const MCExpr *Value); virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, - unsigned AddrSpace); + unsigned AddrSpace = 0); virtual void FinishImpl(); /// @} + + static bool classof(const MCStreamer *S) { + return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer; + } }; } // end namespace llvm diff --git a/contrib/llvm/include/llvm/MC/MCObjectWriter.h b/contrib/llvm/include/llvm/MC/MCObjectWriter.h index 14fe75f..4939a3f 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCObjectWriter.h @@ -10,9 +10,10 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> namespace llvm { @@ -51,6 +52,9 @@ protected: // Can only create subclasses. public: virtual ~MCObjectWriter(); + /// lifetime management + virtual void reset() { } + bool isLittleEndian() const { return IsLittleEndian; } raw_ostream &getStream() { return OS; } @@ -58,15 +62,15 @@ public: /// @name High-Level API /// @{ - /// Perform any late binding of symbols (for example, to assign symbol indices - /// for use when generating relocations). + /// \brief Perform any late binding of symbols (for example, to assign symbol + /// indices for use when generating relocations). /// /// This routine is called by the assembler after layout and relaxation is /// complete. virtual void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; - /// Record a relocation entry. + /// \brief Record a relocation entry. /// /// This routine is called by the assembler after layout and relaxation, and /// post layout binding. The implementation is responsible for storing @@ -96,8 +100,7 @@ public: bool InSet, bool IsPCRel) const; - - /// Write the object file. + /// \brief Write the object file. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations @@ -173,7 +176,13 @@ public: OS << StringRef(Zeros, N % 16); } + void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { + WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + } + void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + // TODO: this version may need to go away once all fragment contents are + // converted to SmallVector<char, N> assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && "data size greater than fill size, unexpected large write will occur"); OS << Str; diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h index 92a115e..a918b56 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h +++ b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ASMCOND_H -#define ASMCOND_H +#ifndef LLVM_MC_MCPARSER_ASMCOND_H +#define LLVM_MC_MCPARSER_ASMCOND_H namespace llvm { diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h index e102dfb..0dab314 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h +++ b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ASMLEXER_H -#define ASMLEXER_H +#ifndef LLVM_MC_MCPARSER_ASMLEXER_H +#define LLVM_MC_MCPARSER_ASMLEXER_H #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/MCAsmLexer.h" diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h index 0a961d6..53b380f 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMLEXER_H -#define LLVM_MC_MCASMLEXER_H +#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H +#define LLVM_MC_MCPARSER_MCASMLEXER_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" @@ -34,9 +34,6 @@ public: // Real values. Real, - // Register values (stored in IntVal). Only used by MCTargetAsmLexer. - Register, - // No-value. EndOfStatement, Colon, @@ -104,13 +101,6 @@ public: assert(Kind == Integer && "This token isn't an integer!"); return IntVal; } - - /// getRegVal - Get the register number for the current token, which should - /// be a register. - unsigned getRegVal() const { - assert(Kind == Register && "This token isn't a register!"); - return static_cast<unsigned>(IntVal); - } }; /// MCAsmLexer - Generic assembler lexer interface, for use by target specific diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h index a71d3c3..d7e3902 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h +++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h @@ -7,14 +7,15 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMPARSER_H -#define LLVM_MC_MCASMPARSER_H +#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H +#define LLVM_MC_MCPARSER_MCASMPARSER_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/AsmLexer.h" +#include "llvm/Support/DataTypes.h" namespace llvm { -class AsmToken; class MCAsmInfo; class MCAsmLexer; class MCAsmParserExtension; @@ -22,13 +23,11 @@ class MCContext; class MCExpr; class MCInstPrinter; class MCInstrInfo; -class MCParsedAsmOperand; class MCStreamer; class MCTargetAsmParser; class SMLoc; class SMRange; class SourceMgr; -class StringRef; class Twine; /// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. @@ -36,16 +35,21 @@ class MCAsmParserSemaCallback { public: virtual ~MCAsmParserSemaCallback(); virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc, - unsigned &Size) = 0; + unsigned &Length, unsigned &Size, + unsigned &Type, bool &IsVarDecl) = 0; + virtual bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset) = 0; }; + /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { public: typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc); + typedef std::pair<MCAsmParserExtension*, DirectiveHandler> + ExtensionDirectiveHandler; private: MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION; @@ -61,9 +65,8 @@ protected: // Can only create subclasses. public: virtual ~MCAsmParser(); - virtual void AddDirectiveHandler(MCAsmParserExtension *Object, - StringRef Directive, - DirectiveHandler Handler) = 0; + virtual void addDirectiveHandler(StringRef Directive, + ExtensionDirectiveHandler Handler) = 0; virtual SourceMgr &getSourceManager() = 0; @@ -89,8 +92,8 @@ public: virtual void setParsingInlineAsm(bool V) = 0; virtual bool isParsingInlineAsm() = 0; - /// ParseMSInlineAsm - Parse ms-style inline assembly. - virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, + /// parseMSInlineAsm - Parse ms-style inline assembly. + virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool> > &OpDecls, SmallVectorImpl<std::string> &Constraints, @@ -123,42 +126,50 @@ public: bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); - /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) + /// parseIdentifier - Parse an identifier or string (as a quoted identifier) /// and set \p Res to the identifier contents. - virtual bool ParseIdentifier(StringRef &Res) = 0; + virtual bool parseIdentifier(StringRef &Res) = 0; /// \brief Parse up to the end of statement and return the contents from the /// current token until the end of the statement; the current token on exit /// will be either the EndOfStatement or EOF. - virtual StringRef ParseStringToEndOfStatement() = 0; + virtual StringRef parseStringToEndOfStatement() = 0; + + /// parseEscapedString - Parse the current token as a string which may include + /// escaped characters and return the string contents. + virtual bool parseEscapedString(std::string &Data) = 0; - /// EatToEndOfStatement - Skip to the end of the current statement, for error + /// eatToEndOfStatement - Skip to the end of the current statement, for error /// recovery. - virtual void EatToEndOfStatement() = 0; + virtual void eatToEndOfStatement() = 0; - /// ParseExpression - Parse an arbitrary expression. + /// parseExpression - Parse an arbitrary expression. /// /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; - bool ParseExpression(const MCExpr *&Res); + virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; + bool parseExpression(const MCExpr *&Res); - /// ParseParenExpression - Parse an arbitrary expression, assuming that an + /// parseParenExpression - Parse an arbitrary expression, assuming that an /// initial '(' has already been consumed. /// /// @param Res - The value of the expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; + virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; - /// ParseAbsoluteExpression - Parse an expression which must evaluate to an + /// parseAbsoluteExpression - Parse an expression which must evaluate to an /// absolute value. /// /// @param Res - The value of the absolute expression. The result is undefined /// on error. /// @result - False on success. - virtual bool ParseAbsoluteExpression(int64_t &Res) = 0; + virtual bool parseAbsoluteExpression(int64_t &Res) = 0; + + /// checkForValidSection - Ensure that we have a valid section set in the + /// streamer. Otherwise, report an error and switch to .text. + virtual void checkForValidSection() = 0; }; /// \brief Create an MCAsmParser instance. diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h index 0918c93..2eda3a9 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMPARSEREXTENSION_H -#define LLVM_MC_MCASMPARSEREXTENSION_H +#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H +#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H -#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/Support/SMLoc.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 60e7887..4650bf2 100644 --- a/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMOPERAND_H -#define LLVM_MC_MCASMOPERAND_H +#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H +#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H namespace llvm { class SMLoc; @@ -57,18 +57,15 @@ public: /// isMem - Is this a memory operand? virtual bool isMem() const = 0; - virtual unsigned getMemSize() const { return 0; } /// getStartLoc - Get the location of the first token of this operand. virtual SMLoc getStartLoc() const = 0; /// getEndLoc - Get the location of the last token of this operand. virtual SMLoc getEndLoc() const = 0; - /// needAsmRewrite - AsmRewrites happen in both the target-independent and - /// target-dependent parsers. The target-independent parser calls this - /// function to determine if the target-dependent parser has already taken - /// care of the rewrites. Only valid when parsing MS-style inline assembly. - virtual bool needAsmRewrite() const { return true; } + /// needAddressOf - Do we need to emit code to get the address of the + /// variable/label? Only valid when parsing MS-style inline assembly. + virtual bool needAddressOf() const { return false; } /// isOffsetOf - Do we need to emit code to get the offset of the variable, /// rather then the value of the variable? Only valid when parsing MS-style @@ -78,10 +75,6 @@ public: /// getOffsetOfLoc - Get the location of the offset operator. virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } - /// needSizeDirective - Do we need to emit a sizing directive for this - /// operand? Only valid when parsing MS-style inline assembly. - virtual bool needSizeDirective() const { return false; } - /// print - Print a debug representation of the operand to the given stream. virtual void print(raw_ostream &OS) const = 0; /// dump - Print to the debug stream. diff --git a/contrib/llvm/include/llvm/MC/MCRegisterInfo.h b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h index f05baea..f5b4ddd 100644 --- a/contrib/llvm/include/llvm/MC/MCRegisterInfo.h +++ b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h @@ -22,11 +22,15 @@ namespace llvm { +/// An unsigned integer type large enough to represent all physical registers, +/// but not necessarily virtual registers. +typedef uint16_t MCPhysReg; + /// MCRegisterClass - Base class of TargetRegisterClass. class MCRegisterClass { public: - typedef const uint16_t* iterator; - typedef const uint16_t* const_iterator; + typedef const MCPhysReg* iterator; + typedef const MCPhysReg* const_iterator; const char *Name; const iterator RegsBegin; @@ -148,11 +152,12 @@ private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array unsigned RAReg; // Return address register + unsigned PCReg; // Program counter register const MCRegisterClass *Classes; // Pointer to the regclass array unsigned NumClasses; // Number of entries in the array unsigned NumRegUnits; // Number of regunits. const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table. - const uint16_t *DiffLists; // Pointer to the difflists array + const MCPhysReg *DiffLists; // Pointer to the difflists array const char *RegStrings; // Pointer to the string table. const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. @@ -177,7 +182,7 @@ public: /// defined below. class DiffListIterator { uint16_t Val; - const uint16_t *List; + const MCPhysReg *List; protected: /// Create an invalid iterator. Call init() to point to something useful. @@ -186,7 +191,7 @@ public: /// init - Point the iterator to InitVal, decoding subsequent values from /// DiffList. The iterator will initially point to InitVal, sub-classes are /// responsible for skipping the seed value if it is not part of the list. - void init(uint16_t InitVal, const uint16_t *DiffList) { + void init(MCPhysReg InitVal, const MCPhysReg *DiffList) { Val = InitVal; List = DiffList; } @@ -196,7 +201,7 @@ public: /// is the caller's responsibility (by checking for a 0 return value). unsigned advance() { assert(isValid() && "Cannot move off the end of the list."); - uint16_t D = *List++; + MCPhysReg D = *List++; Val += D; return D; } @@ -225,13 +230,14 @@ public: friend class MCRegUnitIterator; friend class MCRegUnitRootIterator; - /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen + /// \brief Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, + unsigned PC, const MCRegisterClass *C, unsigned NC, const uint16_t (*RURoots)[2], unsigned NRU, - const uint16_t *DL, + const MCPhysReg *DL, const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, @@ -239,6 +245,7 @@ public: Desc = D; NumRegs = NR; RAReg = RA; + PCReg = PC; Classes = C; DiffLists = DL; RegStrings = Strings; @@ -250,7 +257,7 @@ public: RegEncodingTable = RET; } - /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf + /// \brief Used to initialize LLVM register to Dwarf /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -264,7 +271,7 @@ public: } } - /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM + /// \brief Used to initialize Dwarf register to LLVM /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -287,77 +294,80 @@ public: L2SEHRegs[LLVMReg] = SEHReg; } - /// getRARegister - This method should return the register where the return + /// \brief This method should return the register where the return /// address can be found. unsigned getRARegister() const { return RAReg; } + /// Return the register which is the program counter. + unsigned getProgramCounter() const { + return PCReg; + } + const MCRegisterDesc &operator[](unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to access record for invalid register number!"); return Desc[RegNo]; } - /// Provide a get method, equivalent to [], but more useful if we have a + /// \brief Provide a get method, equivalent to [], but more useful with a /// pointer to this object. - /// const MCRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } - /// getSubReg - Returns the physical register number of sub-register "Index" + /// \brief Returns the physical register number of sub-register "Index" /// for physical register RegNo. Return zero if the sub-register does not /// exist. unsigned getSubReg(unsigned Reg, unsigned Idx) const; - /// getMatchingSuperReg - Return a super-register of the specified register + /// \brief Return a super-register of the specified register /// Reg so its sub-register of index SubIdx is Reg. unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const; - /// getSubRegIndex - For a given register pair, return the sub-register index + /// \brief For a given register pair, return the sub-register index /// if the second register is a sub-register of the first. Return zero /// otherwise. unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; - /// getName - Return the human-readable symbolic target-specific name for the + /// \brief Return the human-readable symbolic target-specific name for the /// specified physical register. const char *getName(unsigned RegNo) const { return RegStrings + get(RegNo).Name; } - /// getNumRegs - Return the number of registers this target has (useful for + /// \brief Return the number of registers this target has (useful for /// sizing arrays holding per register information) unsigned getNumRegs() const { return NumRegs; } - /// getNumSubRegIndices - Return the number of sub-register indices + /// \brief Return the number of sub-register indices /// understood by the target. Index 0 is reserved for the no-op sub-register, /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. unsigned getNumSubRegIndices() const { return NumSubRegIndices; } - /// getNumRegUnits - Return the number of (native) register units in the + /// \brief Return the number of (native) register units in the /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They /// can be accessed through MCRegUnitIterator defined below. unsigned getNumRegUnits() const { return NumRegUnits; } - /// getDwarfRegNum - Map a target register to an equivalent dwarf register + /// \brief Map a target register to an equivalent dwarf register /// number. Returns -1 if there is no equivalent value. The second /// parameter allows targets to use different numberings for EH info and /// debugging info. int getDwarfRegNum(unsigned RegNum, bool isEH) const; - /// getLLVMRegNum - Map a dwarf register back to a target register. - /// + /// \brief Map a dwarf register back to a target register. int getLLVMRegNum(unsigned RegNum, bool isEH) const; - /// getSEHRegNum - Map a target register to an equivalent SEH register + /// \brief Map a target register to an equivalent SEH register /// number. Returns LLVM register number if there is no equivalent value. int getSEHRegNum(unsigned RegNum) const; @@ -368,20 +378,39 @@ public: return (unsigned)(regclass_end()-regclass_begin()); } - /// getRegClass - Returns the register class associated with the enumeration + /// \brief Returns the register class associated with the enumeration /// value. See class MCOperandInfo. const MCRegisterClass& getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); return Classes[i]; } - /// getEncodingValue - Returns the encoding for RegNo + /// \brief Returns the encoding for RegNo uint16_t getEncodingValue(unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to get encoding for invalid register number!"); return RegEncodingTable[RegNo]; } + /// \brief Returns true if RegB is a sub-register of RegA. + bool isSubRegister(unsigned RegA, unsigned RegB) const { + return isSuperRegister(RegB, RegA); + } + + /// \brief Returns true if RegB is a super-register of RegA. + bool isSuperRegister(unsigned RegA, unsigned RegB) const; + + /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA. + bool isSubRegisterEq(unsigned RegA, unsigned RegB) const { + return isSuperRegisterEq(RegB, RegA); + } + + /// \brief Returns true if RegB is a super-register of RegA or if + /// RegB == RegA. + bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const { + return RegA == RegB || isSuperRegister(RegA, RegB); + } + }; //===----------------------------------------------------------------------===// @@ -422,6 +451,15 @@ public: } }; +// Definition for isSuperRegister. Put it down here since it needs the +// iterator defined above in addition to the MCRegisterInfo class itself. +inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{ + for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) + if (*I == RegB) + return true; + return false; +} + //===----------------------------------------------------------------------===// // Register Units //===----------------------------------------------------------------------===// @@ -441,6 +479,7 @@ public: /// MCRegUnitIterator - Create an iterator that traverses the register units /// in Reg. MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { + assert(Reg && "Null register has no regunits"); // Decode the RegUnits MCRegisterDesc field. unsigned RU = MCRI->get(Reg).RegUnits; unsigned Scale = RU & 15; @@ -480,17 +519,17 @@ public: Reg1 = MCRI->RegUnitRoots[RegUnit][1]; } - /// Dereference to get the current root register. + /// \brief Dereference to get the current root register. unsigned operator*() const { return Reg0; } - /// isValid - Check if the iterator is at the end of the list. + /// \brief Check if the iterator is at the end of the list. bool isValid() const { return Reg0; } - /// Preincrement to move to the next root register. + /// \brief Preincrement to move to the next root register. void operator++() { assert(isValid() && "Cannot move off the end of the list."); Reg0 = Reg1; diff --git a/contrib/llvm/include/llvm/MC/MCSchedule.h b/contrib/llvm/include/llvm/MC/MCSchedule.h index 0c71ee5..defa299 100644 --- a/contrib/llvm/include/llvm/MC/MCSchedule.h +++ b/contrib/llvm/include/llvm/MC/MCSchedule.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCSCHEDMODEL_H -#define LLVM_MC_MCSCHEDMODEL_H +#ifndef LLVM_MC_MCSCHEDULE_H +#define LLVM_MC_MCSCHEDULE_H #include "llvm/Support/DataTypes.h" #include <cassert> @@ -155,7 +155,7 @@ public: // Optional InstrItinerary OperandCycles provides expected latency. // TODO: can't yet specify both min and expected latency per operand. int MinLatency; - static const unsigned DefaultMinLatency = -1; + static const int DefaultMinLatency = -1; // LoadLatency is the expected latency of load instructions. // @@ -172,6 +172,16 @@ public: unsigned HighLatency; static const unsigned DefaultHighLatency = 10; + // ILPWindow is the number of cycles that the scheduler effectively ignores + // before attempting to hide latency. This should be zero for in-order cpus to + // always hide expected latency. For out-of-order cpus, it may be tweaked as + // desired to roughly approximate instruction buffers. The actual threshold is + // not very important for an OOO processor, as long as it isn't too high. A + // nonzero value helps avoid rescheduling to hide latency when its is fairly + // obviously useless and makes register pressure heuristics more effective. + unsigned ILPWindow; + static const unsigned DefaultILPWindow = 0; + // MispredictPenalty is the typical number of extra cycles the processor // takes to recover from a branch misprediction. unsigned MispredictPenalty; @@ -196,6 +206,7 @@ public: MinLatency(DefaultMinLatency), LoadLatency(DefaultLoadLatency), HighLatency(DefaultHighLatency), + ILPWindow(DefaultILPWindow), MispredictPenalty(DefaultMispredictPenalty), ProcID(0), ProcResourceTable(0), SchedClassTable(0), NumProcResourceKinds(0), NumSchedClasses(0), @@ -205,12 +216,12 @@ public: } // Table-gen driven ctor. - MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, - unsigned pi, const MCProcResourceDesc *pr, + MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp, + unsigned mp, unsigned pi, const MCProcResourceDesc *pr, const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, const InstrItinerary *ii): IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), - MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), + ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), InstrItineraries(ii) {} diff --git a/contrib/llvm/include/llvm/MC/MCSection.h b/contrib/llvm/include/llvm/MC/MCSection.h index 21fdb6b..e575424 100644 --- a/contrib/llvm/include/llvm/MC/MCSection.h +++ b/contrib/llvm/include/llvm/MC/MCSection.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSECTION_H #define LLVM_MC_MCSECTION_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Compiler.h" @@ -49,6 +50,11 @@ namespace llvm { virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const = 0; + // Convenience routines to get label names for the beginning/end of a + // section. + virtual std::string getLabelBeginName() const = 0; + virtual std::string getLabelEndName() const = 0; + /// isBaseAddressKnownZero - Return true if we know that this section will /// get a base address of zero. In cases where we know that this is true we /// can emit section offsets as direct references to avoid a subtraction diff --git a/contrib/llvm/include/llvm/MC/MCSectionCOFF.h b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h index b050c0f..07c4714 100644 --- a/contrib/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h @@ -14,9 +14,9 @@ #ifndef LLVM_MC_MCSECTIONCOFF_H #define LLVM_MC_MCSECTIONCOFF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/COFF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { @@ -50,6 +50,12 @@ namespace llvm { bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } + virtual std::string getLabelBeginName() const { + return SectionName.str() + "_begin"; + } + virtual std::string getLabelEndName() const { + return SectionName.str() + "_end"; + } unsigned getCharacteristics() const { return Characteristics; } int getSelection () const { return Selection; } diff --git a/contrib/llvm/include/llvm/MC/MCSectionELF.h b/contrib/llvm/include/llvm/MC/MCSectionELF.h index 4d54465..4b8b849 100644 --- a/contrib/llvm/include/llvm/MC/MCSectionELF.h +++ b/contrib/llvm/include/llvm/MC/MCSectionELF.h @@ -14,9 +14,11 @@ #ifndef LLVM_MC_MCSECTIONELF_H #define LLVM_MC_MCSECTIONELF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -57,6 +59,11 @@ public: bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } + virtual std::string getLabelBeginName() const { + return SectionName.str() + "_begin"; } + virtual std::string getLabelEndName() const { + return SectionName.str() + "_end"; + } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } diff --git a/contrib/llvm/include/llvm/MC/MCSectionMachO.h b/contrib/llvm/include/llvm/MC/MCSectionMachO.h index 71ea8f3..898f571 100644 --- a/contrib/llvm/include/llvm/MC/MCSectionMachO.h +++ b/contrib/llvm/include/llvm/MC/MCSectionMachO.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSECTIONMACHO_H #define LLVM_MC_MCSECTIONMACHO_H -#include "llvm/MC/MCSection.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCSection.h" namespace llvm { @@ -145,6 +145,14 @@ public: return StringRef(SectionName); } + virtual std::string getLabelBeginName() const { + return StringRef(getSegmentName().str() + getSectionName().str() + "_begin"); + } + + virtual std::string getLabelEndName() const { + return StringRef(getSegmentName().str() + getSectionName().str() + "_end"); + } + unsigned getTypeAndAttributes() const { return TypeAndAttributes; } unsigned getStubSize() const { return Reserved2; } diff --git a/contrib/llvm/include/llvm/MC/MCStreamer.h b/contrib/llvm/include/llvm/MC/MCStreamer.h index 230d27e..a069a2b 100644 --- a/contrib/llvm/include/llvm/MC/MCStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCStreamer.h @@ -14,12 +14,14 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" +#include <string> namespace llvm { class MCAsmBackend; @@ -45,6 +47,23 @@ namespace llvm { /// a .s file, and implementations that write out .o files of various formats. /// class MCStreamer { + public: + enum StreamerKind { + SK_AsmStreamer, + SK_NullStreamer, + SK_RecordStreamer, + + // MCObjectStreamer subclasses. + SK_ELFStreamer, + SK_ARMELFStreamer, + SK_MachOStreamer, + SK_PureStreamer, + SK_MipsELFStreamer, + SK_WinCOFFStreamer + }; + + private: + const StreamerKind Kind; MCContext &Context; MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; @@ -55,6 +74,7 @@ namespace llvm { std::vector<MCDwarfFrameInfo> FrameInfos; MCDwarfFrameInfo *getCurrentFrameInfo(); + MCSymbol *EmitCFICommon(); void EnsureValidFrame(); std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; @@ -69,8 +89,10 @@ namespace llvm { SmallVector<std::pair<const MCSection *, const MCSection *>, 4> SectionStack; + bool AutoInitSections; + protected: - MCStreamer(MCContext &Ctx); + MCStreamer(StreamerKind Kind, MCContext &Ctx); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, const MCSymbol *B); @@ -89,6 +111,12 @@ namespace llvm { public: virtual ~MCStreamer(); + StreamerKind getKind() const { return Kind; } + + /// State management + /// + virtual void reset(); + MCContext &getContext() const { return Context; } unsigned getNumFrameInfos() { @@ -213,9 +241,23 @@ namespace llvm { SectionStack.back().first = Section; } + /// Initialize the streamer. + void InitStreamer() { + if (AutoInitSections) + InitSections(); + } + + /// Tell this MCStreamer to call InitSections upon initialization. + void setAutoInitSections(bool AutoInitSections) { + this->AutoInitSections = AutoInitSections; + } + /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; + /// InitToTextSection - Create a text section and switch the streamer to it. + virtual void InitToTextSection() = 0; + /// EmitLabel - Emit a label for @p Symbol into the current section. /// /// This corresponds to an assembler statement such as: @@ -226,12 +268,18 @@ namespace llvm { /// used in an assignment. virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(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; + /// EmitLinkerOptions - Emit the given list @p Options of strings as linker + /// options into the output. + virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {} + /// EmitDataRegion - Note in the output the specified region @p Kind. virtual void EmitDataRegion(MCDataRegionType Kind) {} @@ -239,6 +287,9 @@ namespace llvm { /// a Thumb mode function (ARM target only). virtual void EmitThumbFunc(MCSymbol *Func) = 0; + /// getOrCreateSymbolData - Get symbol data for given symbol. + virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// /// This corresponds to an assembler statement such as: @@ -346,7 +397,7 @@ namespace llvm { /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. - virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; + virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0; /// EmitValue - Emit the expression @p Value into the output as a native /// integer of the given @p Size bytes. @@ -380,8 +431,8 @@ namespace llvm { /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. - void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0, - unsigned Padding = 0); + void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0, + unsigned AddrSpace = 0); /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. @@ -409,15 +460,14 @@ namespace llvm { /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, - unsigned AddrSpace); + unsigned AddrSpace = 0); /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience /// function that just wraps EmitFill. - void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) { + void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) { EmitFill(NumBytes, 0, AddrSpace); } - /// EmitValueToAlignment - Emit some number of copies of @p Value until /// the byte alignment @p ByteAlignment is reached. /// @@ -475,7 +525,7 @@ namespace llvm { /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename); + StringRef Filename, unsigned CUID = 0); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. @@ -515,6 +565,8 @@ namespace llvm { virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFIEscape(StringRef Values); virtual void EmitCFISignalFrame(); + virtual void EmitCFIUndefined(int64_t Register); + virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -535,6 +587,20 @@ namespace llvm { /// section. virtual void EmitInstruction(const MCInst &Inst) = 0; + /// \brief Set the bundle alignment mode from now on in the section. + /// The argument is the power of 2 to which the alignment is set. The + /// value 0 means turn the bundle alignment off. + virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0; + + /// \brief The following instructions are a bundle-locked group. + /// + /// \param AlignToEnd - If true, the bundle-locked group will be aligned to + /// the end of a bundle. + virtual void EmitBundleLock(bool AlignToEnd) = 0; + + /// \brief Ends a bundle-locked group. + virtual void EmitBundleUnlock() = 0; + /// EmitRawText - If this file is backed by a assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. By default this aborts. diff --git a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h index 69213cd..346fb2d 100644 --- a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSUBTARGET_H #define LLVM_MC_MCSUBTARGET_H -#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/SubtargetFeature.h" #include <string> namespace llvm { diff --git a/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h b/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h deleted file mode 100644 index b1cc546..0000000 --- a/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h +++ /dev/null @@ -1,89 +0,0 @@ -//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCTARGETASMLEXER_H -#define LLVM_MC_MCTARGETASMLEXER_H - -#include "llvm/MC/MCParser/MCAsmLexer.h" - -namespace llvm { -class Target; - -/// MCTargetAsmLexer - Generic interface to target specific assembly lexers. -class MCTargetAsmLexer { - /// The current token - AsmToken CurTok; - - /// The location and description of the current error - SMLoc ErrLoc; - std::string Err; - - MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; - void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; -protected: // Can only create subclasses. - MCTargetAsmLexer(const Target &); - - virtual AsmToken LexToken() = 0; - - void SetError(const SMLoc &errLoc, const std::string &err) { - ErrLoc = errLoc; - Err = err; - } - - /// TheTarget - The Target that this machine was created for. - const Target &TheTarget; - MCAsmLexer *Lexer; - -public: - virtual ~MCTargetAsmLexer(); - - const Target &getTarget() const { return TheTarget; } - - /// InstallLexer - Set the lexer to get tokens from lower-level lexer \p L. - void InstallLexer(MCAsmLexer &L) { - Lexer = &L; - } - - MCAsmLexer *getLexer() { - return Lexer; - } - - /// Lex - Consume the next token from the input stream and return it. - const AsmToken &Lex() { - return CurTok = LexToken(); - } - - /// getTok - Get the current (last) lexed token. - const AsmToken &getTok() { - return CurTok; - } - - /// getErrLoc - Get the current error location - const SMLoc &getErrLoc() { - return ErrLoc; - } - - /// getErr - Get the current error string - const std::string &getErr() { - return Err; - } - - /// getKind - Get the kind of current token. - AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - - /// is - Check if the current token has kind \p K. - bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - - /// isNot - Check if the current token has kind \p K. - bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h b/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h index 483a80b..4c5b176 100644 --- a/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h +++ b/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h @@ -22,6 +22,7 @@ class MCInst; template <typename T> class SmallVectorImpl; enum AsmRewriteKind { + AOK_Align, // Rewrite align as .align. AOK_DotOperator, // Rewrite a dot operator expression as an immediate. // E.g., [eax].foo.bar -> [eax].8 AOK_Emit, // Rewrite _emit as .byte. @@ -142,6 +143,15 @@ public: MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm) = 0; + /// Allow a target to add special case operand matching for things that + /// tblgen doesn't/can't handle effectively. For example, literal + /// immediates on ARM. TableGen expects a token operand, but the parser + /// will recognize them as immediates. + virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, + unsigned Kind) { + return Match_InvalidOperand; + } + /// checkTargetMatchPredicate - Validate the instruction match against /// any complex target predicates not expressible via match classes. virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { diff --git a/contrib/llvm/include/llvm/MC/MCValue.h b/contrib/llvm/include/llvm/MC/MCValue.h index f9af8bc..a4e7301 100644 --- a/contrib/llvm/include/llvm/MC/MCValue.h +++ b/contrib/llvm/include/llvm/MC/MCValue.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCVALUE_H #define LLVM_MC_MCVALUE_H -#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { diff --git a/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h index 7a0b1ff..11df574 100644 --- a/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -11,6 +11,9 @@ #define LLVM_MC_MCWINCOFFOBJECTWRITER_H namespace llvm { + class MCObjectWriter; + class raw_ostream; + class MCWinCOFFObjectTargetWriter { const unsigned Machine; diff --git a/contrib/llvm/include/llvm/MC/SubtargetFeature.h b/contrib/llvm/include/llvm/MC/SubtargetFeature.h index 57f0518..37ae03b 100644 --- a/contrib/llvm/include/llvm/MC/SubtargetFeature.h +++ b/contrib/llvm/include/llvm/MC/SubtargetFeature.h @@ -18,9 +18,9 @@ #ifndef LLVM_MC_SUBTARGETFEATURE_H #define LLVM_MC_SUBTARGETFEATURE_H -#include <vector> #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" +#include <vector> namespace llvm { class raw_ostream; diff --git a/contrib/llvm/include/llvm/MDBuilder.h b/contrib/llvm/include/llvm/MDBuilder.h deleted file mode 100644 index 1867a63..0000000 --- a/contrib/llvm/include/llvm/MDBuilder.h +++ /dev/null @@ -1,162 +0,0 @@ -//===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the MDBuilder class, which is used as a convenient way to -// create LLVM metadata with a consistent and simplified interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MDBUILDER_H -#define LLVM_MDBUILDER_H - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include "llvm/Metadata.h" -#include "llvm/ADT/APInt.h" - -namespace llvm { - - class MDBuilder { - LLVMContext &Context; - - public: - MDBuilder(LLVMContext &context) : Context(context) {} - - /// \brief Return the given string as metadata. - MDString *createString(StringRef Str) { - return MDString::get(Context, Str); - } - - //===------------------------------------------------------------------===// - // FPMath metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata with the given settings. The special value 0.0 - /// for the Accuracy parameter indicates the default (maximal precision) - /// setting. - MDNode *createFPMath(float Accuracy) { - if (Accuracy == 0.0) - return 0; - assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); - Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); - return MDNode::get(Context, Op); - } - - //===------------------------------------------------------------------===// - // Prof metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata containing two branch weights. - MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) { - uint32_t Weights[] = { TrueWeight, FalseWeight }; - return createBranchWeights(Weights); - } - - /// \brief Return metadata containing a number of branch weights. - MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { - assert(Weights.size() >= 2 && "Need at least two branch weights!"); - - SmallVector<Value *, 4> Vals(Weights.size()+1); - Vals[0] = createString("branch_weights"); - - Type *Int32Ty = Type::getInt32Ty(Context); - for (unsigned i = 0, e = Weights.size(); i != e; ++i) - Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); - - return MDNode::get(Context, Vals); - } - - //===------------------------------------------------------------------===// - // Range metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata describing the range [Lo, Hi). - MDNode *createRange(const APInt &Lo, const APInt &Hi) { - assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); - // If the range is everything then it is useless. - if (Hi == Lo) - return 0; - - // Return the range [Lo, Hi). - Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); - Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; - return MDNode::get(Context, Range); - } - - - //===------------------------------------------------------------------===// - // TBAA metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata appropriate for a TBAA root node. Each returned - /// node is distinct from all other metadata and will never be identified - /// (uniqued) with anything else. - MDNode *createAnonymousTBAARoot() { - // To ensure uniqueness the root node is self-referential. - MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); - MDNode *Root = MDNode::get(Context, Dummy); - // At this point we have - // !0 = metadata !{} <- dummy - // !1 = metadata !{metadata !0} <- root - // Replace the dummy operand with the root node itself and delete the dummy. - Root->replaceOperandWith(0, Root); - MDNode::deleteTemporary(Dummy); - // We now have - // !1 = metadata !{metadata !1} <- self-referential root - return Root; - } - - /// \brief Return metadata appropriate for a TBAA root node with the given - /// name. This may be identified (uniqued) with other roots with the same - /// name. - MDNode *createTBAARoot(StringRef Name) { - return MDNode::get(Context, createString(Name)); - } - - /// \brief Return metadata for a non-root TBAA node with the given name, - /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. - MDNode *createTBAANode(StringRef Name, MDNode *Parent, - bool isConstant = false) { - if (isConstant) { - Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); - Value *Ops[3] = { createString(Name), Parent, Flags }; - return MDNode::get(Context, Ops); - } else { - Value *Ops[2] = { createString(Name), Parent }; - return MDNode::get(Context, Ops); - } - } - - struct TBAAStructField { - uint64_t Offset; - uint64_t Size; - MDNode *TBAA; - TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : - Offset(Offset), Size(Size), TBAA(TBAA) {} - }; - - /// \brief Return metadata for a tbaa.struct node with the given - /// struct field descriptions. - MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { - SmallVector<Value *, 4> Vals(Fields.size() * 3); - Type *Int64 = IntegerType::get(Context, 64); - for (unsigned i = 0, e = Fields.size(); i != e; ++i) { - Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); - Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); - Vals[i * 3 + 2] = Fields[i].TBAA; - } - return MDNode::get(Context, Vals); - } - - }; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/Object/Archive.h b/contrib/llvm/include/llvm/Object/Archive.h index f3d8249..e2478f6 100644 --- a/contrib/llvm/include/llvm/Object/Archive.h +++ b/contrib/llvm/include/llvm/Object/Archive.h @@ -14,22 +14,78 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H -#include "llvm/Object/Binary.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" namespace llvm { namespace object { +struct ArchiveMemberHeader { + char Name[16]; + char LastModified[12]; + char UID[6]; + char GID[6]; + char AccessMode[8]; + char Size[10]; ///< Size of data, not including header or padding. + char Terminator[2]; + + ///! Get the name without looking up long names. + llvm::StringRef getName() const { + char EndCond; + if (Name[0] == '/' || Name[0] == '#') + EndCond = ' '; + else + EndCond = '/'; + llvm::StringRef::size_type end = + llvm::StringRef(Name, sizeof(Name)).find(EndCond); + if (end == llvm::StringRef::npos) + end = sizeof(Name); + assert(end <= sizeof(Name) && end > 0); + // Don't include the EndCond if there is one. + return llvm::StringRef(Name, end); + } + + uint64_t getSize() const { + uint64_t ret; + if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret)) + llvm_unreachable("Size is not an integer."); + return ret; + } +}; + +static const ArchiveMemberHeader *ToHeader(const char *base) { + return reinterpret_cast<const ArchiveMemberHeader *>(base); +} class Archive : public Binary { virtual void anchor(); public: class Child { const Archive *Parent; + /// \brief Includes header but not padding byte. StringRef Data; + /// \brief Offset from Data to the start of the file. + uint16_t StartOfFile; public: - Child(const Archive *p, StringRef d) : Parent(p), Data(d) {} + Child(const Archive *p, StringRef d) : Parent(p), Data(d) { + if (!p || d.empty()) + return; + // Setup StartOfFile and PaddingBytes. + StartOfFile = sizeof(ArchiveMemberHeader); + // Don't include attached name. + StringRef Name = ToHeader(Data.data())->getName(); + if (Name.startswith("#1/")) { + uint64_t NameSize; + if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize)) + llvm_unreachable("Long name length is not an integer"); + StartOfFile += NameSize; + } + } bool operator ==(const Child &other) const { return (Parent == other.Parent) && (Data.begin() == other.Data.begin()); @@ -39,16 +95,48 @@ public: return Data.begin() < other.Data.begin(); } - Child getNext() const; + Child getNext() const { + size_t SpaceToSkip = Data.size(); + // If it's odd, add 1 to make it even. + if (SpaceToSkip & 1) + ++SpaceToSkip; + + const char *NextLoc = Data.data() + SpaceToSkip; + + // Check to see if this is past the end of the archive. + if (NextLoc >= Parent->Data->getBufferEnd()) + return Child(Parent, StringRef(0, 0)); + + size_t NextSize = + sizeof(ArchiveMemberHeader) + ToHeader(NextLoc)->getSize(); + + return Child(Parent, StringRef(NextLoc, NextSize)); + } + error_code getName(StringRef &Result) const; int getLastModified() const; int getUID() const; int getGID() const; int getAccessMode() const; - ///! Return the size of the archive member without the header or padding. - uint64_t getSize() const; + /// \return the size of the archive member without the header or padding. + uint64_t getSize() const { return Data.size() - StartOfFile; } + + StringRef getBuffer() const { + return StringRef(Data.data() + StartOfFile, getSize()); + } + + error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result, + bool FullPath = false) const { + StringRef Name; + if (error_code ec = getName(Name)) + return ec; + SmallString<128> Path; + Result.reset(MemoryBuffer::getMemBuffer( + getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name + + ")").toStringRef(Path) : Name, false)); + return error_code::success(); + } - MemoryBuffer *getBuffer() const; error_code getAsBinary(OwningPtr<Binary> &Result) const; }; @@ -122,6 +210,16 @@ public: Archive(MemoryBuffer *source, error_code &ec); + enum Kind { + K_GNU, + K_BSD, + K_COFF + }; + + Kind kind() const { + return Format; + } + child_iterator begin_children(bool skip_internal = true) const; child_iterator end_children() const; @@ -133,9 +231,13 @@ public: return v->isArchive(); } + // check if a symbol is in the archive + child_iterator findSym(StringRef name) const; + private: child_iterator SymbolTable; child_iterator StringTable; + Kind Format; }; } diff --git a/contrib/llvm/include/llvm/Object/Binary.h b/contrib/llvm/include/llvm/Object/Binary.h index d555de3..8bbcd8b 100644 --- a/contrib/llvm/include/llvm/Object/Binary.h +++ b/contrib/llvm/include/llvm/Object/Binary.h @@ -49,8 +49,8 @@ protected: ID_EndObjects }; - static inline unsigned int getELFType(bool isLittleEndian, bool is64Bits) { - if (isLittleEndian) + static inline unsigned int getELFType(bool isLE, bool is64Bits) { + if (isLE) return is64Bits ? ID_ELF64L : ID_ELF32L; else return is64Bits ? ID_ELF64B : ID_ELF32B; @@ -85,6 +85,10 @@ public: bool isCOFF() const { return TypeID == ID_COFF; } + + bool isLittleEndian() const { + return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B); + } }; /// @brief Create a Binary from Source, autodetecting the file type. diff --git a/contrib/llvm/include/llvm/Object/ELF.h b/contrib/llvm/include/llvm/Object/ELF.h index 466de93..8ea5e46 100644 --- a/contrib/llvm/include/llvm/Object/ELF.h +++ b/contrib/llvm/include/llvm/Object/ELF.h @@ -14,11 +14,11 @@ #ifndef LLVM_OBJECT_ELF_H #define LLVM_OBJECT_ELF_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerIntPair.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" @@ -33,6 +33,21 @@ namespace llvm { namespace object { +using support::endianness; + +template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +struct ELFType { + static const endianness TargetEndianness = target_endianness; + static const std::size_t MaxAlignment = max_alignment; + static const bool Is64Bits = is64Bits; +}; + +template<typename T, int max_align> +struct MaximumAlignment { + enum {value = AlignOf<T>::Alignment > max_align ? max_align + : AlignOf<T>::Alignment}; +}; + // Subclasses of ELFObjectFile may need this for template instantiation inline std::pair<unsigned char, unsigned char> getElfArchType(MemoryBuffer *Object) { @@ -43,69 +58,78 @@ getElfArchType(MemoryBuffer *Object) { } // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. -template<support::endianness target_endianness> +template<endianness target_endianness, std::size_t max_alignment> struct ELFDataTypeTypedefHelperCommon { typedef support::detail::packed_endian_specific_integral - <uint16_t, target_endianness, support::aligned> Elf_Half; + <uint16_t, target_endianness, + MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; typedef support::detail::packed_endian_specific_integral - <uint32_t, target_endianness, support::aligned> Elf_Word; + <uint32_t, target_endianness, + MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; typedef support::detail::packed_endian_specific_integral - <int32_t, target_endianness, support::aligned> Elf_Sword; + <int32_t, target_endianness, + MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; typedef support::detail::packed_endian_specific_integral - <uint64_t, target_endianness, support::aligned> Elf_Xword; + <uint64_t, target_endianness, + MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; typedef support::detail::packed_endian_specific_integral - <int64_t, target_endianness, support::aligned> Elf_Sxword; + <int64_t, target_endianness, + MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template<support::endianness target_endianness> -struct ELFDataTypeTypedefHelper<target_endianness, false> - : ELFDataTypeTypedefHelperCommon<target_endianness> { +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> > + : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, support::aligned> Elf_Addr; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, support::aligned> Elf_Off; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; }; /// ELF 64bit types. -template<support::endianness target_endianness> -struct ELFDataTypeTypedefHelper<target_endianness, true> - : ELFDataTypeTypedefHelperCommon<target_endianness>{ +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> > + : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, support::aligned> Elf_Addr; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, support::aligned> Elf_Off; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \ -typedef typename \ - ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword; +#define LLVM_ELF_IMPORT_TYPES(ELFT) \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Addr Elf_Addr; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Off Elf_Off; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Half Elf_Half; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Word Elf_Word; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sword Elf_Sword; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Xword Elf_Xword; \ +typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sxword Elf_Sxword; + +// This is required to get template types into a macro :( +#define LLVM_ELF_COMMA , // Section header. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Shdr_Base; -template<support::endianness target_endianness> -struct Elf_Shdr_Base<target_endianness, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, false> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -118,9 +142,11 @@ struct Elf_Shdr_Base<target_endianness, false> { Elf_Word sh_entsize; // Size of records contained within the section }; -template<support::endianness target_endianness> -struct Elf_Shdr_Base<target_endianness, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, true> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -133,10 +159,10 @@ struct Elf_Shdr_Base<target_endianness, true> { Elf_Xword sh_entsize; // Size of records contained within the section }; -template<support::endianness target_endianness, bool is64Bits> -struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { - using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize; - using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size; +template<class ELFT> +struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { + using Elf_Shdr_Base<ELFT>::sh_entsize; + using Elf_Shdr_Base<ELFT>::sh_size; /// @brief Get the number of entities this section contains if it has any. unsigned getEntityCount() const { @@ -146,12 +172,14 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { } }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Sym_Base; -template<support::endianness target_endianness> -struct Elf_Sym_Base<target_endianness, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, false> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -160,9 +188,11 @@ struct Elf_Sym_Base<target_endianness, false> { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template<support::endianness target_endianness> -struct Elf_Sym_Base<target_endianness, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, true> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -171,9 +201,9 @@ struct Elf_Sym_Base<target_endianness, true> { Elf_Xword st_size; // Size of the symbol }; -template<support::endianness target_endianness, bool is64Bits> -struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { - using Elf_Sym_Base<target_endianness, is64Bits>::st_info; +template<class ELFT> +struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { + using Elf_Sym_Base<ELFT>::st_info; // These accessors and mutators correspond to the ELF32_ST_BIND, // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: @@ -188,21 +218,21 @@ struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section /// (.gnu.version). This structure is identical for ELF32 and ELF64. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Versym_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT) Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Verdaux_Impl; /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section /// (.gnu.version_d). This structure is identical for ELF32 and ELF64. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Verdef_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) - typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; + LLVM_ELF_IMPORT_TYPES(ELFT) + typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) Elf_Half vd_ndx; // Version index, used in .gnu.version entries @@ -219,18 +249,18 @@ struct Elf_Verdef_Impl { /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Verdaux_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT) Elf_Word vda_name; // Version name (offset in string table) Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) }; /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Verneed_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT) Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) Elf_Half vn_cnt; // Number of associated Vernaux entries Elf_Word vn_file; // Library name (string table offset) @@ -240,9 +270,9 @@ struct Elf_Verneed_Impl { /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Vernaux_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT) Elf_Word vna_hash; // Hash of dependency name Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) Elf_Half vna_other; // Version index, used in .gnu.version entries @@ -252,12 +282,14 @@ struct Elf_Vernaux_Impl { /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic /// table section (.dynamic) look like. -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Dyn_Base; -template<support::endianness target_endianness> -struct Elf_Dyn_Base<target_endianness, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, false> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Sword d_tag; union { Elf_Word d_val; @@ -265,9 +297,11 @@ struct Elf_Dyn_Base<target_endianness, false> { } d_un; }; -template<support::endianness target_endianness> -struct Elf_Dyn_Base<target_endianness, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, true> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -276,120 +310,154 @@ struct Elf_Dyn_Base<target_endianness, true> { }; /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters. -template<support::endianness target_endianness, bool is64Bits> -struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> { - using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag; - using Elf_Dyn_Base<target_endianness, is64Bits>::d_un; +template<class ELFT> +struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { + using Elf_Dyn_Base<ELFT>::d_tag; + using Elf_Dyn_Base<ELFT>::d_un; int64_t getTag() const { return d_tag; } uint64_t getVal() const { return d_un.d_val; } uint64_t getPtr() const { return d_un.ptr; } }; -template<support::endianness target_endianness, bool is64Bits> -class ELFObjectFile; - -// DynRefImpl: Reference to an entry in the dynamic table -// This is an ELF-specific interface. -template<support::endianness target_endianness, bool is64Bits> -class DynRefImpl { - typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; - typedef ELFObjectFile<target_endianness, is64Bits> OwningType; - - DataRefImpl DynPimpl; - const OwningType *OwningObject; - -public: - DynRefImpl() : OwningObject(NULL) { } - - DynRefImpl(DataRefImpl DynP, const OwningType *Owner); - - bool operator==(const DynRefImpl &Other) const; - bool operator <(const DynRefImpl &Other) const; - - error_code getNext(DynRefImpl &Result) const; - int64_t getTag() const; - uint64_t getVal() const; - uint64_t getPtr() const; - - DataRefImpl getRawDataRefImpl() const; -}; - // Elf_Rel: Elf Relocation -template<support::endianness target_endianness, bool is64Bits, bool isRela> +template<class ELFT, bool isRela> struct Elf_Rel_Base; -template<support::endianness target_endianness> -struct Elf_Rel_Base<target_endianness, false, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, false> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply + + uint32_t getRInfo(bool isMips64EL) const { + assert(!isMips64EL); + return r_info; + } + void setRInfo(uint32_t R) { + r_info = R; + } }; -template<support::endianness target_endianness> -struct Elf_Rel_Base<target_endianness, true, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, false> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply + + uint64_t getRInfo(bool isMips64EL) const { + uint64_t t = r_info; + if (!isMips64EL) + return t; + // Mip64 little endian has a "special" encoding of r_info. Instead of one + // 64 bit little endian number, it is a little ending 32 bit number followed + // by a 32 bit big endian number. + return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | + ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); + return r_info; + } + void setRInfo(uint64_t R) { + // FIXME: Add mips64el support. + r_info = R; + } }; -template<support::endianness target_endianness> -struct Elf_Rel_Base<target_endianness, false, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, true> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this + + uint32_t getRInfo(bool isMips64EL) const { + assert(!isMips64EL); + return r_info; + } + void setRInfo(uint32_t R) { + r_info = R; + } }; -template<support::endianness target_endianness> -struct Elf_Rel_Base<target_endianness, true, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, true> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply Elf_Sxword r_addend; // Compute value for relocatable field by adding this. + + uint64_t getRInfo(bool isMips64EL) const { + // Mip64 little endian has a "special" encoding of r_info. Instead of one + // 64 bit little endian number, it is a little ending 32 bit number followed + // by a 32 bit big endian number. + uint64_t t = r_info; + if (!isMips64EL) + return t; + return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | + ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); + } + void setRInfo(uint64_t R) { + // FIXME: Add mips64el support. + r_info = R; + } }; -template<support::endianness target_endianness, bool is64Bits, bool isRela> +template<class ELFT, bool isRela> struct Elf_Rel_Impl; -template<support::endianness target_endianness, bool isRela> -struct Elf_Rel_Impl<target_endianness, true, isRela> - : Elf_Rel_Base<target_endianness, true, isRela> { - using Elf_Rel_Base<target_endianness, true, isRela>::r_info; - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign, bool isRela> +struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, true>, isRela> + : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: - uint64_t getSymbol() const { return (r_info >> 32); } - unsigned char getType() const { - return (unsigned char) (r_info & 0xffffffffL); + uint32_t getSymbol(bool isMips64EL) const { + return (uint32_t) (this->getRInfo(isMips64EL) >> 32); } - void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); } - void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } - void setSymbolAndType(uint64_t s, unsigned char t) { - r_info = (s << 32) + (t&0xffffffffL); + uint32_t getType(bool isMips64EL) const { + return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL); + } + void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } + void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); } + void setSymbolAndType(uint32_t s, uint32_t t) { + this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL)); } }; -template<support::endianness target_endianness, bool isRela> -struct Elf_Rel_Impl<target_endianness, false, isRela> - : Elf_Rel_Base<target_endianness, false, isRela> { - using Elf_Rel_Base<target_endianness, false, isRela>::r_info; - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign, bool isRela> +struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, false>, isRela> + : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela> { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, // and ELF32_R_INFO macros defined in the ELF specification: - uint32_t getSymbol() const { return (r_info >> 8); } - unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); } + uint32_t getSymbol(bool isMips64EL) const { + return this->getRInfo(isMips64EL) >> 8; + } + unsigned char getType(bool isMips64EL) const { + return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff); + } void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } void setSymbolAndType(uint32_t s, unsigned char t) { - r_info = (s << 8) + t; + this->setRInfo((s << 8) + t); } }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> struct Elf_Ehdr_Impl { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT) unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes Elf_Half e_type; // Type of file (see ET_*) Elf_Half e_machine; // Required architecture for this file (see EM_*) @@ -412,15 +480,17 @@ struct Elf_Ehdr_Impl { unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } }; -template<support::endianness target_endianness, bool is64Bits> -struct Elf_Phdr; +template<class ELFT> +struct Elf_Phdr_Impl; -template<support::endianness target_endianness> -struct Elf_Phdr<target_endianness, false> { - LLVM_ELF_IMPORT_TYPES(target_endianness, false) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, false> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA false>) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes - Elf_Addr p_vaddr; // Virtual Address of beginning of segment + Elf_Addr p_vaddr; // Virtual Address of beginning of segment Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) @@ -428,121 +498,140 @@ struct Elf_Phdr<target_endianness, false> { Elf_Word p_align; // Segment alignment constraint }; -template<support::endianness target_endianness> -struct Elf_Phdr<target_endianness, true> { - LLVM_ELF_IMPORT_TYPES(target_endianness, true) +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, true> > { + LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA + MaxAlign LLVM_ELF_COMMA true>) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes - Elf_Addr p_vaddr; // Virtual Address of beginning of segment + Elf_Addr p_vaddr; // Virtual Address of beginning of segment Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) - Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) - Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) - Elf_Word p_align; // Segment alignment constraint + Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero) + Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero) + Elf_Xword p_align; // Segment alignment constraint }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> class ELFObjectFile : public ObjectFile { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) - - typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr; - typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; - typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; - typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; - typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; - typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; - typedef Elf_Verdef_Impl<target_endianness, is64Bits> Elf_Verdef; - typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; - typedef Elf_Verneed_Impl<target_endianness, is64Bits> Elf_Verneed; - typedef Elf_Vernaux_Impl<target_endianness, is64Bits> Elf_Vernaux; - typedef Elf_Versym_Impl<target_endianness, is64Bits> Elf_Versym; - typedef DynRefImpl<target_endianness, is64Bits> DynRef; - typedef content_iterator<DynRef> dyn_iterator; - -protected: - // This flag is used for classof, to distinguish ELFObjectFile from - // its subclass. If more subclasses will be created, this flag will - // have to become an enum. - bool isDyldELFObject; - -private: - typedef SmallVector<const Elf_Shdr*, 1> Sections_t; - typedef DenseMap<unsigned, unsigned> IndexMap_t; - typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; - - const Elf_Ehdr *Header; - const Elf_Shdr *SectionHeaderTable; - const Elf_Shdr *dot_shstrtab_sec; // Section header string table. - const Elf_Shdr *dot_strtab_sec; // Symbol header string table. - const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. - - // SymbolTableSections[0] always points to the dynamic string table section - // header, or NULL if there is no dynamic string table. - Sections_t SymbolTableSections; - IndexMap_t SymbolTableSectionsIndexMap; - DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; - - const Elf_Shdr *dot_dynamic_sec; // .dynamic - const Elf_Shdr *dot_gnu_version_sec; // .gnu.version - const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r - const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d - - // Pointer to SONAME entry in dynamic string table - // This is set the first time getLoadName is called. - mutable const char *dt_soname; + LLVM_ELF_IMPORT_TYPES(ELFT) public: - /// \brief Iterate over relocations in a .rel or .rela section. - template<class RelocT> - class ELFRelocationIterator { + /// \brief Iterate over constant sized entities. + template<class EntT> + class ELFEntityIterator { public: - typedef void difference_type; - typedef const RelocT value_type; - typedef std::forward_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef EntT value_type; + typedef std::random_access_iterator_tag iterator_category; typedef value_type &reference; typedef value_type *pointer; /// \brief Default construct iterator. - ELFRelocationIterator() : Section(0), Current(0) {} - ELFRelocationIterator(const Elf_Shdr *Sec, const char *Start) - : Section(Sec) + ELFEntityIterator() : EntitySize(0), Current(0) {} + ELFEntityIterator(uint64_t EntSize, const char *Start) + : EntitySize(EntSize) , Current(Start) {} reference operator *() { assert(Current && "Attempted to dereference an invalid iterator!"); - return *reinterpret_cast<const RelocT*>(Current); + return *reinterpret_cast<pointer>(Current); } pointer operator ->() { assert(Current && "Attempted to dereference an invalid iterator!"); - return reinterpret_cast<const RelocT*>(Current); + return reinterpret_cast<pointer>(Current); } - bool operator ==(const ELFRelocationIterator &Other) { - return Section == Other.Section && Current == Other.Current; + bool operator ==(const ELFEntityIterator &Other) { + return Current == Other.Current; } - bool operator !=(const ELFRelocationIterator &Other) { + bool operator !=(const ELFEntityIterator &Other) { return !(*this == Other); } - ELFRelocationIterator &operator ++(int) { + ELFEntityIterator &operator ++() { assert(Current && "Attempted to increment an invalid iterator!"); - Current += Section->sh_entsize; + Current += EntitySize; return *this; } - ELFRelocationIterator operator ++() { - ELFRelocationIterator Tmp = *this; + ELFEntityIterator operator ++(int) { + ELFEntityIterator Tmp = *this; ++*this; return Tmp; } + ELFEntityIterator &operator =(const ELFEntityIterator &Other) { + EntitySize = Other.EntitySize; + Current = Other.Current; + return *this; + } + + difference_type operator -(const ELFEntityIterator &Other) const { + assert(EntitySize == Other.EntitySize && + "Subtracting iterators of different EntitiySize!"); + return (Current - Other.Current) / EntitySize; + } + + const char *get() const { return Current; } + private: - const Elf_Shdr *Section; + uint64_t EntitySize; const char *Current; }; + typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; + typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; + typedef Elf_Sym_Impl<ELFT> Elf_Sym; + typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; + typedef Elf_Phdr_Impl<ELFT> Elf_Phdr; + typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; + typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; + typedef Elf_Verdef_Impl<ELFT> Elf_Verdef; + typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; + typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; + typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; + typedef Elf_Versym_Impl<ELFT> Elf_Versym; + typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_iterator; + typedef ELFEntityIterator<const Elf_Sym> Elf_Sym_iterator; + typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; + typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; + +protected: + // This flag is used for classof, to distinguish ELFObjectFile from + // its subclass. If more subclasses will be created, this flag will + // have to become an enum. + bool isDyldELFObject; + +private: + typedef SmallVector<const Elf_Shdr *, 2> Sections_t; + typedef DenseMap<unsigned, unsigned> IndexMap_t; + typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; + + const Elf_Ehdr *Header; + const Elf_Shdr *SectionHeaderTable; + const Elf_Shdr *dot_shstrtab_sec; // Section header string table. + const Elf_Shdr *dot_strtab_sec; // Symbol header string table. + const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. + + // SymbolTableSections[0] always points to the dynamic string table section + // header, or NULL if there is no dynamic string table. + Sections_t SymbolTableSections; + IndexMap_t SymbolTableSectionsIndexMap; + DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; + + const Elf_Shdr *dot_dynamic_sec; // .dynamic + const Elf_Shdr *dot_gnu_version_sec; // .gnu.version + const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r + const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d + + // Pointer to SONAME entry in dynamic string table + // This is set the first time getLoadName is called. + mutable const char *dt_soname; + private: // Records for each version index the corresponding Verdef or Vernaux entry. // This is filled the first time LoadVersionMap() is called. @@ -579,6 +668,7 @@ private: return getSection(Rel.w.b); } +public: bool isRelocationHasAddend(DataRefImpl Rel) const; template<typename T> const T *getEntry(uint16_t Section, uint32_t Entry) const; @@ -609,6 +699,7 @@ public: const Elf_Dyn *getDyn(DataRefImpl DynData) const; error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, bool &IsDefault) const; + uint64_t getSymbolIndex(const Elf_Sym *sym) const; protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; @@ -622,9 +713,6 @@ protected: section_iterator &Res) const; virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; - friend class DynRefImpl<target_endianness, is64Bits>; - virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const; - virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; @@ -666,6 +754,13 @@ protected: public: ELFObjectFile(MemoryBuffer *Object, error_code &ec); + + bool isMips64EL() const { + return Header->e_machine == ELF::EM_MIPS && + Header->getFileClass() == ELF::ELFCLASS64 && + Header->getDataEncoding() == ELF::ELFDATA2LSB; + } + virtual symbol_iterator begin_symbols() const; virtual symbol_iterator end_symbols() const; @@ -678,30 +773,70 @@ public: virtual library_iterator begin_libraries_needed() const; virtual library_iterator end_libraries_needed() const; - virtual dyn_iterator begin_dynamic_table() const; - virtual dyn_iterator end_dynamic_table() const; + const Elf_Shdr *getDynamicSymbolTableSectionHeader() const { + return SymbolTableSections[0]; + } + + const Elf_Shdr *getDynamicStringTableSectionHeader() const { + return dot_dynstr_sec; + } + + Elf_Dyn_iterator begin_dynamic_table() const; + /// \param NULLEnd use one past the first DT_NULL entry as the end instead of + /// the section size. + Elf_Dyn_iterator end_dynamic_table(bool NULLEnd = false) const; + + Elf_Sym_iterator begin_elf_dynamic_symbols() const { + const Elf_Shdr *DynSymtab = SymbolTableSections[0]; + if (DynSymtab) + return Elf_Sym_iterator(DynSymtab->sh_entsize, + (const char *)base() + DynSymtab->sh_offset); + return Elf_Sym_iterator(0, 0); + } - typedef ELFRelocationIterator<Elf_Rela> Elf_Rela_Iter; - typedef ELFRelocationIterator<Elf_Rel> Elf_Rel_Iter; + Elf_Sym_iterator end_elf_dynamic_symbols() const { + const Elf_Shdr *DynSymtab = SymbolTableSections[0]; + if (DynSymtab) + return Elf_Sym_iterator(DynSymtab->sh_entsize, (const char *)base() + + DynSymtab->sh_offset + DynSymtab->sh_size); + return Elf_Sym_iterator(0, 0); + } - virtual Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { - return Elf_Rela_Iter(sec, (const char *)(base() + sec->sh_offset)); + Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { + return Elf_Rela_Iter(sec->sh_entsize, + (const char *)(base() + sec->sh_offset)); } - virtual Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { - return Elf_Rela_Iter(sec, (const char *) + Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { + return Elf_Rela_Iter(sec->sh_entsize, (const char *) (base() + sec->sh_offset + sec->sh_size)); } - virtual Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec, (const char *)(base() + sec->sh_offset)); + Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { + return Elf_Rel_Iter(sec->sh_entsize, + (const char *)(base() + sec->sh_offset)); } - virtual Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec, (const char *) + Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { + return Elf_Rel_Iter(sec->sh_entsize, (const char *) (base() + sec->sh_offset + sec->sh_size)); } + /// \brief Iterate over program header table. + typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter; + + Elf_Phdr_Iter begin_program_headers() const { + return Elf_Phdr_Iter(Header->e_phentsize, + (const char*)base() + Header->e_phoff); + } + + Elf_Phdr_Iter end_program_headers() const { + return Elf_Phdr_Iter(Header->e_phentsize, + (const char*)base() + + Header->e_phoff + + (Header->e_phnum * Header->e_phentsize)); + } + virtual uint8_t getBytesInAddress() const; virtual StringRef getFileFormatName() const; virtual StringRef getObjectType() const { return "ELF"; } @@ -713,6 +848,7 @@ public: uint64_t getNumSections() const; uint64_t getStringTableIndex() const; ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; + const Elf_Ehdr *getElfHeader() const; const Elf_Shdr *getSection(const Elf_Sym *symb) const; const Elf_Shdr *getElfSection(section_iterator &It) const; const Elf_Sym *getElfSymbol(symbol_iterator &It) const; @@ -721,16 +857,15 @@ public: // Methods for type inquiry through isa, cast, and dyn_cast bool isDyldType() const { return isDyldELFObject; } static inline bool classof(const Binary *v) { - return v->getType() == getELFType(target_endianness == support::little, - is64Bits); + return v->getType() == getELFType(ELFT::TargetEndianness == support::little, + ELFT::Is64Bits); } }; // Iterate through the version definitions, and place each Elf_Verdef // in the VersionMap according to its index. -template<support::endianness target_endianness, bool is64Bits> -void ELFObjectFile<target_endianness, is64Bits>:: - LoadVersionDefs(const Elf_Shdr *sec) const { +template<class ELFT> +void ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const { unsigned vd_size = sec->sh_size; // Size of section in bytes unsigned vd_count = sec->sh_info; // Number of Verdef entries const char *sec_start = (const char*)base() + sec->sh_offset; @@ -754,9 +889,8 @@ void ELFObjectFile<target_endianness, is64Bits>:: // Iterate through the versions needed section, and place each Elf_Vernaux // in the VersionMap according to its index. -template<support::endianness target_endianness, bool is64Bits> -void ELFObjectFile<target_endianness, is64Bits>:: - LoadVersionNeeds(const Elf_Shdr *sec) const { +template<class ELFT> +void ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { unsigned vn_size = sec->sh_size; // Size of section in bytes unsigned vn_count = sec->sh_info; // Number of Verneed entries const char *sec_start = (const char*)base() + sec->sh_offset; @@ -787,8 +921,8 @@ void ELFObjectFile<target_endianness, is64Bits>:: } } -template<support::endianness target_endianness, bool is64Bits> -void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const { +template<class ELFT> +void ELFObjectFile<ELFT>::LoadVersionMap() const { // If there is no dynamic symtab or version table, there is nothing to do. if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) return; @@ -809,9 +943,9 @@ void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const { LoadVersionNeeds(dot_gnu_version_r_sec); } -template<support::endianness target_endianness, bool is64Bits> -void ELFObjectFile<target_endianness, is64Bits> - ::validateSymbol(DataRefImpl Symb) const { +template<class ELFT> +void ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const { +#ifndef NDEBUG const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; // FIXME: We really need to do proper error handling in the case of an invalid @@ -826,12 +960,12 @@ void ELFObjectFile<target_endianness, is64Bits> + SymbolTableSection->sh_size))) // FIXME: Proper error handling. report_fatal_error("Symb must point to a valid symbol!"); +#endif } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolNext(DataRefImpl Symb, - SymbolRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, + SymbolRef &Result) const { validateSymbol(Symb); const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; @@ -856,20 +990,18 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolName(DataRefImpl Symb, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, + StringRef &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolVersion(SymbolRef SymRef, - StringRef &Version, - bool &IsDefault) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, + StringRef &Version, + bool &IsDefault) const { DataRefImpl Symb = SymRef.getRawDataRefImpl(); validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -877,18 +1009,17 @@ error_code ELFObjectFile<target_endianness, is64Bits> Version, IsDefault); } -template<support::endianness target_endianness, bool is64Bits> -ELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits> - ::getSymbolTableIndex(const Elf_Sym *symb) const { +template<class ELFT> +ELF::Elf64_Word ELFObjectFile<ELFT> + ::getSymbolTableIndex(const Elf_Sym *symb) const { if (symb->st_shndx == ELF::SHN_XINDEX) return ExtendedSymbolTable.lookup(symb); return symb->st_shndx; } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * -ELFObjectFile<target_endianness, is64Bits> - ::getSection(const Elf_Sym *symb) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Shdr * +ELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const { if (symb->st_shndx == ELF::SHN_XINDEX) return getSection(ExtendedSymbolTable.lookup(symb)); if (symb->st_shndx >= ELF::SHN_LORESERVE) @@ -896,35 +1027,37 @@ ELFObjectFile<target_endianness, is64Bits> return getSection(symb->st_shndx); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * -ELFObjectFile<target_endianness, is64Bits> - ::getElfSection(section_iterator &It) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Ehdr * +ELFObjectFile<ELFT>::getElfHeader() const { + return Header; +} + +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Shdr * +ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const { llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl(); return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * -ELFObjectFile<target_endianness, is64Bits> - ::getElfSymbol(symbol_iterator &It) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Sym * +ELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const { return getSymbol(It->getRawDataRefImpl()); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * -ELFObjectFile<target_endianness, is64Bits> - ::getElfSymbol(uint32_t index) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Sym * +ELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const { DataRefImpl SymbolData; SymbolData.d.a = index; SymbolData.d.b = 1; return getSymbol(SymbolData); } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolFileOffset(DataRefImpl Symb, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, + uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *Section; @@ -942,7 +1075,7 @@ error_code ELFObjectFile<target_endianness, is64Bits> switch (symb->getType()) { case ELF::STT_SECTION: - Result = Section ? Section->sh_addr : UnknownAddressOrSize; + Result = Section ? Section->sh_offset : UnknownAddressOrSize; return object_error::success; case ELF::STT_FUNC: case ELF::STT_OBJECT: @@ -956,10 +1089,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> } } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *Section; @@ -991,6 +1123,11 @@ error_code ELFObjectFile<target_endianness, is64Bits> IsRelocatable = true; } Result = symb->st_value; + + // Clear the ARM/Thumb indicator flag. + if (Header->e_machine == ELF::EM_ARM) + Result &= ~1; + if (IsRelocatable && Section != 0) Result += Section->sh_addr; return object_error::success; @@ -1000,10 +1137,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> } } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, + uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); if (symb->st_size == 0) @@ -1012,10 +1148,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolNMTypeChar(DataRefImpl Symb, - char &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb, + char &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *Section = getSection(symb); @@ -1077,10 +1212,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -1109,10 +1243,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolFlags(DataRefImpl Symb, - uint32_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, + uint32_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); @@ -1144,10 +1277,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *sec = getSection(symb); @@ -1161,19 +1293,18 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, + uint64_t &Val) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); Val = symb->st_value; return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, + SectionRef &Result) const { const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); sec += Header->e_shentsize; Sec.p = reinterpret_cast<intptr_t>(sec); @@ -1181,65 +1312,58 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionName(DataRefImpl Sec, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, + StringRef &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionAddress(DataRefImpl Sec, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, + uint64_t &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); Result = sec->sh_addr; return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionSize(DataRefImpl Sec, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, + uint64_t &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); Result = sec->sh_size; return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionContents(DataRefImpl Sec, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, + StringRef &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); const char *start = (const char*)base() + sec->sh_offset; Result = StringRef(start, sec->sh_size); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionContents(const Elf_Shdr *Sec, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionContents(const Elf_Shdr *Sec, + StringRef &Result) const { const char *start = (const char*)base() + Sec->sh_offset; Result = StringRef(start, Sec->sh_size); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionAlignment(DataRefImpl Sec, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, + uint64_t &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); Result = sec->sh_addralign; return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionText(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_flags & ELF::SHF_EXECINSTR) Result = true; @@ -1248,10 +1372,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionData(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && sec->sh_type == ELF::SHT_PROGBITS) @@ -1261,10 +1384,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionBSS(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && sec->sh_type == ELF::SHT_NOBITS) @@ -1274,10 +1396,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionRequiredForExecution(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionRequiredForExecution( + DataRefImpl Sec, bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_flags & ELF::SHF_ALLOC) Result = true; @@ -1286,10 +1407,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_type == ELF::SHT_NOBITS) Result = true; @@ -1298,24 +1418,19 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionZeroInit(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); // For ELF, all zero-init sections are virtual (that is, they occupy no space // in the object image) and vice versa. - if (sec->sh_flags & ELF::SHT_NOBITS) - Result = true; - else - Result = false; + Result = sec->sh_type == ELF::SHT_NOBITS; return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, + bool &Result) const { const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR) Result = false; @@ -1324,19 +1439,26 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { - // FIXME: Unimplemented. - Result = false; +template<class ELFT> +error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + validateSymbol(Symb); + + const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); + const Elf_Sym *symb = getSymbol(Symb); + + unsigned shndx = symb->st_shndx; + bool Reserved = shndx >= ELF::SHN_LORESERVE + && shndx <= ELF::SHN_HIRESERVE; + + Result = !Reserved && (sec == getSection(symb->st_shndx)); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -relocation_iterator ELFObjectFile<target_endianness, is64Bits> - ::getSectionRelBegin(DataRefImpl Sec) const { +template<class ELFT> +relocation_iterator +ELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const { DataRefImpl RelData; const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); @@ -1348,9 +1470,9 @@ relocation_iterator ELFObjectFile<target_endianness, is64Bits> return relocation_iterator(RelocationRef(RelData, this)); } -template<support::endianness target_endianness, bool is64Bits> -relocation_iterator ELFObjectFile<target_endianness, is64Bits> - ::getSectionRelEnd(DataRefImpl Sec) const { +template<class ELFT> +relocation_iterator +ELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const { DataRefImpl RelData; const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); @@ -1366,10 +1488,9 @@ relocation_iterator ELFObjectFile<target_endianness, is64Bits> } // Relocations -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationNext(DataRefImpl Rel, - RelocationRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, + RelocationRef &Result) const { ++Rel.w.c; const Elf_Shdr *relocsec = getSection(Rel.w.b); if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { @@ -1395,21 +1516,20 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Result) const { uint32_t symbolIdx; const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { default : report_fatal_error("Invalid section type in Rel!"); case ELF::SHT_REL : { - symbolIdx = getRel(Rel)->getSymbol(); + symbolIdx = getRel(Rel)->getSymbol(isMips64EL()); break; } case ELF::SHT_RELA : { - symbolIdx = getRela(Rel)->getSymbol(); + symbolIdx = getRela(Rel)->getSymbol(isMips64EL()); break; } } @@ -1423,10 +1543,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationAddress(DataRefImpl Rel, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, + uint64_t &Result) const { uint64_t offset; const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { @@ -1446,10 +1565,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationOffset(DataRefImpl Rel, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, + uint64_t &Result) const { uint64_t offset; const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { @@ -1469,20 +1587,19 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationType(DataRefImpl Rel, - uint64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, + uint64_t &Result) const { const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { default : report_fatal_error("Invalid section type in Rel!"); case ELF::SHT_REL : { - Result = getRel(Rel)->getType(); + Result = getRel(Rel)->getType(isMips64EL()); break; } case ELF::SHT_RELA : { - Result = getRela(Rel)->getType(); + Result = getRela(Rel)->getType(isMips64EL()); break; } } @@ -1492,22 +1609,21 @@ error_code ELFObjectFile<target_endianness, is64Bits> #define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ case ELF::enum: res = #enum; break; -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationTypeName( + DataRefImpl Rel, SmallVectorImpl<char> &Result) const { const Elf_Shdr *sec = getSection(Rel.w.b); - uint8_t type; + uint32_t type; StringRef res; switch (sec->sh_type) { default : return object_error::parse_failed; case ELF::SHT_REL : { - type = getRel(Rel)->getType(); + type = getRel(Rel)->getType(isMips64EL()); break; } case ELF::SHT_RELA : { - type = getRela(Rel)->getType(); + type = getRela(Rel)->getType(isMips64EL()); break; } } @@ -1596,6 +1712,143 @@ error_code ELFObjectFile<target_endianness, is64Bits> res = "Unknown"; } break; + case ELF::EM_MIPS: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT); + default: + res = "Unknown"; + } + break; + case ELF::EM_AARCH64: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G3); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD_PREL_LO19); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_LO21); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_PG_HI21); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADD_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST8_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TSTBR14); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CONDBR19); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_JUMP26); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CALL26); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST16_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST32_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST64_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST128_ABS_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_GOT_PAGE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD64_GOT_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_HI12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G2); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_HI12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADR_PAGE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL); + + default: + res = "Unknown"; + } + break; case ELF::EM_ARM: switch (type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); @@ -1834,10 +2087,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> #undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo( + DataRefImpl Rel, int64_t &Result) const { const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { default : @@ -1853,10 +2105,9 @@ error_code ELFObjectFile<target_endianness, is64Bits> } } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getRelocationValueString( + DataRefImpl Rel, SmallVectorImpl<char> &Result) const { const Elf_Shdr *sec = getSection(Rel.w.b); uint8_t type; StringRef res; @@ -1866,14 +2117,14 @@ error_code ELFObjectFile<target_endianness, is64Bits> default: return object_error::parse_failed; case ELF::SHT_REL: { - type = getRel(Rel)->getType(); - symbol_index = getRel(Rel)->getSymbol(); + type = getRel(Rel)->getType(isMips64EL()); + symbol_index = getRel(Rel)->getSymbol(isMips64EL()); // TODO: Read implicit addend from section data. break; } case ELF::SHT_RELA: { - type = getRela(Rel)->getType(); - symbol_index = getRela(Rel)->getSymbol(); + type = getRela(Rel)->getType(isMips64EL()); + symbol_index = getRela(Rel)->getSymbol(isMips64EL()); addend = getRela(Rel)->r_addend; break; } @@ -1911,6 +2162,7 @@ error_code ELFObjectFile<target_endianness, is64Bits> res = "Unknown"; } break; + case ELF::EM_AARCH64: case ELF::EM_ARM: case ELF::EM_HEXAGON: res = symname; @@ -1924,20 +2176,21 @@ error_code ELFObjectFile<target_endianness, is64Bits> } // Verify that the last byte in the string table in a null. -template<support::endianness target_endianness, bool is64Bits> -void ELFObjectFile<target_endianness, is64Bits> - ::VerifyStrTab(const Elf_Shdr *sh) const { +template<class ELFT> +void ELFObjectFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const { const char *strtab = (const char*)base() + sh->sh_offset; if (strtab[sh->sh_size - 1] != 0) // FIXME: Proper error handling. report_fatal_error("String table must end with a null terminator!"); } -template<support::endianness target_endianness, bool is64Bits> -ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object - , error_code &ec) - : ObjectFile(getELFType(target_endianness == support::little, is64Bits), - Object, ec) +template<class ELFT> +ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) + : ObjectFile(getELFType( + static_cast<endianness>(ELFT::TargetEndianness) == support::little, + ELFT::Is64Bits), + Object, + ec) , isDyldELFObject(false) , SectionHeaderTable(0) , dot_shstrtab_sec(0) @@ -2094,9 +2347,22 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object } } -template<support::endianness target_endianness, bool is64Bits> -symbol_iterator ELFObjectFile<target_endianness, is64Bits> - ::begin_symbols() const { +// Get the symbol table index in the symtab section given a symbol +template<class ELFT> +uint64_t ELFObjectFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const { + assert(SymbolTableSections.size() == 1 && "Only one symbol table supported!"); + const Elf_Shdr *SymTab = *SymbolTableSections.begin(); + uintptr_t SymLoc = uintptr_t(Sym); + uintptr_t SymTabLoc = uintptr_t(base() + SymTab->sh_offset); + assert(SymLoc > SymTabLoc && "Symbol not in symbol table!"); + uint64_t SymOffset = SymLoc - SymTabLoc; + assert(SymOffset % SymTab->sh_entsize == 0 && + "Symbol not multiple of symbol size!"); + return SymOffset / SymTab->sh_entsize; +} + +template<class ELFT> +symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { DataRefImpl SymbolData; if (SymbolTableSections.size() <= 1) { SymbolData.d.a = std::numeric_limits<uint32_t>::max(); @@ -2108,18 +2374,16 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits> return symbol_iterator(SymbolRef(SymbolData, this)); } -template<support::endianness target_endianness, bool is64Bits> -symbol_iterator ELFObjectFile<target_endianness, is64Bits> - ::end_symbols() const { +template<class ELFT> +symbol_iterator ELFObjectFile<ELFT>::end_symbols() const { DataRefImpl SymbolData; SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); return symbol_iterator(SymbolRef(SymbolData, this)); } -template<support::endianness target_endianness, bool is64Bits> -symbol_iterator ELFObjectFile<target_endianness, is64Bits> - ::begin_dynamic_symbols() const { +template<class ELFT> +symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { DataRefImpl SymbolData; if (SymbolTableSections[0] == NULL) { SymbolData.d.a = std::numeric_limits<uint32_t>::max(); @@ -2131,26 +2395,23 @@ symbol_iterator ELFObjectFile<target_endianness, is64Bits> return symbol_iterator(SymbolRef(SymbolData, this)); } -template<support::endianness target_endianness, bool is64Bits> -symbol_iterator ELFObjectFile<target_endianness, is64Bits> - ::end_dynamic_symbols() const { +template<class ELFT> +symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { DataRefImpl SymbolData; SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); return symbol_iterator(SymbolRef(SymbolData, this)); } -template<support::endianness target_endianness, bool is64Bits> -section_iterator ELFObjectFile<target_endianness, is64Bits> - ::begin_sections() const { +template<class ELFT> +section_iterator ELFObjectFile<ELFT>::begin_sections() const { DataRefImpl ret; ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); return section_iterator(SectionRef(ret, this)); } -template<support::endianness target_endianness, bool is64Bits> -section_iterator ELFObjectFile<target_endianness, is64Bits> - ::end_sections() const { +template<class ELFT> +section_iterator ELFObjectFile<ELFT>::end_sections() const { DataRefImpl ret; ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff @@ -2158,58 +2419,47 @@ section_iterator ELFObjectFile<target_endianness, is64Bits> return section_iterator(SectionRef(ret, this)); } -template<support::endianness target_endianness, bool is64Bits> -typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator -ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const { - DataRefImpl DynData; - if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) { - DynData.d.a = std::numeric_limits<uint32_t>::max(); - } else { - DynData.d.a = 0; - } - return dyn_iterator(DynRef(DynData, this)); -} - -template<support::endianness target_endianness, bool is64Bits> -typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator -ELFObjectFile<target_endianness, is64Bits> - ::end_dynamic_table() const { - DataRefImpl DynData; - DynData.d.a = std::numeric_limits<uint32_t>::max(); - return dyn_iterator(DynRef(DynData, this)); -} - -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getDynNext(DataRefImpl DynData, - DynRef &Result) const { - ++DynData.d.a; - - // Check to see if we are at the end of .dynamic - if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) { - // We are at the end. Return the terminator. - DynData.d.a = std::numeric_limits<uint32_t>::max(); +template<class ELFT> +typename ELFObjectFile<ELFT>::Elf_Dyn_iterator +ELFObjectFile<ELFT>::begin_dynamic_table() const { + if (dot_dynamic_sec) + return Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, + (const char *)base() + dot_dynamic_sec->sh_offset); + return Elf_Dyn_iterator(0, 0); +} + +template<class ELFT> +typename ELFObjectFile<ELFT>::Elf_Dyn_iterator +ELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const { + if (dot_dynamic_sec) { + Elf_Dyn_iterator Ret(dot_dynamic_sec->sh_entsize, + (const char *)base() + dot_dynamic_sec->sh_offset + + dot_dynamic_sec->sh_size); + + if (NULLEnd) { + Elf_Dyn_iterator Start = begin_dynamic_table(); + while (Start != Ret && Start->getTag() != ELF::DT_NULL) + ++Start; + + // Include the DT_NULL. + if (Start != Ret) + ++Start; + Ret = Start; + } + return Ret; } - - Result = DynRef(DynData, this); - return object_error::success; + return Elf_Dyn_iterator(0, 0); } -template<support::endianness target_endianness, bool is64Bits> -StringRef -ELFObjectFile<target_endianness, is64Bits>::getLoadName() const { +template<class ELFT> +StringRef ELFObjectFile<ELFT>::getLoadName() const { if (!dt_soname) { // Find the DT_SONAME entry - dyn_iterator it = begin_dynamic_table(); - dyn_iterator ie = end_dynamic_table(); - error_code ec; - while (it != ie) { - if (it->getTag() == ELF::DT_SONAME) - break; - it.increment(ec); - if (ec) - report_fatal_error("dynamic table iteration failed"); - } + Elf_Dyn_iterator it = begin_dynamic_table(); + Elf_Dyn_iterator ie = end_dynamic_table(); + while (it != ie && it->getTag() != ELF::DT_SONAME) + ++it; + if (it != ie) { if (dot_dynstr_sec == NULL) report_fatal_error("Dynamic string table is missing"); @@ -2221,57 +2471,43 @@ ELFObjectFile<target_endianness, is64Bits>::getLoadName() const { return dt_soname; } -template<support::endianness target_endianness, bool is64Bits> -library_iterator ELFObjectFile<target_endianness, is64Bits> - ::begin_libraries_needed() const { +template<class ELFT> +library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { // Find the first DT_NEEDED entry - dyn_iterator i = begin_dynamic_table(); - dyn_iterator e = end_dynamic_table(); - error_code ec; - while (i != e) { - if (i->getTag() == ELF::DT_NEEDED) - break; - i.increment(ec); - if (ec) - report_fatal_error("dynamic table iteration failed"); - } - // Use the same DataRefImpl format as DynRef. - return library_iterator(LibraryRef(i->getRawDataRefImpl(), this)); + Elf_Dyn_iterator i = begin_dynamic_table(); + Elf_Dyn_iterator e = end_dynamic_table(); + while (i != e && i->getTag() != ELF::DT_NEEDED) + ++i; + + DataRefImpl DRI; + DRI.p = reinterpret_cast<uintptr_t>(i.get()); + return library_iterator(LibraryRef(DRI, this)); } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getLibraryNext(DataRefImpl Data, - LibraryRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, + LibraryRef &Result) const { // Use the same DataRefImpl format as DynRef. - dyn_iterator i = dyn_iterator(DynRef(Data, this)); - dyn_iterator e = end_dynamic_table(); - - // Skip the current dynamic table entry. - error_code ec; - if (i != e) { - i.increment(ec); - // TODO: proper error handling - if (ec) - report_fatal_error("dynamic table iteration failed"); - } - - // Find the next DT_NEEDED entry. - while (i != e) { - if (i->getTag() == ELF::DT_NEEDED) - break; - i.increment(ec); - if (ec) - report_fatal_error("dynamic table iteration failed"); - } - Result = LibraryRef(i->getRawDataRefImpl(), this); + Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, + reinterpret_cast<const char *>(Data.p)); + Elf_Dyn_iterator e = end_dynamic_table(); + + // Skip the current dynamic table entry and find the next DT_NEEDED entry. + do + ++i; + while (i != e && i->getTag() != ELF::DT_NEEDED); + + DataRefImpl DRI; + DRI.p = reinterpret_cast<uintptr_t>(i.get()); + Result = LibraryRef(DRI, this); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getLibraryPath(DataRefImpl Data, StringRef &Res) const { - dyn_iterator i = dyn_iterator(DynRef(Data, this)); +template<class ELFT> +error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, + StringRef &Res) const { + Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, + reinterpret_cast<const char *>(Data.p)); if (i == end_dynamic_table()) report_fatal_error("getLibraryPath() called on iterator end"); @@ -2289,22 +2525,21 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -library_iterator ELFObjectFile<target_endianness, is64Bits> - ::end_libraries_needed() const { - dyn_iterator e = end_dynamic_table(); - // Use the same DataRefImpl format as DynRef. - return library_iterator(LibraryRef(e->getRawDataRefImpl(), this)); +template<class ELFT> +library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { + Elf_Dyn_iterator e = end_dynamic_table(); + DataRefImpl DRI; + DRI.p = reinterpret_cast<uintptr_t>(e.get()); + return library_iterator(LibraryRef(DRI, this)); } -template<support::endianness target_endianness, bool is64Bits> -uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const { - return is64Bits ? 8 : 4; +template<class ELFT> +uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { + return ELFT::Is64Bits ? 8 : 4; } -template<support::endianness target_endianness, bool is64Bits> -StringRef ELFObjectFile<target_endianness, is64Bits> - ::getFileFormatName() const { +template<class ELFT> +StringRef ELFObjectFile<ELFT>::getFileFormatName() const { switch(Header->e_ident[ELF::EI_CLASS]) { case ELF::ELFCLASS32: switch(Header->e_machine) { @@ -2316,6 +2551,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits> return "ELF32-arm"; case ELF::EM_HEXAGON: return "ELF32-hexagon"; + case ELF::EM_MIPS: + return "ELF32-mips"; default: return "ELF32-unknown"; } @@ -2325,6 +2562,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits> return "ELF64-i386"; case ELF::EM_X86_64: return "ELF64-x86-64"; + case ELF::EM_AARCH64: + return "ELF64-aarch64"; case ELF::EM_PPC64: return "ELF64-ppc64"; default: @@ -2336,19 +2575,21 @@ StringRef ELFObjectFile<target_endianness, is64Bits> } } -template<support::endianness target_endianness, bool is64Bits> -unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { +template<class ELFT> +unsigned ELFObjectFile<ELFT>::getArch() const { switch(Header->e_machine) { case ELF::EM_386: return Triple::x86; case ELF::EM_X86_64: return Triple::x86_64; + case ELF::EM_AARCH64: + return Triple::aarch64; case ELF::EM_ARM: return Triple::arm; case ELF::EM_HEXAGON: return Triple::hexagon; case ELF::EM_MIPS: - return (target_endianness == support::little) ? + return (ELFT::TargetEndianness == support::little) ? Triple::mipsel : Triple::mips; case ELF::EM_PPC64: return Triple::ppc64; @@ -2357,8 +2598,8 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { } } -template<support::endianness target_endianness, bool is64Bits> -uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const { +template<class ELFT> +uint64_t ELFObjectFile<ELFT>::getNumSections() const { assert(Header && "Header not initialized!"); if (Header->e_shnum == ELF::SHN_UNDEF) { assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); @@ -2367,9 +2608,9 @@ uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const { return Header->e_shnum; } -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> uint64_t -ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const { +ELFObjectFile<ELFT>::getStringTableIndex() const { if (Header->e_shnum == ELF::SHN_UNDEF) { if (Header->e_shstrndx == ELF::SHN_HIRESERVE) return SectionHeaderTable->sh_link; @@ -2379,53 +2620,44 @@ ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const { return Header->e_shstrndx; } - -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> template<typename T> inline const T * -ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section, - uint32_t Entry) const { +ELFObjectFile<ELFT>::getEntry(uint16_t Section, uint32_t Entry) const { return getEntry<T>(getSection(Section), Entry); } -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> template<typename T> inline const T * -ELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section, - uint32_t Entry) const { +ELFObjectFile<ELFT>::getEntry(const Elf_Shdr * Section, uint32_t Entry) const { return reinterpret_cast<const T *>( base() + Section->sh_offset + (Entry * Section->sh_entsize)); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * -ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Sym * +ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Dyn * -ELFObjectFile<target_endianness, is64Bits>::getDyn(DataRefImpl DynData) const { - return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a); -} - -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel * -ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Rel * +ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela * -ELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Rela * +ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * -ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Shdr * +ELFObjectFile<ELFT>::getSection(DataRefImpl Symb) const { const Elf_Shdr *sec = getSection(Symb.d.b); if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) // FIXME: Proper error handling. @@ -2433,9 +2665,9 @@ ELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const { return sec; } -template<support::endianness target_endianness, bool is64Bits> -const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * -ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const { +template<class ELFT> +const typename ELFObjectFile<ELFT>::Elf_Shdr * +ELFObjectFile<ELFT>::getSection(uint32_t index) const { if (index == 0) return 0; if (!SectionHeaderTable || index >= getNumSections()) @@ -2447,17 +2679,15 @@ ELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const { + (index * Header->e_shentsize)); } -template<support::endianness target_endianness, bool is64Bits> -const char *ELFObjectFile<target_endianness, is64Bits> - ::getString(uint32_t section, - ELF::Elf32_Word offset) const { +template<class ELFT> +const char *ELFObjectFile<ELFT>::getString(uint32_t section, + ELF::Elf32_Word offset) const { return getString(getSection(section), offset); } -template<support::endianness target_endianness, bool is64Bits> -const char *ELFObjectFile<target_endianness, is64Bits> - ::getString(const Elf_Shdr *section, - ELF::Elf32_Word offset) const { +template<class ELFT> +const char *ELFObjectFile<ELFT>::getString(const Elf_Shdr *section, + ELF::Elf32_Word offset) const { assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); if (offset >= section->sh_size) // FIXME: Proper error handling. @@ -2465,11 +2695,10 @@ const char *ELFObjectFile<target_endianness, is64Bits> return (const char *)base() + section->sh_offset + offset; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolName(const Elf_Shdr *section, - const Elf_Sym *symb, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolName(const Elf_Shdr *section, + const Elf_Sym *symb, + StringRef &Result) const { if (symb->st_name == 0) { const Elf_Shdr *section = getSection(symb); if (!section) @@ -2489,20 +2718,18 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSectionName(const Elf_Shdr *section, - StringRef &Result) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSectionName(const Elf_Shdr *section, + StringRef &Result) const { Result = StringRef(getString(dot_shstrtab_sec, section->sh_name)); return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -error_code ELFObjectFile<target_endianness, is64Bits> - ::getSymbolVersion(const Elf_Shdr *section, - const Elf_Sym *symb, - StringRef &Version, - bool &IsDefault) const { +template<class ELFT> +error_code ELFObjectFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, + const Elf_Sym *symb, + StringRef &Version, + bool &IsDefault) const { // Handle non-dynamic symbols. if (section != SymbolTableSections[0]) { // Non-dynamic symbols can have versions in their names @@ -2580,54 +2807,6 @@ error_code ELFObjectFile<target_endianness, is64Bits> return object_error::success; } -template<support::endianness target_endianness, bool is64Bits> -inline DynRefImpl<target_endianness, is64Bits> - ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner) - : DynPimpl(DynP) - , OwningObject(Owner) {} - -template<support::endianness target_endianness, bool is64Bits> -inline bool DynRefImpl<target_endianness, is64Bits> - ::operator==(const DynRefImpl &Other) const { - return DynPimpl == Other.DynPimpl; -} - -template<support::endianness target_endianness, bool is64Bits> -inline bool DynRefImpl<target_endianness, is64Bits> - ::operator <(const DynRefImpl &Other) const { - return DynPimpl < Other.DynPimpl; -} - -template<support::endianness target_endianness, bool is64Bits> -inline error_code DynRefImpl<target_endianness, is64Bits> - ::getNext(DynRefImpl &Result) const { - return OwningObject->getDynNext(DynPimpl, Result); -} - -template<support::endianness target_endianness, bool is64Bits> -inline int64_t DynRefImpl<target_endianness, is64Bits> - ::getTag() const { - return OwningObject->getDyn(DynPimpl)->d_tag; -} - -template<support::endianness target_endianness, bool is64Bits> -inline uint64_t DynRefImpl<target_endianness, is64Bits> - ::getVal() const { - return OwningObject->getDyn(DynPimpl)->d_un.d_val; -} - -template<support::endianness target_endianness, bool is64Bits> -inline uint64_t DynRefImpl<target_endianness, is64Bits> - ::getPtr() const { - return OwningObject->getDyn(DynPimpl)->d_un.d_ptr; -} - -template<support::endianness target_endianness, bool is64Bits> -inline DataRefImpl DynRefImpl<target_endianness, is64Bits> - ::getRawDataRefImpl() const { - return DynPimpl; -} - /// This is a generic interface for retrieving GNU symbol version /// information from an ELFObjectFile. static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, @@ -2635,28 +2814,43 @@ static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, StringRef &Version, bool &IsDefault) { // Little-endian 32-bit - if (const ELFObjectFile<support::little, false> *ELFObj = - dyn_cast<ELFObjectFile<support::little, false> >(Obj)) + if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj)) return ELFObj->getSymbolVersion(Sym, Version, IsDefault); // Big-endian 32-bit - if (const ELFObjectFile<support::big, false> *ELFObj = - dyn_cast<ELFObjectFile<support::big, false> >(Obj)) + if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj)) return ELFObj->getSymbolVersion(Sym, Version, IsDefault); // Little-endian 64-bit - if (const ELFObjectFile<support::little, true> *ELFObj = - dyn_cast<ELFObjectFile<support::little, true> >(Obj)) + if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj)) return ELFObj->getSymbolVersion(Sym, Version, IsDefault); // Big-endian 64-bit - if (const ELFObjectFile<support::big, true> *ELFObj = - dyn_cast<ELFObjectFile<support::big, true> >(Obj)) + if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj)) return ELFObj->getSymbolVersion(Sym, Version, IsDefault); llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); } +/// This function returns the hash value for a symbol in the .dynsym section +/// Name of the API remains consistent as specified in the libelf +/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash +static inline unsigned elf_hash(StringRef &symbolName) { + unsigned h = 0, g; + for (unsigned i = 0, j = symbolName.size(); i < j; i++) { + h = (h << 4) + symbolName[i]; + g = h & 0xf0000000L; + if (g != 0) + h ^= g >> 24; + h &= ~g; + } + return h; +} + } } diff --git a/contrib/llvm/include/llvm/Object/MachO.h b/contrib/llvm/include/llvm/Object/MachO.h index 4e03daa..ed7aabd 100644 --- a/contrib/llvm/include/llvm/Object/MachO.h +++ b/contrib/llvm/include/llvm/Object/MachO.h @@ -15,11 +15,11 @@ #ifndef LLVM_OBJECT_MACHO_H #define LLVM_OBJECT_MACHO_H -#include "llvm/Object/ObjectFile.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Object/MachOObject.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallVector.h" namespace llvm { namespace object { @@ -44,7 +44,12 @@ public: virtual unsigned getArch() const; virtual StringRef getLoadName() const; - MachOObject *getObject() { return MachOObj; } + // In a MachO file, sections have a segment name. This is used in the .o + // files. They have a single segment, but this field specifies which segment + // a section should be put in in the final object. + error_code getSectionFinalSegmentName(DataRefImpl Sec, StringRef &Res) const; + + MachOObject *getObject() { return MachOObj.get(); } static inline bool classof(const Binary *v) { return v->isMachO(); @@ -104,7 +109,7 @@ protected: virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const; private: - MachOObject *MachOObj; + OwningPtr<MachOObject> MachOObj; mutable uint32_t RegisteredStringTable; typedef SmallVector<DataRefImpl, 1> SectionList; SectionList Sections; diff --git a/contrib/llvm/include/llvm/Object/MachOFormat.h b/contrib/llvm/include/llvm/Object/MachOFormat.h index c0f700d..ffca391 100644 --- a/contrib/llvm/include/llvm/Object/MachOFormat.h +++ b/contrib/llvm/include/llvm/Object/MachOFormat.h @@ -64,7 +64,10 @@ namespace mach { CSARM_V7 = 9, CSARM_V7F = 10, CSARM_V7S = 11, - CSARM_V7K = 12 + CSARM_V7K = 12, + CSARM_V6M = 14, + CSARM_V7M = 15, + CSARM_V7EM = 16 }; /// \brief PowerPC Machine Subtypes. @@ -145,7 +148,8 @@ namespace macho { LCT_CodeSignature = 0x1d, LCT_SegmentSplitInfo = 0x1e, LCT_FunctionStarts = 0x26, - LCT_DataInCode = 0x29 + LCT_DataInCode = 0x29, + LCT_LinkerOptions = 0x2D }; /// \brief Load command structure. @@ -233,10 +237,22 @@ namespace macho { uint32_t DataSize; }; + struct LinkerOptionsLoadCommand { + uint32_t Type; + uint32_t Size; + uint32_t Count; + // Load command is followed by Count number of zero-terminated UTF8 strings, + // and then zero-filled to be 4-byte aligned. + }; + /// @} /// @name Section Data /// @{ + enum SectionFlags { + SF_PureInstructions = 0x80000000 + }; + struct Section { char Name[16]; char SegmentName[16]; diff --git a/contrib/llvm/include/llvm/Object/MachOObject.h b/contrib/llvm/include/llvm/Object/MachOObject.h index 86f150a..9e4ab19 100644 --- a/contrib/llvm/include/llvm/Object/MachOObject.h +++ b/contrib/llvm/include/llvm/Object/MachOObject.h @@ -10,11 +10,11 @@ #ifndef LLVM_OBJECT_MACHOOBJECT_H #define LLVM_OBJECT_MACHOOBJECT_H -#include <string> #include "llvm/ADT/InMemoryStruct.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/MachOFormat.h" +#include <string> namespace llvm { @@ -153,6 +153,9 @@ public: void ReadLinkeditDataLoadCommand( const LoadCommandInfo &LCI, InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const; + void ReadLinkerOptionsLoadCommand( + const LoadCommandInfo &LCI, + InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const; void ReadIndirectSymbolTableEntry( const macho::DysymtabLoadCommand &DLC, unsigned Index, diff --git a/contrib/llvm/include/llvm/Object/ObjectFile.h b/contrib/llvm/include/llvm/Object/ObjectFile.h index 1a3120a..6a66653 100644 --- a/contrib/llvm/include/llvm/Object/ObjectFile.h +++ b/contrib/llvm/include/llvm/Object/ObjectFile.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJECT_OBJECT_FILE_H -#define LLVM_OBJECT_OBJECT_FILE_H +#ifndef LLVM_OBJECT_OBJECTFILE_H +#define LLVM_OBJECT_OBJECTFILE_H -#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/contrib/llvm/include/llvm/Object/RelocVisitor.h b/contrib/llvm/include/llvm/Object/RelocVisitor.h index 7668bde..2dcbdf9 100644 --- a/contrib/llvm/include/llvm/Object/RelocVisitor.h +++ b/contrib/llvm/include/llvm/Object/RelocVisitor.h @@ -13,14 +13,14 @@ // //===----------------------------------------------------------------------===// -#ifndef _LLVM_OBJECT_RELOCVISITOR -#define _LLVM_OBJECT_RELOCVISITOR +#ifndef LLVM_OBJECT_RELOCVISITOR_H +#define LLVM_OBJECT_RELOCVISITOR_H +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Object/ELF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { namespace object { @@ -40,7 +40,7 @@ struct RelocToApply { /// @brief Base class for object file relocation visitors. class RelocVisitor { public: - explicit RelocVisitor(llvm::StringRef FileFormat) + explicit RelocVisitor(StringRef FileFormat) : FileFormat(FileFormat), HasError(false) {} // TODO: Should handle multiple applied relocations via either passing in the @@ -64,35 +64,77 @@ public: HasError = true; return RelocToApply(); } + } else if (FileFormat == "ELF32-i386") { + switch (RelocType) { + case llvm::ELF::R_386_NONE: + return visitELF_386_NONE(R); + case llvm::ELF::R_386_32: + return visitELF_386_32(R, Value); + case llvm::ELF::R_386_PC32: + return visitELF_386_PC32(R, Value, SecAddr); + default: + HasError = true; + return RelocToApply(); + } + } else if (FileFormat == "ELF64-ppc64") { + switch (RelocType) { + case llvm::ELF::R_PPC64_ADDR32: + return visitELF_PPC64_ADDR32(R, Value); + default: + HasError = true; + return RelocToApply(); + } + } else if (FileFormat == "ELF32-mips") { + switch (RelocType) { + case llvm::ELF::R_MIPS_32: + return visitELF_MIPS_32(R, Value); + default: + HasError = true; + return RelocToApply(); + } + } else if (FileFormat == "ELF64-aarch64") { + switch (RelocType) { + case llvm::ELF::R_AARCH64_ABS32: + return visitELF_AARCH64_ABS32(R, Value); + case llvm::ELF::R_AARCH64_ABS64: + return visitELF_AARCH64_ABS64(R, Value); + default: + HasError = true; + return RelocToApply(); + } } + HasError = true; return RelocToApply(); } bool error() { return HasError; } private: - llvm::StringRef FileFormat; + StringRef FileFormat; bool HasError; /// Operations - // Width is the width in bytes of the extend. - RelocToApply zeroExtend(RelocToApply r, char Width) { - if (Width == r.Width) - return r; - r.Value &= (1 << ((Width * 8))) - 1; - return r; + /// 386-ELF + RelocToApply visitELF_386_NONE(RelocationRef R) { + return RelocToApply(0, 0); } - RelocToApply signExtend(RelocToApply r, char Width) { - if (Width == r.Width) - return r; - bool SignBit = r.Value & (1 << ((Width * 8) - 1)); - if (SignBit) { - r.Value |= ~((1 << (Width * 8)) - 1); - } else { - r.Value &= (1 << (Width * 8)) - 1; - } - return r; + + // Ideally the Addend here will be the addend in the data for + // the relocation. It's not actually the case for Rel relocations. + RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + return RelocToApply(Value + Addend, 4); + } + + RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value, + uint64_t SecAddr) { + int64_t Addend; + R.getAdditionalInfo(Addend); + uint64_t Address; + R.getAddress(Address); + return RelocToApply(Value + Addend - Address, 4); } /// X86-64 ELF @@ -124,6 +166,42 @@ private: int32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } + + /// PPC64 ELF + RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + uint32_t Res = (Value + Addend) & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } + + /// MIPS ELF + RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + uint32_t Res = (Value + Addend) & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } + + // AArch64 ELF + RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + int64_t Res = Value + Addend; + + // Overflow check allows for both signed and unsigned interpretation. + if (Res < INT32_MIN || Res > UINT32_MAX) + HasError = true; + + return RelocToApply(static_cast<uint32_t>(Res), 4); + } + + RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { + int64_t Addend; + R.getAdditionalInfo(Addend); + return RelocToApply(Value + Addend, 8); + } + }; } diff --git a/contrib/llvm/include/llvm/Option/Arg.h b/contrib/llvm/include/llvm/Option/Arg.h new file mode 100644 index 0000000..6b8ed3f --- /dev/null +++ b/contrib/llvm/include/llvm/Option/Arg.h @@ -0,0 +1,132 @@ +//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines the llvm::Arg class for parsed arguments. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPTION_ARG_H +#define LLVM_OPTION_ARG_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" +#include <string> + +namespace llvm { +namespace opt { +class ArgList; + +/// \brief A concrete instance of a particular driver option. +/// +/// The Arg class encodes just enough information to be able to +/// derive the argument values efficiently. In addition, Arg +/// instances have an intrusive double linked list which is used by +/// ArgList to provide efficient iteration over all instances of a +/// particular option. +class Arg { + Arg(const Arg &) LLVM_DELETED_FUNCTION; + void operator=(const Arg &) LLVM_DELETED_FUNCTION; + +private: + /// \brief The option this argument is an instance of. + const Option Opt; + + /// \brief The argument this argument was derived from (during tool chain + /// argument translation), if any. + const Arg *BaseArg; + + /// \brief How this instance of the option was spelled. + StringRef Spelling; + + /// \brief The index at which this argument appears in the containing + /// ArgList. + unsigned Index; + + /// \brief Was this argument used to effect compilation? + /// + /// This is used for generating "argument unused" diagnostics. + mutable unsigned Claimed : 1; + + /// \brief Does this argument own its values? + mutable unsigned OwnsValues : 1; + + /// \brief The argument values, as C strings. + SmallVector<const char *, 2> Values; + +public: + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const Arg *BaseArg = 0); + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const char *Value0, const Arg *BaseArg = 0); + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const char *Value0, const char *Value1, const Arg *BaseArg = 0); + ~Arg(); + + const Option getOption() const { return Opt; } + StringRef getSpelling() const { return Spelling; } + unsigned getIndex() const { return Index; } + + /// \brief Return the base argument which generated this arg. + /// + /// This is either the argument itself or the argument it was + /// derived from during tool chain specific argument translation. + const Arg &getBaseArg() const { + return BaseArg ? *BaseArg : *this; + } + void setBaseArg(const Arg *_BaseArg) { + BaseArg = _BaseArg; + } + + bool getOwnsValues() const { return OwnsValues; } + void setOwnsValues(bool Value) const { OwnsValues = Value; } + + bool isClaimed() const { return getBaseArg().Claimed; } + + /// \brief Set the Arg claimed bit. + void claim() const { getBaseArg().Claimed = true; } + + unsigned getNumValues() const { return Values.size(); } + const char *getValue(unsigned N = 0) const { + return Values[N]; + } + + SmallVectorImpl<const char*> &getValues() { + return Values; + } + + bool containsValue(StringRef Value) const { + for (unsigned i = 0, e = getNumValues(); i != e; ++i) + if (Values[i] == Value) + return true; + return false; + } + + /// \brief Append the argument onto the given array as strings. + void render(const ArgList &Args, ArgStringList &Output) const; + + /// \brief Append the argument, render as an input, onto the given + /// array as strings. + /// + /// The distinction is that some options only render their values + /// when rendered as a input (e.g., Xlinker). + void renderAsInput(const ArgList &Args, ArgStringList &Output) const; + + void dump() const; + + /// \brief Return a formatted version of the argument and + /// its values, for debugging and diagnostics. + std::string getAsString(const ArgList &Args) const; +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Option/ArgList.h b/contrib/llvm/include/llvm/Option/ArgList.h new file mode 100644 index 0000000..d3accfe --- /dev/null +++ b/contrib/llvm/include/llvm/Option/ArgList.h @@ -0,0 +1,414 @@ +//===--- ArgList.h - Argument List Management -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPTION_ARGLIST_H +#define LLVM_OPTION_ARGLIST_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/OptSpecifier.h" +#include "llvm/Option/Option.h" +#include <list> +#include <string> +#include <vector> + +namespace llvm { +namespace opt { +class Arg; +class ArgList; +class Option; + +/// arg_iterator - Iterates through arguments stored inside an ArgList. +class arg_iterator { + /// The current argument. + SmallVectorImpl<Arg*>::const_iterator Current; + + /// The argument list we are iterating over. + const ArgList &Args; + + /// Optional filters on the arguments which will be match. Most clients + /// should never want to iterate over arguments without filters, so we won't + /// bother to factor this into two separate iterator implementations. + // + // FIXME: Make efficient; the idea is to provide efficient iteration over + // all arguments which match a particular id and then just provide an + // iterator combinator which takes multiple iterators which can be + // efficiently compared and returns them in order. + OptSpecifier Id0, Id1, Id2; + + void SkipToNextArg(); + +public: + typedef Arg * const * value_type; + typedef Arg * const & reference; + typedef Arg * const * pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, + const ArgList &_Args, OptSpecifier _Id0 = 0U, + OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) + : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { + SkipToNextArg(); + } + + operator const Arg*() { return *Current; } + reference operator*() const { return *Current; } + pointer operator->() const { return Current; } + + arg_iterator &operator++() { + ++Current; + SkipToNextArg(); + return *this; + } + + arg_iterator operator++(int) { + arg_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool operator==(arg_iterator LHS, arg_iterator RHS) { + return LHS.Current == RHS.Current; + } + friend bool operator!=(arg_iterator LHS, arg_iterator RHS) { + return !(LHS == RHS); + } +}; + +/// ArgList - Ordered collection of driver arguments. +/// +/// The ArgList class manages a list of Arg instances as well as +/// auxiliary data and convenience methods to allow Tools to quickly +/// check for the presence of Arg instances for a particular Option +/// and to iterate over groups of arguments. +class ArgList { +private: + ArgList(const ArgList &) LLVM_DELETED_FUNCTION; + void operator=(const ArgList &) LLVM_DELETED_FUNCTION; + +public: + typedef SmallVector<Arg*, 16> arglist_type; + typedef arglist_type::iterator iterator; + typedef arglist_type::const_iterator const_iterator; + typedef arglist_type::reverse_iterator reverse_iterator; + typedef arglist_type::const_reverse_iterator const_reverse_iterator; + +private: + /// The internal list of arguments. + arglist_type Args; + +protected: + ArgList(); + +public: + virtual ~ArgList(); + + /// @name Arg Access + /// @{ + + /// append - Append \p A to the arg list. + void append(Arg *A); + + arglist_type &getArgs() { return Args; } + const arglist_type &getArgs() const { return Args; } + + unsigned size() const { return Args.size(); } + + /// @} + /// @name Arg Iteration + /// @{ + + iterator begin() { return Args.begin(); } + iterator end() { return Args.end(); } + + reverse_iterator rbegin() { return Args.rbegin(); } + reverse_iterator rend() { return Args.rend(); } + + const_iterator begin() const { return Args.begin(); } + const_iterator end() const { return Args.end(); } + + const_reverse_iterator rbegin() const { return Args.rbegin(); } + const_reverse_iterator rend() const { return Args.rend(); } + + arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U, + OptSpecifier Id2 = 0U) const { + return arg_iterator(Args.begin(), *this, Id0, Id1, Id2); + } + arg_iterator filtered_end() const { + return arg_iterator(Args.end(), *this); + } + + /// @} + /// @name Arg Removal + /// @{ + + /// eraseArg - Remove any option matching \p Id. + void eraseArg(OptSpecifier Id); + + /// @} + /// @name Arg Access + /// @{ + + /// hasArg - Does the arg list contain any option matching \p Id. + /// + /// \p Claim Whether the argument should be claimed, if it exists. + bool hasArgNoClaim(OptSpecifier Id) const { + return getLastArgNoClaim(Id) != 0; + } + bool hasArg(OptSpecifier Id) const { + return getLastArg(Id) != 0; + } + bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { + return getLastArg(Id0, Id1) != 0; + } + bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { + return getLastArg(Id0, Id1, Id2) != 0; + } + + /// getLastArg - Return the last argument matching \p Id, or null. + /// + /// \p Claim Whether the argument should be claimed, if it exists. + Arg *getLastArgNoClaim(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, + OptSpecifier Id6) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, + OptSpecifier Id6, OptSpecifier Id7) const; + + /// getArgString - Return the input argument string at \p Index. + virtual const char *getArgString(unsigned Index) const = 0; + + /// getNumInputArgStrings - Return the number of original argument strings, + /// which are guaranteed to be the first strings in the argument string + /// list. + virtual unsigned getNumInputArgStrings() const = 0; + + /// @} + /// @name Argument Lookup Utilities + /// @{ + + /// getLastArgValue - Return the value of the last argument, or a default. + StringRef getLastArgValue(OptSpecifier Id, + StringRef Default = "") const; + + /// getAllArgValues - Get the values of all instances of the given argument + /// as strings. + std::vector<std::string> getAllArgValues(OptSpecifier Id) const; + + /// @} + /// @name Translation Utilities + /// @{ + + /// hasFlag - Given an option \p Pos and its negative form \p Neg, return + /// true if the option is present, false if the negation is present, and + /// \p Default if neither option is given. If both the option and its + /// negation are present, the last one wins. + bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; + + /// AddLastArg - Render only the last argument match \p Id0, if present. + void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; + + /// AddAllArgs - Render all arguments matching the given ids. + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; + + /// AddAllArgValues - Render the argument values of all arguments + /// matching the given ids. + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; + + /// AddAllArgsTranslated - Render all the arguments matching the + /// given ids, but forced to separate args and using the provided + /// name instead of the first option value. + /// + /// \param Joined - If true, render the argument as joined with + /// the option specifier. + void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, + const char *Translation, + bool Joined = false) const; + + /// ClaimAllArgs - Claim all arguments which match the given + /// option id. + void ClaimAllArgs(OptSpecifier Id0) const; + + /// ClaimAllArgs - Claim all arguments. + /// + void ClaimAllArgs() const; + + /// @} + /// @name Arg Synthesis + /// @{ + + /// MakeArgString - Construct a constant string pointer whose + /// lifetime will match that of the ArgList. + virtual const char *MakeArgString(StringRef Str) const = 0; + const char *MakeArgString(const char *Str) const { + return MakeArgString(StringRef(Str)); + } + const char *MakeArgString(std::string Str) const { + return MakeArgString(StringRef(Str)); + } + const char *MakeArgString(const Twine &Str) const; + + /// \brief Create an arg string for (\p LHS + \p RHS), reusing the + /// string at \p Index if possible. + const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, + StringRef RHS) const; + + /// @} +}; + +class InputArgList : public ArgList { +private: + /// List of argument strings used by the contained Args. + /// + /// This is mutable since we treat the ArgList as being the list + /// of Args, and allow routines to add new strings (to have a + /// convenient place to store the memory) via MakeIndex. + mutable ArgStringList ArgStrings; + + /// Strings for synthesized arguments. + /// + /// This is mutable since we treat the ArgList as being the list + /// of Args, and allow routines to add new strings (to have a + /// convenient place to store the memory) via MakeIndex. + mutable std::list<std::string> SynthesizedStrings; + + /// The number of original input argument strings. + unsigned NumInputArgStrings; + +public: + InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); + ~InputArgList(); + + virtual const char *getArgString(unsigned Index) const { + return ArgStrings[Index]; + } + + virtual unsigned getNumInputArgStrings() const { + return NumInputArgStrings; + } + + /// @name Arg Synthesis + /// @{ + +public: + /// MakeIndex - Get an index for the given string(s). + unsigned MakeIndex(StringRef String0) const; + unsigned MakeIndex(StringRef String0, StringRef String1) const; + + virtual const char *MakeArgString(StringRef Str) const; + + /// @} +}; + +/// DerivedArgList - An ordered collection of driver arguments, +/// whose storage may be in another argument list. +class DerivedArgList : public ArgList { + const InputArgList &BaseArgs; + + /// The list of arguments we synthesized. + mutable arglist_type SynthesizedArgs; + +public: + /// Construct a new derived arg list from \p BaseArgs. + DerivedArgList(const InputArgList &BaseArgs); + ~DerivedArgList(); + + virtual const char *getArgString(unsigned Index) const { + return BaseArgs.getArgString(Index); + } + + virtual unsigned getNumInputArgStrings() const { + return BaseArgs.getNumInputArgStrings(); + } + + const InputArgList &getBaseArgs() const { + return BaseArgs; + } + + /// @name Arg Synthesis + /// @{ + + /// AddSynthesizedArg - Add a argument to the list of synthesized arguments + /// (to be freed). + void AddSynthesizedArg(Arg *A) { + SynthesizedArgs.push_back(A); + } + + virtual const char *MakeArgString(StringRef Str) const; + + /// AddFlagArg - Construct a new FlagArg for the given option \p Id and + /// append it to the argument list. + void AddFlagArg(const Arg *BaseArg, const Option Opt) { + append(MakeFlagArg(BaseArg, Opt)); + } + + /// AddPositionalArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument + /// list. + void AddPositionalArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakePositionalArg(BaseArg, Opt, Value)); + } + + + /// AddSeparateArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument + /// list. + void AddSeparateArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakeSeparateArg(BaseArg, Opt, Value)); + } + + + /// AddJoinedArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument list. + void AddJoinedArg(const Arg *BaseArg, const Option Opt, + StringRef Value) { + append(MakeJoinedArg(BaseArg, Opt, Value)); + } + + + /// MakeFlagArg - Construct a new FlagArg for the given option \p Id. + Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; + + /// MakePositionalArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// MakeSeparateArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// MakeJoinedArg - Construct a new Positional arg for the + /// given option \p Id, with the provided \p Value. + Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, + StringRef Value) const; + + /// @} +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Option/OptParser.td b/contrib/llvm/include/llvm/Option/OptParser.td new file mode 100644 index 0000000..e781fa0 --- /dev/null +++ b/contrib/llvm/include/llvm/Option/OptParser.td @@ -0,0 +1,127 @@ +//===--- OptParser.td - Common Option Parsing Interfaces ------------------===// +// +// 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 common interfaces used by the option parsing TableGen +// backend. +// +//===----------------------------------------------------------------------===// + +// Define the kinds of options. + +class OptionKind<string name, int predecence = 0, bit sentinel = 0> { + string Name = name; + // The kind precedence, kinds with lower precedence are matched first. + int Precedence = predecence; + // Indicate a sentinel option. + bit Sentinel = sentinel; +} + +// An option group. +def KIND_GROUP : OptionKind<"Group">; +// The input option kind. +def KIND_INPUT : OptionKind<"Input", 1, 1>; +// The unknown option kind. +def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>; +// A flag with no values. +def KIND_FLAG : OptionKind<"Flag">; +// An option which prefixes its (single) value. +def KIND_JOINED : OptionKind<"Joined", 1>; +// An option which is followed by its value. +def KIND_SEPARATE : OptionKind<"Separate">; +// An option followed by its values, which are separated by commas. +def KIND_COMMAJOINED : OptionKind<"CommaJoined">; +// An option which is which takes multiple (separate) arguments. +def KIND_MULTIARG : OptionKind<"MultiArg">; +// An option which is either joined to its (non-empty) value, or followed by its +// value. +def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">; +// An option which is both joined to its (first) value, and followed by its +// (second) value. +def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">; + +// Define the option flags. + +class OptionFlag {} + +// HelpHidden - The option should not be displayed in --help, even if it has +// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp +// arguments to implement hidden help groups. +def HelpHidden : OptionFlag; + +// RenderAsInput - The option should not render the name when rendered as an +// input (i.e., the option is rendered as values). +def RenderAsInput : OptionFlag; + +// RenderJoined - The option should be rendered joined, even if separate (only +// sensible on single value separate options). +def RenderJoined : OptionFlag; + +// RenderSeparate - The option should be rendered separately, even if joined +// (only sensible on joined options). +def RenderSeparate : OptionFlag; + +// Define the option group class. + +class OptionGroup<string name> { + string EnumName = ?; // Uses the def name if undefined. + string Name = name; + string HelpText = ?; + OptionGroup Group = ?; +} + +// Define the option class. + +class Option<list<string> prefixes, string name, OptionKind kind> { + string EnumName = ?; // Uses the def name if undefined. + list<string> Prefixes = prefixes; + string Name = name; + OptionKind Kind = kind; + // Used by MultiArg option kind. + int NumArgs = 0; + string HelpText = ?; + string MetaVarName = ?; + list<OptionFlag> Flags = []; + OptionGroup Group = ?; + Option Alias = ?; +} + +// Helpers for defining options. + +class Flag<list<string> prefixes, string name> + : Option<prefixes, name, KIND_FLAG>; +class Joined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED>; +class Separate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_SEPARATE>; +class CommaJoined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_COMMAJOINED>; +class MultiArg<list<string> prefixes, string name, int numargs> + : Option<prefixes, name, KIND_MULTIARG> { + int NumArgs = numargs; +} +class JoinedOrSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>; +class JoinedAndSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>; + +// Mix-ins for adding optional attributes. + +class Alias<Option alias> { Option Alias = alias; } +class EnumName<string name> { string EnumName = name; } +class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } +class Group<OptionGroup group> { OptionGroup Group = group; } +class HelpText<string text> { string HelpText = text; } +class MetaVarName<string name> { string MetaVarName = name; } + +// Predefined options. + +// FIXME: Have generator validate that these appear in correct position (and +// aren't duplicated). +def INPUT : Option<[], "<input>", KIND_INPUT>; +def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>; diff --git a/contrib/llvm/include/llvm/Option/OptSpecifier.h b/contrib/llvm/include/llvm/Option/OptSpecifier.h new file mode 100644 index 0000000..02bc6b1 --- /dev/null +++ b/contrib/llvm/include/llvm/Option/OptSpecifier.h @@ -0,0 +1,39 @@ +//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPTION_OPTSPECIFIER_H +#define LLVM_OPTION_OPTSPECIFIER_H + +namespace llvm { +namespace opt { + class Option; + + /// OptSpecifier - Wrapper class for abstracting references to option IDs. + class OptSpecifier { + unsigned ID; + + private: + explicit OptSpecifier(bool) LLVM_DELETED_FUNCTION; + + public: + OptSpecifier() : ID(0) {} + /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} + /*implicit*/ OptSpecifier(const Option *Opt); + + bool isValid() const { return ID != 0; } + + unsigned getID() const { return ID; } + + bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } + bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } + }; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/Option/OptTable.h b/contrib/llvm/include/llvm/Option/OptTable.h new file mode 100644 index 0000000..a93acbf --- /dev/null +++ b/contrib/llvm/include/llvm/Option/OptTable.h @@ -0,0 +1,161 @@ +//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPTION_OPTTABLE_H +#define LLVM_OPTION_OPTTABLE_H + +#include "llvm/ADT/StringSet.h" +#include "llvm/Option/OptSpecifier.h" + +namespace llvm { +class raw_ostream; +namespace opt { +class Arg; +class ArgList; +class InputArgList; +class Option; + +/// \brief Provide access to the Option info table. +/// +/// The OptTable class provides a layer of indirection which allows Option +/// instance to be created lazily. In the common case, only a few options will +/// be needed at runtime; the OptTable class maintains enough information to +/// parse command lines without instantiating Options, while letting other +/// parts of the driver still use Option instances where convenient. +class OptTable { +public: + /// \brief Entry for a single option instance in the option data table. + struct Info { + /// A null terminated array of prefix strings to apply to name while + /// matching. + const char *const *Prefixes; + const char *Name; + const char *HelpText; + const char *MetaVar; + unsigned ID; + unsigned char Kind; + unsigned char Param; + unsigned short Flags; + unsigned short GroupID; + unsigned short AliasID; + }; + +private: + /// \brief The static option information table. + const Info *OptionInfos; + unsigned NumOptionInfos; + + unsigned TheInputOptionID; + unsigned TheUnknownOptionID; + + /// The index of the first option which can be parsed (i.e., is not a + /// special option like 'input' or 'unknown', and is not an option group). + unsigned FirstSearchableIndex; + + /// The union of all option prefixes. If an argument does not begin with + /// one of these, it is an input. + StringSet<> PrefixesUnion; + std::string PrefixChars; + +private: + const Info &getInfo(OptSpecifier Opt) const { + unsigned id = Opt.getID(); + assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID."); + return OptionInfos[id - 1]; + } + +protected: + OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); +public: + ~OptTable(); + + /// \brief Return the total number of option classes. + unsigned getNumOptions() const { return NumOptionInfos; } + + /// \brief Get the given Opt's Option instance, lazily creating it + /// if necessary. + /// + /// \return The option, or null for the INVALID option id. + const Option getOption(OptSpecifier Opt) const; + + /// \brief Lookup the name of the given option. + const char *getOptionName(OptSpecifier id) const { + return getInfo(id).Name; + } + + /// \brief Get the kind of the given option. + unsigned getOptionKind(OptSpecifier id) const { + return getInfo(id).Kind; + } + + /// \brief Get the group id for the given option. + unsigned getOptionGroupID(OptSpecifier id) const { + return getInfo(id).GroupID; + } + + /// \brief Should the help for the given option be hidden by default. + bool isOptionHelpHidden(OptSpecifier id) const; + + /// \brief Get the help text to use to describe this option. + const char *getOptionHelpText(OptSpecifier id) const { + return getInfo(id).HelpText; + } + + /// \brief Get the meta-variable name to use when describing + /// this options values in the help text. + const char *getOptionMetaVar(OptSpecifier id) const { + return getInfo(id).MetaVar; + } + + /// \brief Parse a single argument; returning the new argument and + /// updating Index. + /// + /// \param [in,out] Index - The current parsing position in the argument + /// string list; on return this will be the index of the next argument + /// string to parse. + /// + /// \return The parsed argument, or 0 if the argument is missing values + /// (in which case Index still points at the conceptual next argument string + /// to parse). + Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const; + + /// \brief Parse an list of arguments into an InputArgList. + /// + /// The resulting InputArgList will reference the strings in [\p ArgBegin, + /// \p ArgEnd), and their lifetime should extend past that of the returned + /// InputArgList. + /// + /// The only error that can occur in this routine is if an argument is + /// missing values; in this case \p MissingArgCount will be non-zero. + /// + /// \param ArgBegin - The beginning of the argument vector. + /// \param ArgEnd - The end of the argument vector. + /// \param MissingArgIndex - On error, the index of the option which could + /// not be parsed. + /// \param MissingArgCount - On error, the number of missing options. + /// \return An InputArgList; on error this will contain all the options + /// which could be parsed. + InputArgList *ParseArgs(const char* const *ArgBegin, + const char* const *ArgEnd, + unsigned &MissingArgIndex, + unsigned &MissingArgCount) const; + + /// \brief Render the help text for an option table. + /// + /// \param OS - The stream to write the help text to. + /// \param Name - The name to use in the usage line. + /// \param Title - The title to use in the usage line. + /// \param ShowHidden - Whether help-hidden arguments should be shown. + void PrintHelp(raw_ostream &OS, const char *Name, + const char *Title, bool ShowHidden = false) const; +}; +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Option/Option.h b/contrib/llvm/include/llvm/Option/Option.h new file mode 100644 index 0000000..541aa8d --- /dev/null +++ b/contrib/llvm/include/llvm/Option/Option.h @@ -0,0 +1,193 @@ +//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPTION_OPTION_H +#define LLVM_OPTION_OPTION_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/OptTable.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { +namespace opt { +class Arg; +class ArgList; +/// ArgStringList - Type used for constructing argv lists for subprocesses. +typedef SmallVector<const char*, 16> ArgStringList; + +/// Base flags for all options. Custom flags may be added after. +enum DriverFlag { + HelpHidden = (1 << 0), + RenderAsInput = (1 << 1), + RenderJoined = (1 << 2), + RenderSeparate = (1 << 3) +}; + +/// Option - Abstract representation for a single form of driver +/// argument. +/// +/// An Option class represents a form of option that the driver +/// takes, for example how many arguments the option has and how +/// they can be provided. Individual option instances store +/// additional information about what group the option is a member +/// of (if any), if the option is an alias, and a number of +/// flags. At runtime the driver parses the command line into +/// concrete Arg instances, each of which corresponds to a +/// particular Option instance. +class Option { +public: + enum OptionClass { + GroupClass = 0, + InputClass, + UnknownClass, + FlagClass, + JoinedClass, + SeparateClass, + CommaJoinedClass, + MultiArgClass, + JoinedOrSeparateClass, + JoinedAndSeparateClass + }; + + enum RenderStyleKind { + RenderCommaJoinedStyle, + RenderJoinedStyle, + RenderSeparateStyle, + RenderValuesStyle + }; + +protected: + const OptTable::Info *Info; + const OptTable *Owner; + +public: + Option(const OptTable::Info *Info, const OptTable *Owner); + ~Option(); + + bool isValid() const { + return Info != 0; + } + + unsigned getID() const { + assert(Info && "Must have a valid info!"); + return Info->ID; + } + + OptionClass getKind() const { + assert(Info && "Must have a valid info!"); + return OptionClass(Info->Kind); + } + + /// \brief Get the name of this option without any prefix. + StringRef getName() const { + assert(Info && "Must have a valid info!"); + return Info->Name; + } + + const Option getGroup() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->GroupID); + } + + const Option getAlias() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->AliasID); + } + + /// \brief Get the default prefix for this option. + StringRef getPrefix() const { + const char *Prefix = *Info->Prefixes; + return Prefix ? Prefix : StringRef(); + } + + /// \brief Get the name of this option with the default prefix. + std::string getPrefixedName() const { + std::string Ret = getPrefix(); + Ret += getName(); + return Ret; + } + + unsigned getNumArgs() const { return Info->Param; } + + bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} + + RenderStyleKind getRenderStyle() const { + if (Info->Flags & RenderJoined) + return RenderJoinedStyle; + if (Info->Flags & RenderSeparate) + return RenderSeparateStyle; + switch (getKind()) { + case GroupClass: + case InputClass: + case UnknownClass: + return RenderValuesStyle; + case JoinedClass: + case JoinedAndSeparateClass: + return RenderJoinedStyle; + case CommaJoinedClass: + return RenderCommaJoinedStyle; + case FlagClass: + case SeparateClass: + case MultiArgClass: + case JoinedOrSeparateClass: + return RenderSeparateStyle; + } + llvm_unreachable("Unexpected kind!"); + } + + /// Test if this option has the flag \a Val. + bool hasFlag(unsigned Val) const { + return Info->Flags & Val; + } + + /// getUnaliasedOption - Return the final option this option + /// aliases (itself, if the option has no alias). + const Option getUnaliasedOption() const { + const Option Alias = getAlias(); + if (Alias.isValid()) return Alias.getUnaliasedOption(); + return *this; + } + + /// getRenderName - Return the name to use when rendering this + /// option. + StringRef getRenderName() const { + return getUnaliasedOption().getName(); + } + + /// matches - Predicate for whether this option is part of the + /// given option (which may be a group). + /// + /// Note that matches against options which are an alias should never be + /// done -- aliases do not participate in matching and so such a query will + /// always be false. + bool matches(OptSpecifier ID) const; + + /// accept - Potentially accept the current argument, returning a + /// new Arg instance, or 0 if the option does not accept this + /// argument (or the argument is missing values). + /// + /// If the option accepts the current argument, accept() sets + /// Index to the position where argument parsing should resume + /// (even if the argument is missing values). + /// + /// \parm ArgSize The number of bytes taken up by the matched Option prefix + /// and name. This is used to determine where joined values + /// start. + Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; + + void dump() const; +}; + +} // end namespace opt +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Pass.h b/contrib/llvm/include/llvm/Pass.h index cd651db..35ec022 100644 --- a/contrib/llvm/include/llvm/Pass.h +++ b/contrib/llvm/include/llvm/Pass.h @@ -104,6 +104,16 @@ public: return PassID; } + /// doInitialization - Virtual method overridden by subclasses to do + /// any necessary initialization before any pass is run. + /// + virtual bool doInitialization(Module &) { return false; } + + /// doFinalization - Virtual method overriden by subclasses to do any + /// necessary clean up after all passes have run. + /// + virtual bool doFinalization(Module &) { return false; } + /// print - Print out the internal state of the pass. This is called by /// Analyze to print out the contents of an analysis. Otherwise it is not /// necessary to implement this method. Beware that the module pointer MAY be @@ -287,21 +297,11 @@ public: /// createPrinterPass - Get a function printer pass. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; - /// doInitialization - Virtual method overridden by subclasses to do - /// any necessary per-module initialization. - /// - virtual bool doInitialization(Module &); - /// runOnFunction - Virtual method overriden by subclasses to do the /// per-function processing of the pass. /// virtual bool runOnFunction(Function &F) = 0; - /// doFinalization - Virtual method overriden by subclasses to do any post - /// processing needed after all passes have run. - /// - virtual bool doFinalization(Module &); - virtual void assignPassManager(PMStack &PMS, PassManagerType T); @@ -328,10 +328,8 @@ public: /// 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 - /// any necessary per-module initialization. - /// - virtual bool doInitialization(Module &); + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; /// doInitialization - Virtual method overridden by BasicBlockPass subclasses /// to do any necessary per-function initialization. @@ -348,11 +346,6 @@ public: /// virtual bool doFinalization(Function &); - /// doFinalization - Virtual method overriden by subclasses to do any post - /// processing needed after all passes have run. - /// - virtual bool doFinalization(Module &); - virtual void assignPassManager(PMStack &PMS, PassManagerType T); diff --git a/contrib/llvm/include/llvm/PassAnalysisSupport.h b/contrib/llvm/include/llvm/PassAnalysisSupport.h index d14d73b..a581802 100644 --- a/contrib/llvm/include/llvm/PassAnalysisSupport.h +++ b/contrib/llvm/include/llvm/PassAnalysisSupport.h @@ -16,12 +16,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H -#define LLVM_PASS_ANALYSIS_SUPPORT_H +#ifndef LLVM_PASSANALYSISSUPPORT_H +#define LLVM_PASSANALYSISSUPPORT_H -#include "llvm/Pass.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Pass.h" #include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/PassManagers.h b/contrib/llvm/include/llvm/PassManagers.h index 0af5853..7afb0a0 100644 --- a/contrib/llvm/include/llvm/PassManagers.h +++ b/contrib/llvm/include/llvm/PassManagers.h @@ -14,13 +14,13 @@ #ifndef LLVM_PASSMANAGERS_H #define LLVM_PASSMANAGERS_H -#include "llvm/Pass.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/DenseMap.h" -#include <vector> +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Pass.h" #include <map> +#include <vector> //===----------------------------------------------------------------------===// // Overview: @@ -168,7 +168,7 @@ class PMTopLevelManager { protected: explicit PMTopLevelManager(PMDataManager *PMDM); - virtual unsigned getNumContainedManagers() const { + unsigned getNumContainedManagers() const { return (unsigned)PassManagers.size(); } @@ -343,7 +343,7 @@ public: void dumpRequiredSet(const Pass *P) const; void dumpPreservedSet(const Pass *P) const; - virtual unsigned getNumContainedPasses() const { + unsigned getNumContainedPasses() const { return (unsigned)PassVector.size(); } @@ -352,7 +352,7 @@ public: return PMT_Unknown; } - std::map<AnalysisID, Pass*> *getAvailableAnalysis() { + DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() { return &AvailableAnalysis; } @@ -375,8 +375,7 @@ protected: // Collection of Analysis provided by Parent pass manager and // used by current pass manager. At at time there can not be more // then PMT_Last active pass mangers. - std::map<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; - + DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions /// or higher is specified. @@ -390,7 +389,7 @@ private: // pass. If a pass requires an analysis which is not available then // the required analysis pass is scheduled to run before the pass itself is // scheduled to run. - std::map<AnalysisID, Pass*> AvailableAnalysis; + DenseMap<AnalysisID, Pass*> AvailableAnalysis; // Collection of higher level analysis used by the pass managed by // this manager. @@ -420,10 +419,20 @@ public: /// cleanup - After running all passes, clean up pass manager cache. void cleanup(); + /// doInitialization - Overrides ModulePass doInitialization for global + /// initialization tasks + /// + using ModulePass::doInitialization; + /// doInitialization - Run all of the initializers for the function passes. /// bool doInitialization(Module &M); + /// doFinalization - Overrides ModulePass doFinalization for global + /// finalization tasks + /// + using ModulePass::doFinalization; + /// doFinalization - Run all of the finalizers for the function passes. /// bool doFinalization(Module &M); diff --git a/contrib/llvm/include/llvm/PassSupport.h b/contrib/llvm/include/llvm/PassSupport.h index c6ad44f..ccc7934 100644 --- a/contrib/llvm/include/llvm/PassSupport.h +++ b/contrib/llvm/include/llvm/PassSupport.h @@ -18,12 +18,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_PASS_SUPPORT_H -#define LLVM_PASS_SUPPORT_H +#ifndef LLVM_PASSSUPPORT_H +#define LLVM_PASSSUPPORT_H #include "Pass.h" -#include "llvm/PassRegistry.h" #include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" #include "llvm/Support/Atomic.h" #include "llvm/Support/Valgrind.h" #include <vector> @@ -305,7 +305,7 @@ struct RegisterAnalysisGroup : public RegisterAGBase { /// clients that are interested in which passes get registered and unregistered /// at runtime (which can be because of the RegisterPass constructors being run /// as the program starts up, or may be because a shared object just got -/// loaded). Deriving from the PassRegistationListener class automatically +/// loaded). Deriving from the PassRegistrationListener class automatically /// registers your object to receive callbacks indicating when passes are loaded /// and removed. /// diff --git a/contrib/llvm/include/llvm/Support/AlignOf.h b/contrib/llvm/include/llvm/Support/AlignOf.h index d6b0ab8..bba3424 100644 --- a/contrib/llvm/include/llvm/Support/AlignOf.h +++ b/contrib/llvm/include/llvm/Support/AlignOf.h @@ -19,7 +19,6 @@ #include <cstddef> namespace llvm { - template <typename T> struct AlignmentCalcImpl { char x; @@ -49,7 +48,6 @@ struct AlignOf { enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; - }; /// alignOf - A templated function that returns the minimum alignment of @@ -59,112 +57,148 @@ struct AlignOf { template <typename T> inline unsigned alignOf() { return AlignOf<T>::Alignment; } - +/// \struct AlignedCharArray /// \brief Helper for building an aligned character array type. /// /// This template is used to explicitly build up a collection of aligned -/// character types. We have to build these up using a macro and explicit +/// character array types. We have to build these up using a macro and explicit /// specialization to cope with old versions of MSVC and GCC where only an /// integer literal can be used to specify an alignment constraint. Once built /// up here, we can then begin to indirect between these using normal C++ /// template parameters. -template <size_t Alignment> struct AlignedCharArrayImpl; // MSVC requires special handling here. #ifndef _MSC_VER #if __has_feature(cxx_alignas) -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template <> struct AlignedCharArrayImpl<x> { \ - char alignas(x) aligned; \ - } +template<std::size_t Alignment, std::size_t Size> +struct AlignedCharArray { + alignas(Alignment) char buffer[Size]; +}; + #elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) +/// \brief Create a type with an aligned char buffer. +template<std::size_t Alignment, std::size_t Size> +struct AlignedCharArray; + #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template <> struct AlignedCharArrayImpl<x> { \ - char aligned __attribute__((aligned(x))); \ - } -#else -# error No supported align as directive. -#endif + template<std::size_t Size> \ + struct AlignedCharArray<x, Size> { \ + __attribute__((aligned(x))) char buffer[Size]; \ + }; -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT +#else +# error No supported align as directive. +#endif + #else // _MSC_VER +/// \brief Create a type with an aligned char buffer. +template<std::size_t Alignment, std::size_t Size> +struct AlignedCharArray; + // We provide special variations of this template for the most common // alignments because __declspec(align(...)) doesn't actually work when it is // a member of a by-value function argument in MSVC, even if the alignment -// request is something reasonably like 8-byte or 16-byte. -template <> struct AlignedCharArrayImpl<1> { char aligned; }; -template <> struct AlignedCharArrayImpl<2> { short aligned; }; -template <> struct AlignedCharArrayImpl<4> { int aligned; }; -template <> struct AlignedCharArrayImpl<8> { double aligned; }; +// request is something reasonably like 8-byte or 16-byte. Note that we can't +// even include the declspec with the union that forces the alignment because +// MSVC warns on the existence of the declspec despite the union member forcing +// proper alignment. + +template<std::size_t Size> +struct AlignedCharArray<1, Size> { + union { + char aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<2, Size> { + union { + short aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<4, Size> { + union { + int aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<8, Size> { + union { + double aligned; + char buffer[Size]; + }; +}; + + +// The rest of these are provided with a __declspec(align(...)) and we simply +// can't pass them by-value as function arguments on MSVC. #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template <> struct AlignedCharArrayImpl<x> { \ - __declspec(align(x)) char aligned; \ - } -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); -// Any larger and MSVC complains. + template<std::size_t Size> \ + struct AlignedCharArray<x, Size> { \ + __declspec(align(x)) char buffer[Size]; \ + }; + +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) + #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT #endif // _MSC_VER +namespace detail { +template <typename T1, + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char> +class AlignerImpl { + T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; + + AlignerImpl(); // Never defined or instantiated. +}; + +template <typename T1, + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char> +union SizerImpl { + char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)], + arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)]; +}; +} // end namespace detail + /// \brief This union template exposes a suitably aligned and sized character /// array member which can hold elements of any of up to four types. /// /// These types may be arrays, structs, or any other types. The goal is to -/// produce a union type containing a character array which, when used, forms -/// storage suitable to placement new any of these types over. Support for more -/// than four types can be added at the cost of more boiler plate. +/// expose a char array buffer member which can be used as suitable storage for +/// a placement new of any of these types. Support for more than seven types can +/// be added at the cost of more boiler plate. template <typename T1, - typename T2 = char, typename T3 = char, typename T4 = char> -union AlignedCharArrayUnion { -private: - class AlignerImpl { - T1 t1; T2 t2; T3 t3; T4 t4; - - AlignerImpl(); // Never defined or instantiated. - }; - union SizerImpl { - char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)]; - }; - -public: - /// \brief The character array buffer for use by clients. - /// - /// No other member of this union should be referenced. The exist purely to - /// constrain the layout of this character array. - char buffer[sizeof(SizerImpl)]; - -private: - // Tests seem to indicate that both Clang and GCC will properly register the - // alignment of a struct containing an aligned member, and this alignment - // should carry over to the character array in the union. - llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> nonce_member; + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char> +struct AlignedCharArrayUnion : llvm::AlignedCharArray< + AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment, + sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> { }; - } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/Allocator.h b/contrib/llvm/include/llvm/Support/Allocator.h index a644b13..3243fd9 100644 --- a/contrib/llvm/include/llvm/Support/Allocator.h +++ b/contrib/llvm/include/llvm/Support/Allocator.h @@ -15,12 +15,12 @@ #define LLVM_SUPPORT_ALLOCATOR_H #include "llvm/Support/AlignOf.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/MathExtras.h" #include <algorithm> #include <cassert> -#include <cstdlib> #include <cstddef> +#include <cstdlib> namespace llvm { template <typename T> struct ReferenceAdder { typedef T& result; }; diff --git a/contrib/llvm/include/llvm/Support/ArrayRecycler.h b/contrib/llvm/include/llvm/Support/ArrayRecycler.h new file mode 100644 index 0000000..c7e0cba --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ArrayRecycler.h @@ -0,0 +1,143 @@ +//==- llvm/Support/ArrayRecycler.h - Recycling of Arrays ---------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ArrayRecycler class template which can recycle small +// arrays allocated from one of the allocators in Allocator.h +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARRAYRECYCLER_H +#define LLVM_SUPPORT_ARRAYRECYCLER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/MathExtras.h" + +namespace llvm { + +class BumpPtrAllocator; + +/// Recycle small arrays allocated from a BumpPtrAllocator. +/// +/// Arrays are allocated in a small number of fixed sizes. For each supported +/// array size, the ArrayRecycler keeps a free list of available arrays. +/// +template<class T, size_t Align = AlignOf<T>::Alignment> +class ArrayRecycler { + // The free list for a given array size is a simple singly linked list. + // We can't use iplist or Recycler here since those classes can't be copied. + struct FreeList { + FreeList *Next; + }; + + // Keep a free list for each array size. + SmallVector<FreeList*, 8> Bucket; + + // Remove an entry from the free list in Bucket[Idx] and return it. + // Return NULL if no entries are available. + T *pop(unsigned Idx) { + if (Idx >= Bucket.size()) + return 0; + FreeList *Entry = Bucket[Idx]; + if (!Entry) + return 0; + Bucket[Idx] = Entry->Next; + return reinterpret_cast<T*>(Entry); + } + + // Add an entry to the free list at Bucket[Idx]. + void push(unsigned Idx, T *Ptr) { + assert(Ptr && "Cannot recycle NULL pointer"); + assert(sizeof(T) >= sizeof(FreeList) && "Objects are too small"); + assert(Align >= AlignOf<FreeList>::Alignment && "Object underaligned"); + FreeList *Entry = reinterpret_cast<FreeList*>(Ptr); + if (Idx >= Bucket.size()) + Bucket.resize(size_t(Idx) + 1); + Entry->Next = Bucket[Idx]; + Bucket[Idx] = Entry; + } + +public: + /// The size of an allocated array is represented by a Capacity instance. + /// + /// This class is much smaller than a size_t, and it provides methods to work + /// with the set of legal array capacities. + class Capacity { + uint8_t Index; + explicit Capacity(uint8_t idx) : Index(idx) {} + + public: + Capacity() : Index(0) {} + + /// Get the capacity of an array that can hold at least N elements. + static Capacity get(size_t N) { + return Capacity(N ? Log2_64_Ceil(N) : 0); + } + + /// Get the number of elements in an array with this capacity. + size_t getSize() const { return size_t(1u) << Index; } + + /// Get the bucket number for this capacity. + unsigned getBucket() const { return Index; } + + /// Get the next larger capacity. Large capacities grow exponentially, so + /// this function can be used to reallocate incrementally growing vectors + /// in amortized linear time. + Capacity getNext() const { return Capacity(Index + 1); } + }; + + ~ArrayRecycler() { + // The client should always call clear() so recycled arrays can be returned + // to the allocator. + assert(Bucket.empty() && "Non-empty ArrayRecycler deleted!"); + } + + /// Release all the tracked allocations to the allocator. The recycler must + /// be free of any tracked allocations before being deleted. + template<class AllocatorType> + void clear(AllocatorType &Allocator) { + for (; !Bucket.empty(); Bucket.pop_back()) + while (T *Ptr = pop(Bucket.size() - 1)) + Allocator.Deallocate(Ptr); + } + + /// Special case for BumpPtrAllocator which has an empty Deallocate() + /// function. + /// + /// There is no need to traverse the free lists, pulling all the objects into + /// cache. + void clear(BumpPtrAllocator&) { + Bucket.clear(); + } + + /// Allocate an array of at least the requested capacity. + /// + /// Return an existing recycled array, or allocate one from Allocator if + /// none are available for recycling. + /// + template<class AllocatorType> + T *allocate(Capacity Cap, AllocatorType &Allocator) { + // Try to recycle an existing array. + if (T *Ptr = pop(Cap.getBucket())) + return Ptr; + // Nope, get more memory. + return static_cast<T*>(Allocator.Allocate(sizeof(T)*Cap.getSize(), Align)); + } + + /// Deallocate an array with the specified Capacity. + /// + /// Cap must be the same capacity that was given to allocate(). + /// + void deallocate(Capacity Cap, T *Ptr) { + push(Cap.getBucket(), Ptr); + } +}; + +} // end llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/Support/Atomic.h b/contrib/llvm/include/llvm/Support/Atomic.h index 1a6c606..9ec23e8 100644 --- a/contrib/llvm/include/llvm/Support/Atomic.h +++ b/contrib/llvm/include/llvm/Support/Atomic.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_ATOMIC_H -#define LLVM_SYSTEM_ATOMIC_H +#ifndef LLVM_SUPPORT_ATOMIC_H +#define LLVM_SUPPORT_ATOMIC_H #include "llvm/Support/DataTypes.h" diff --git a/contrib/llvm/include/llvm/Support/CFG.h b/contrib/llvm/include/llvm/Support/CFG.h index f5dc8ea..265b886 100644 --- a/contrib/llvm/include/llvm/Support/CFG.h +++ b/contrib/llvm/include/llvm/Support/CFG.h @@ -16,8 +16,8 @@ #define LLVM_SUPPORT_CFG_H #include "llvm/ADT/GraphTraits.h" -#include "llvm/Function.h" -#include "llvm/InstrTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstrTypes.h" namespace llvm { @@ -27,8 +27,9 @@ namespace llvm { template <class Ptr, class USE_iterator> // Predecessor Iterator class PredIterator : public std::iterator<std::forward_iterator_tag, - Ptr, ptrdiff_t> { - typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super; + Ptr, ptrdiff_t, Ptr*, Ptr*> { + typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, + Ptr*> super; typedef PredIterator<Ptr, USE_iterator> Self; USE_iterator It; @@ -40,6 +41,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag, public: typedef typename super::pointer pointer; + typedef typename super::reference reference; PredIterator() {} explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { @@ -50,7 +52,7 @@ public: inline bool operator==(const Self& x) const { return It == x.It; } inline bool operator!=(const Self& x) const { return !operator==(x); } - inline pointer operator*() const { + inline reference operator*() const { assert(!It.atEnd() && "pred_iterator out of range!"); return cast<TerminatorInst>(*It)->getParent(); } @@ -100,10 +102,11 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) { template <class Term_, class BB_> // Successor Iterator class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, - BB_, ptrdiff_t> { + BB_, ptrdiff_t, BB_*, BB_*> { const Term_ Term; unsigned idx; - typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super; + typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*, + BB_*> super; typedef SuccIterator<Term_, BB_> Self; inline bool index_is_valid(int idx) { @@ -112,6 +115,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, public: typedef typename super::pointer pointer; + typedef typename super::reference reference; // TODO: This can be random access iterator, only operator[] missing. explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator @@ -142,7 +146,7 @@ public: inline bool operator==(const Self& x) const { return idx == x.idx; } inline bool operator!=(const Self& x) const { return !operator==(x); } - inline pointer operator*() const { return Term->getSuccessor(idx); } + inline reference operator*() const { return Term->getSuccessor(idx); } inline pointer operator->() const { return operator*(); } inline Self& operator++() { ++idx; return *this; } // Preincrement diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h index ba8adb0..823b43a 100644 --- a/contrib/llvm/include/llvm/Support/COFF.h +++ b/contrib/llvm/include/llvm/Support/COFF.h @@ -20,8 +20,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_WIN_COFF_H -#define LLVM_SUPPORT_WIN_COFF_H +#ifndef LLVM_SUPPORT_COFF_H +#define LLVM_SUPPORT_COFF_H #include "llvm/Support/DataTypes.h" #include <cassert> @@ -321,7 +321,8 @@ namespace COFF { IMAGE_COMDAT_SELECT_SAME_SIZE, IMAGE_COMDAT_SELECT_EXACT_MATCH, IMAGE_COMDAT_SELECT_ASSOCIATIVE, - IMAGE_COMDAT_SELECT_LARGEST + IMAGE_COMDAT_SELECT_LARGEST, + IMAGE_COMDAT_SELECT_NEWEST }; // Auxiliary Symbol Formats diff --git a/contrib/llvm/include/llvm/Support/CallSite.h b/contrib/llvm/include/llvm/Support/CallSite.h index ad8d6d4..92107ac 100644 --- a/contrib/llvm/include/llvm/Support/CallSite.h +++ b/contrib/llvm/include/llvm/Support/CallSite.h @@ -26,11 +26,10 @@ #ifndef LLVM_SUPPORT_CALLSITE_H #define LLVM_SUPPORT_CALLSITE_H -#include "llvm/Attributes.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/BasicBlock.h" -#include "llvm/CallingConv.h" -#include "llvm/Instructions.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Instructions.h" namespace llvm { @@ -177,20 +176,20 @@ public: /// getAttributes/setAttributes - get or set the parameter attributes of /// the call. - const AttrListPtr &getAttributes() const { + const AttributeSet &getAttributes() const { CALLSITE_DELEGATE_GETTER(getAttributes()); } - void setAttributes(const AttrListPtr &PAL) { + void setAttributes(const AttributeSet &PAL) { CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); } /// \brief Return true if this function has the given attribute. - bool hasFnAttr(Attributes::AttrVal A) const { + bool hasFnAttr(Attribute::AttrKind A) const { CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); } /// \brief Return true if the call or the callee has the given attribute. - bool paramHasAttr(unsigned i, Attributes::AttrVal A) const { + bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); } @@ -244,12 +243,12 @@ public: /// @brief Determine whether this argument is not captured. bool doesNotCapture(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attributes::NoCapture); + return paramHasAttr(ArgNo + 1, Attribute::NoCapture); } /// @brief Determine whether this argument is passed by value. bool isByValArgument(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attributes::ByVal); + return paramHasAttr(ArgNo + 1, Attribute::ByVal); } /// hasArgument - Returns true if this CallSite passes the given Value* as an diff --git a/contrib/llvm/include/llvm/Support/Casting.h b/contrib/llvm/include/llvm/Support/Casting.h index 0c71882..0d2d6c9 100644 --- a/contrib/llvm/include/llvm/Support/Casting.h +++ b/contrib/llvm/include/llvm/Support/Casting.h @@ -36,9 +36,13 @@ template<typename From> struct simplify_type { }; template<typename From> struct simplify_type<const From> { - typedef const From SimpleType; - static SimpleType &getSimplifiedValue(const From &Val) { - return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val)); + typedef typename simplify_type<From>::SimpleType NonConstSimpleType; + typedef typename add_const_past_pointer<NonConstSimpleType>::type + SimpleType; + typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type + RetType; + static RetType getSimplifiedValue(const From& Val) { + return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); } }; @@ -55,8 +59,8 @@ struct isa_impl { /// \brief Always allow upcasts, and perform no dynamic check for them. template <typename To, typename From> struct isa_impl<To, From, - typename llvm::enable_if_c< - llvm::is_base_of<To, From>::value + typename enable_if< + llvm::is_base_of<To, From> >::type > { static inline bool doit(const From &) { return true; } @@ -81,6 +85,13 @@ template <typename To, typename From> struct isa_impl_cl<To, From*> { } }; +template <typename To, typename From> struct isa_impl_cl<To, From*const> { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl<To, From>::doit(*Val); + } +}; + template <typename To, typename From> struct isa_impl_cl<To, const From*> { static inline bool doit(const From *Val) { assert(Val && "isa<> used on a null pointer"); @@ -102,7 +113,7 @@ struct isa_impl_wrap { static bool doit(const From &Val) { return isa_impl_wrap<To, SimpleFrom, typename simplify_type<SimpleFrom>::SimpleType>::doit( - simplify_type<From>::getSimplifiedValue(Val)); + simplify_type<const From>::getSimplifiedValue(Val)); } }; @@ -121,7 +132,8 @@ struct isa_impl_wrap<To, FromTy, FromTy> { // template <class X, class Y> inline bool isa(const Y &Val) { - return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val); + return isa_impl_wrap<X, const Y, + typename simplify_type<const Y>::SimpleType>::doit(Val); } //===----------------------------------------------------------------------===// @@ -178,7 +190,7 @@ struct cast_retty { // template<class To, class From, class SimpleFrom> struct cast_convert_val { // This is not a simple type, use the template to simplify it... - static typename cast_retty<To, From>::ret_type doit(const From &Val) { + static typename cast_retty<To, From>::ret_type doit(From &Val) { return cast_convert_val<To, SimpleFrom, typename simplify_type<SimpleFrom>::SimpleType>::doit( simplify_type<From>::getSimplifiedValue(Val)); @@ -204,12 +216,29 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { // cast<Instruction>(myVal)->getParent() // template <class X, class Y> -inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) { +inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) { + assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); + return cast_convert_val<X, const Y, + typename simplify_type<const Y>::SimpleType>::doit(Val); +} + +template <class X, class Y> +inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); return cast_convert_val<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val); } +template <class X, class Y> +inline typename enable_if< + is_same<Y, typename simplify_type<Y>::SimpleType>, + typename cast_retty<X, Y*>::ret_type +>::type cast(Y *Val) { + assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); + return cast_convert_val<X, Y*, + typename simplify_type<Y*>::SimpleType>::doit(Val); +} + // cast_or_null<X> - Functionally identical to cast, except that a null value is // accepted. // @@ -230,8 +259,21 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { // template <class X, class Y> -inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) { - return isa<X>(Val) ? cast<X, Y>(Val) : 0; +inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) { + return isa<X>(Val) ? cast<X>(Val) : 0; +} + +template <class X, class Y> +inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { + return isa<X>(Val) ? cast<X>(Val) : 0; +} + +template <class X, class Y> +inline typename enable_if< + is_same<Y, typename simplify_type<Y>::SimpleType>, + typename cast_retty<X, Y*>::ret_type +>::type dyn_cast(Y *Val) { + return isa<X>(Val) ? cast<X>(Val) : 0; } // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h index 872c579..2e84d7b 100644 --- a/contrib/llvm/include/llvm/Support/CommandLine.h +++ b/contrib/llvm/include/llvm/Support/CommandLine.h @@ -20,10 +20,10 @@ #ifndef LLVM_SUPPORT_COMMANDLINE_H #define LLVM_SUPPORT_COMMANDLINE_H -#include "llvm/Support/type_traits.h" -#include "llvm/Support/Compiler.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/type_traits.h" #include <cassert> #include <climits> #include <cstdarg> @@ -469,8 +469,7 @@ public: template<class Opt> void apply(Opt &O) const { - for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); - i != e; ++i) + for (size_t i = 0, e = Values.size(); i != e; ++i) O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, Values[i].second.second); } @@ -629,8 +628,7 @@ public: else ArgVal = ArgName; - for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); - i != e; ++i) + for (size_t i = 0, e = Values.size(); i != e; ++i) if (Values[i].Name == ArgVal) { V = Values[i].V.getValue(); return false; @@ -1092,7 +1090,7 @@ public: // Make sure we initialize the value with the default constructor for the // type. - opt_storage() : Value(DataType()) {} + opt_storage() : Value(DataType()), Default(DataType()) {} template<class T> void setValue(const T &V, bool initial = false) { diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h index 7ceeb32..13d057b 100644 --- a/contrib/llvm/include/llvm/Support/Compiler.h +++ b/contrib/llvm/include/llvm/Support/Compiler.h @@ -15,29 +15,90 @@ #ifndef LLVM_SUPPORT_COMPILER_H #define LLVM_SUPPORT_COMPILER_H +#include "llvm/Config/llvm-config.h" + #ifndef __has_feature # define __has_feature(x) 0 #endif -/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references? +/// \brief Does the compiler support r-value references? /// This implies that <utility> provides the one-argument std::move; it /// does not imply the existence of any other C++ library features. #if (__has_feature(cxx_rvalue_references) \ || defined(__GXX_EXPERIMENTAL_CXX0X__) \ || (defined(_MSC_VER) && _MSC_VER >= 1600)) -#define LLVM_USE_RVALUE_REFERENCES 1 +#define LLVM_HAS_RVALUE_REFERENCES 1 +#else +#define LLVM_HAS_RVALUE_REFERENCES 0 +#endif + +/// \brief Does the compiler support r-value reference *this? +/// +/// Sadly, this is separate from just r-value reference support because GCC +/// implemented everything but this thus far. No release of GCC yet has support +/// for this feature so it is enabled with Clang only. +/// FIXME: This should change to a version check when GCC grows support for it. +#if __has_feature(cxx_rvalue_references) +#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 +#else +#define LLVM_HAS_RVALUE_REFERENCE_THIS 0 +#endif + +/// \macro LLVM_HAS_CXX11_TYPETRAITS +/// \brief Does the compiler have the C++11 type traits. +/// +/// #include <type_traits> +/// +/// * enable_if +/// * {true,false}_type +/// * is_constructible +/// * etc... +#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ + || (defined(_MSC_VER) && _MSC_VER >= 1700) +#define LLVM_HAS_CXX11_TYPETRAITS 1 +#else +#define LLVM_HAS_CXX11_TYPETRAITS 0 +#endif + +/// \macro LLVM_HAS_CXX11_STDLIB +/// \brief Does the compiler have the C++11 standard library. +/// +/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS +#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ + || (defined(_MSC_VER) && _MSC_VER >= 1700) +#define LLVM_HAS_CXX11_STDLIB 1 #else -#define LLVM_USE_RVALUE_REFERENCES 0 +#define LLVM_HAS_CXX11_STDLIB 0 +#endif + +/// \macro LLVM_HAS_VARIADIC_TEMPLATES +/// \brief Does this compiler support variadic templates. +/// +/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward. +#if __has_feature(cxx_variadic_templates) +# define LLVM_HAS_VARIADIC_TEMPLATES 1 +#else +# define LLVM_HAS_VARIADIC_TEMPLATES 0 #endif /// llvm_move - Expands to ::std::move if the compiler supports /// r-value references; otherwise, expands to the argument. -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES #define llvm_move(value) (::std::move(value)) #else #define llvm_move(value) (value) #endif +/// Expands to '&' if r-value references are supported. +/// +/// This can be used to provide l-value/r-value overrides of member functions. +/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS +#if LLVM_HAS_RVALUE_REFERENCE_THIS +#define LLVM_LVALUE_FUNCTION & +#else +#define LLVM_LVALUE_FUNCTION +#endif + /// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it. /// Use to mark functions as uncallable. Member functions with this should /// be declared private so that some behavior is kept in C++03 mode. @@ -59,7 +120,8 @@ /// LLVM_FINAL - Expands to 'final' if the compiler supports it. /// Use to mark classes or virtual methods as final. -#if (__has_feature(cxx_override_control)) +#if __has_feature(cxx_override_control) \ + || (defined(_MSC_VER) && _MSC_VER >= 1700) #define LLVM_FINAL final #else #define LLVM_FINAL @@ -67,12 +129,19 @@ /// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it. /// Use to mark virtual methods as overriding a base class method. -#if (__has_feature(cxx_override_control)) +#if __has_feature(cxx_override_control) \ + || (defined(_MSC_VER) && _MSC_VER >= 1700) #define LLVM_OVERRIDE override #else #define LLVM_OVERRIDE #endif +#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define LLVM_CONSTEXPR constexpr +#else +# define LLVM_CONSTEXPR +#endif + /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked /// into a shared library, then the class should be private to the library and /// not accessible from outside it. Can also be used to mark variables and @@ -129,7 +198,6 @@ #define LLVM_UNLIKELY(EXPR) (EXPR) #endif - // C++ doesn't support 'extern template' of template specializations. GCC does, // but requires __extension__ before it. In the header, use this: // EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>); @@ -143,8 +211,8 @@ #define TEMPLATE_INSTANTIATION(X) #endif -// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, -// mark a method "not for inlining". +/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, +/// mark a method "not for inlining". #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) @@ -153,10 +221,10 @@ #define LLVM_ATTRIBUTE_NOINLINE #endif -// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do -// so, mark a method "always inline" because it is performance sensitive. GCC -// 3.4 supported this but is buggy in various cases and produces unimplemented -// errors, just use it in GCC 4.0 and later. +/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do +/// so, mark a method "always inline" because it is performance sensitive. GCC +/// 3.4 supported this but is buggy in various cases and produces unimplemented +/// errors, just use it in GCC 4.0 and later. #if __GNUC__ > 3 #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) @@ -165,7 +233,6 @@ #define LLVM_ATTRIBUTE_ALWAYS_INLINE #endif - #ifdef __GNUC__ #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) #elif defined(_MSC_VER) @@ -174,8 +241,8 @@ #define LLVM_ATTRIBUTE_NORETURN #endif -// LLVM_EXTENSION - Support compilers where we have a keyword to suppress -// pedantic diagnostics. +/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress +/// pedantic diagnostics. #ifdef __GNUC__ #define LLVM_EXTENSION __extension__ #else @@ -197,16 +264,18 @@ 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. +/// 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() +#elif defined(_MSC_VER) +# define LLVM_BUILTIN_UNREACHABLE __assume(false) #endif -// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression -// which causes the program to exit abnormally. +/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression +/// which causes the program to exit abnormally. #if defined(__clang__) || (__GNUC__ > 4) \ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) # define LLVM_BUILTIN_TRAP __builtin_trap() @@ -214,4 +283,82 @@ # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 #endif +/// \macro LLVM_ASSUME_ALIGNED +/// \brief Returns a pointer with an assumed alignment. +#if !defined(__clang__) && ((__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) +// FIXME: Enable on clang when it supports it. +# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) +#elif defined(LLVM_BUILTIN_UNREACHABLE) +# define LLVM_ASSUME_ALIGNED(p, a) \ + (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p))) +#else +# define LLVM_ASSUME_ALIGNED(p, a) (p) +#endif + +/// \macro LLVM_FUNCTION_NAME +/// \brief Expands to __func__ on compilers which support it. Otherwise, +/// expands to a compiler-dependent replacement. +#if defined(_MSC_VER) +# define LLVM_FUNCTION_NAME __FUNCTION__ +#else +# define LLVM_FUNCTION_NAME __func__ +#endif + +#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H) +# include <sanitizer/msan_interface.h> +#else +# define __msan_allocated_memory(p, size) +# define __msan_unpoison(p, size) +#endif + +/// \macro LLVM_MEMORY_SANITIZER_BUILD +/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation. +#if __has_feature(memory_sanitizer) +# define LLVM_MEMORY_SANITIZER_BUILD 1 +#else +# define LLVM_MEMORY_SANITIZER_BUILD 0 +#endif + +/// \macro LLVM_ADDRESS_SANITIZER_BUILD +/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation. +#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +# define LLVM_ADDRESS_SANITIZER_BUILD 1 +#else +# define LLVM_ADDRESS_SANITIZER_BUILD 0 +#endif + +/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST +/// \brief Is unaligned memory access fast on the host machine. +/// +/// Don't specialize on alignment for platforms where unaligned memory accesses +/// generates the same code as aligned memory accesses for common types. +#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \ + defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \ + defined(_X86_) || defined(__i386) || defined(__i386__) +# define LLVM_IS_UNALIGNED_ACCESS_FAST 1 +#else +# define LLVM_IS_UNALIGNED_ACCESS_FAST 0 +#endif + +/// \macro LLVM_EXPLICIT +/// \brief Expands to explicit on compilers which support explicit conversion +/// operators. Otherwise expands to nothing. +#if (__has_feature(cxx_explicit_conversions) \ + || defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define LLVM_EXPLICIT explicit +#else +#define LLVM_EXPLICIT +#endif + +/// \macro LLVM_STATIC_ASSERT +/// \brief Expands to C/C++'s static_assert on compilers which support it. +#if __has_feature(cxx_static_assert) +# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg) +#elif __has_feature(c_static_assert) +# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg) +#else +# define LLVM_STATIC_ASSERT(expr, msg) +#endif + #endif diff --git a/contrib/llvm/include/llvm/Support/ConstantFolder.h b/contrib/llvm/include/llvm/Support/ConstantFolder.h index 93aa343..4aad952 100644 --- a/contrib/llvm/include/llvm/Support/ConstantFolder.h +++ b/contrib/llvm/include/llvm/Support/ConstantFolder.h @@ -17,8 +17,8 @@ #ifndef LLVM_SUPPORT_CONSTANTFOLDER_H #define LLVM_SUPPORT_CONSTANTFOLDER_H -#include "llvm/Constants.h" -#include "llvm/InstrTypes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/InstrTypes.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/ConstantRange.h b/contrib/llvm/include/llvm/Support/ConstantRange.h index 90dd69f..0f29256 100644 --- a/contrib/llvm/include/llvm/Support/ConstantRange.h +++ b/contrib/llvm/include/llvm/Support/ConstantRange.h @@ -29,8 +29,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H -#define LLVM_SUPPORT_CONSTANT_RANGE_H +#ifndef LLVM_SUPPORT_CONSTANTRANGE_H +#define LLVM_SUPPORT_CONSTANTRANGE_H #include "llvm/ADT/APInt.h" #include "llvm/Support/DataTypes.h" diff --git a/contrib/llvm/include/llvm/Support/ConvertUTF.h b/contrib/llvm/include/llvm/Support/ConvertUTF.h new file mode 100644 index 0000000..1eae6d6 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ConvertUTF.h @@ -0,0 +1,228 @@ +/*===--- ConvertUTF.h - Universal Character Names conversions ---------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *==------------------------------------------------------------------------==*/ +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Header file. + + Several funtions are included here, forming a complete set of + conversions between the three formats. UTF-7 is not included + here, but is handled in a separate source file. + + Each of these routines takes pointers to input buffers and output + buffers. The input buffers are const. + + Each routine converts the text between *sourceStart and sourceEnd, + putting the result into the buffer between *targetStart and + targetEnd. Note: the end pointers are *after* the last item: e.g. + *(sourceEnd - 1) is the last item. + + The return result indicates whether the conversion was successful, + and if not, whether the problem was in the source or target buffers. + (Only the first encountered problem is indicated.) + + After the conversion, *sourceStart and *targetStart are both + updated to point to the end of last text successfully converted in + the respective buffers. + + Input parameters: + sourceStart - pointer to a pointer to the source buffer. + The contents of this are modified on return so that + it points at the next thing to be converted. + targetStart - similarly, pointer to pointer to the target buffer. + sourceEnd, targetEnd - respectively pointers to the ends of the + two buffers, for overflow checking only. + + These conversion functions take a ConversionFlags argument. When this + flag is set to strict, both irregular sequences and isolated surrogates + will cause an error. When the flag is set to lenient, both irregular + sequences and isolated surrogates are converted. + + Whether the flag is strict or lenient, all illegal sequences will cause + an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>, + or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code + must check for illegal sequences. + + When the flag is set to lenient, characters over 0x10FFFF are converted + to the replacement character; otherwise (when the flag is set to strict) + they constitute an error. + + Output parameters: + The value "sourceIllegal" is returned from some routines if the input + sequence is malformed. When "sourceIllegal" is returned, the source + value will point to the illegal value that caused the problem. E.g., + in UTF-8 when a sequence is malformed, it points to the start of the + malformed sequence. + + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Fixes & updates, Sept 2001. + +------------------------------------------------------------------------ */ + +#ifndef CLANG_BASIC_CONVERTUTF_H +#define CLANG_BASIC_CONVERTUTF_H + +/* --------------------------------------------------------------------- + The following 4 definitions are compiler-specific. + The C standard does not guarantee that wchar_t has at least + 16 bits, so wchar_t is no less portable than unsigned short! + All should be unsigned values to avoid sign extension during + bit mask & shift operations. +------------------------------------------------------------------------ */ + +typedef unsigned int UTF32; /* at least 32 bits */ +typedef unsigned short UTF16; /* at least 16 bits */ +typedef unsigned char UTF8; /* typically 8 bits */ +typedef unsigned char Boolean; /* 0 or 1 */ + +/* Some fundamental constants */ +#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD +#define UNI_MAX_BMP (UTF32)0x0000FFFF +#define UNI_MAX_UTF16 (UTF32)0x0010FFFF +#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF +#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF + +#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4 + +typedef enum { + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +} ConversionResult; + +typedef enum { + strictConversion = 0, + lenientConversion +} ConversionFlags; + +/* This is for C++ and does no harm in C */ +#ifdef __cplusplus +extern "C" { +#endif + +ConversionResult ConvertUTF8toUTF16 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF8toUTF32 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF16toUTF8 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF32toUTF8 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF16toUTF32 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF32toUTF16 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); + +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); + +Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); + +unsigned getNumBytesForUTF8(UTF8 firstByte); + +#ifdef __cplusplus +} + +/*************************************************************************/ +/* Below are LLVM-specific wrappers of the functions above. */ + +#include "llvm/ADT/StringRef.h" + +namespace llvm { + +/** + * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on + * WideCharWidth. The converted data is written to ResultPtr, which needs to + * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success, + * ResultPtr will point one after the end of the copied string. On failure, + * ResultPtr will not be changed, and ErrorPtr will be set to the location of + * the first character which could not be converted. + * \return true on success. + */ +bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, + char *&ResultPtr, const UTF8 *&ErrorPtr); + +/** + * Convert an Unicode code point to UTF8 sequence. + * + * \param Source a Unicode code point. + * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least + * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is + * updated one past end of the converted sequence. + * + * \returns true on success. + */ +bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr); + +/** + * Convert the first UTF8 sequence in the given source buffer to a UTF32 + * code point. + * + * \param [in,out] source A pointer to the source buffer. If the conversion + * succeeds, this pointer will be updated to point to the byte just past the + * end of the converted sequence. + * \param sourceEnd A pointer just past the end of the source buffer. + * \param [out] target The converted code + * \param flags Whether the conversion is strict or lenient. + * + * \returns conversionOK on success + * + * \sa ConvertUTF8toUTF32 + */ +static inline ConversionResult convertUTF8Sequence(const UTF8 **source, + const UTF8 *sourceEnd, + UTF32 *target, + ConversionFlags flags) { + if (*source == sourceEnd) + return sourceExhausted; + unsigned size = getNumBytesForUTF8(**source); + if ((ptrdiff_t)size > sourceEnd - *source) + return sourceExhausted; + return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags); +} +} /* end namespace llvm */ + +#endif + +/* --------------------------------------------------------------------- */ + +#endif diff --git a/contrib/llvm/include/llvm/Support/DOTGraphTraits.h b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h index 483f267..95e37c0 100644 --- a/contrib/llvm/include/llvm/Support/DOTGraphTraits.h +++ b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h @@ -79,6 +79,11 @@ public: return false; } + template<typename GraphType> + static std::string getNodeDescription(const void *, const GraphType &) { + return ""; + } + /// If you want to specify custom node attributes, this is the place to do so /// template<typename GraphType> diff --git a/contrib/llvm/include/llvm/Support/DataExtractor.h b/contrib/llvm/include/llvm/Support/DataExtractor.h index a3ae782..e8a19cd 100644 --- a/contrib/llvm/include/llvm/Support/DataExtractor.h +++ b/contrib/llvm/include/llvm/Support/DataExtractor.h @@ -18,22 +18,24 @@ namespace llvm { class DataExtractor { StringRef Data; uint8_t IsLittleEndian; - uint8_t PointerSize; + uint8_t AddressSize; public: /// Construct with a buffer that is owned by the caller. /// /// This constructor allows us to use data that is owned by the /// caller. The data must stay around as long as this object is /// valid. - DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize) - : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {} + DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) + : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {} - /// getData - Get the data pointed to by this extractor. + /// \brief Get the data pointed to by this extractor. StringRef getData() const { return Data; } - /// isLittleEndian - Get the endianess for this extractor. + /// \brief Get the endianess for this extractor. bool isLittleEndian() const { return IsLittleEndian; } - /// getAddressSize - Get the address size for this extractor. - uint8_t getAddressSize() const { return PointerSize; } + /// \brief Get the address size for this extractor. + uint8_t getAddressSize() const { return AddressSize; } + /// \brief Set the address size for this extractor. + void setAddressSize(uint8_t Size) { AddressSize = Size; } /// Extract a C string from \a *offset_ptr. /// @@ -113,7 +115,7 @@ public: /// /// Extract a single pointer from the data and update the offset /// pointed to by \a offset_ptr. The size of the extracted pointer - /// comes from the \a m_addr_size member variable and should be + /// is \a getAddressSize(), so the address size has to be /// set correctly prior to extracting any pointer values. /// /// @param[in,out] offset_ptr @@ -126,7 +128,7 @@ public: /// @return /// The extracted pointer value as a 64 integer. uint64_t getAddress(uint32_t *offset_ptr) const { - return getUnsigned(offset_ptr, PointerSize); + return getUnsigned(offset_ptr, AddressSize); } /// Extract a uint8_t value from \a *offset_ptr. diff --git a/contrib/llvm/include/llvm/Support/DataFlow.h b/contrib/llvm/include/llvm/Support/DataFlow.h index 355c402..a09ccaa 100644 --- a/contrib/llvm/include/llvm/Support/DataFlow.h +++ b/contrib/llvm/include/llvm/Support/DataFlow.h @@ -14,8 +14,8 @@ #ifndef LLVM_SUPPORT_DATAFLOW_H #define LLVM_SUPPORT_DATAFLOW_H -#include "llvm/User.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/IR/User.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/DataStream.h b/contrib/llvm/include/llvm/Support/DataStream.h index fedb0c9..8bc4133 100644 --- a/contrib/llvm/include/llvm/Support/DataStream.h +++ b/contrib/llvm/include/llvm/Support/DataStream.h @@ -14,8 +14,8 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_DATASTREAM_H_ -#define LLVM_SUPPORT_DATASTREAM_H_ +#ifndef LLVM_SUPPORT_DATASTREAM_H +#define LLVM_SUPPORT_DATASTREAM_H #include <string> diff --git a/contrib/llvm/include/llvm/Support/DebugLoc.h b/contrib/llvm/include/llvm/Support/DebugLoc.h index 0498075..f35d407 100644 --- a/contrib/llvm/include/llvm/Support/DebugLoc.h +++ b/contrib/llvm/include/llvm/Support/DebugLoc.h @@ -9,7 +9,7 @@ // // This file defines a number of light weight data structures used // to describe and track debug location information. -// +// //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_DEBUGLOC_H @@ -19,7 +19,7 @@ namespace llvm { template <typename T> struct DenseMapInfo; class MDNode; class LLVMContext; - + /// DebugLoc - Debug location id. This is carried by Instruction, SDNode, /// and MachineInstr to compactly encode file/line/scope information for an /// operation. @@ -46,18 +46,18 @@ namespace llvm { /// location, encoded as 24-bits for line and 8 bits for col. A value of 0 /// for either means unknown. unsigned LineCol; - + /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information, /// decoded by LLVMContext. 0 is unknown. int ScopeIdx; public: DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown. - + /// get - Get a new DebugLoc that corresponds to the specified line/col /// scope/inline location. static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope, MDNode *InlinedAt = 0); - + /// getFromDILocation - Translate the DILocation quad into a DebugLoc. static DebugLoc getFromDILocation(MDNode *N); @@ -66,32 +66,32 @@ namespace llvm { /// isUnknown - Return true if this is an unknown location. bool isUnknown() const { return ScopeIdx == 0; } - + unsigned getLine() const { return (LineCol << 8) >> 8; // Mask out column. } - + unsigned getCol() const { return LineCol >> 24; } - + /// getScope - This returns the scope pointer for this DebugLoc, or null if /// invalid. MDNode *getScope(const LLVMContext &Ctx) const; - + /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or /// null if invalid or not present. MDNode *getInlinedAt(const LLVMContext &Ctx) const; - + /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values. void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, const LLVMContext &Ctx) const; - - + + /// getAsMDNode - This method converts the compressed DebugLoc node into a /// DILocation compatible MDNode. MDNode *getAsMDNode(const LLVMContext &Ctx) const; - + bool operator==(const DebugLoc &DL) const { return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx; } @@ -109,4 +109,4 @@ namespace llvm { }; } // end namespace llvm -#endif /* LLVM_DEBUGLOC_H */ +#endif /* LLVM_SUPPORT_DEBUGLOC_H */ diff --git a/contrib/llvm/include/llvm/Support/Dwarf.h b/contrib/llvm/include/llvm/Support/Dwarf.h index 8f18a99..b52914f 100644 --- a/contrib/llvm/include/llvm/Support/Dwarf.h +++ b/contrib/llvm/include/llvm/Support/Dwarf.h @@ -16,6 +16,9 @@ #ifndef LLVM_SUPPORT_DWARF_H #define LLVM_SUPPORT_DWARF_H +#include "llvm/Support/DataTypes.h" + + namespace llvm { //===----------------------------------------------------------------------===// @@ -37,7 +40,7 @@ enum { namespace dwarf { //===----------------------------------------------------------------------===// -// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3 +// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4 // reference manual http://dwarf.freestandards.org . // @@ -50,15 +53,19 @@ enum llvm_dwarf_constants { DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables. DW_TAG_arg_variable = 0x101, // Tag for argument variables. - DW_TAG_return_variable = 0x102, // Tag for return variables. - DW_TAG_vector_type = 0x103, // Tag for vector types. DW_TAG_user_base = 0x1000, // Recommended base for user tags. - DW_CIE_VERSION = 1, // Common frame information version. - DW_CIE_ID = 0xffffffff // Common frame information mark. + DW_CIE_VERSION = 1 // Common frame information version. }; + +// Special ID values that distinguish a CIE from a FDE in DWARF CFI. +// Not inside an enum because a 64-bit value is needed. +const uint32_t DW_CIE_ID = UINT32_MAX; +const uint64_t DW64_CIE_ID = UINT64_MAX; + + enum dwarf_constants { DWARF_VERSION = 2, @@ -231,6 +238,10 @@ enum dwarf_constants { DW_AT_const_expr = 0x6c, DW_AT_enum_class = 0x6d, DW_AT_linkage_name = 0x6e, + + DW_AT_lo_user = 0x2000, + DW_AT_hi_user = 0x3fff, + DW_AT_MIPS_loop_begin = 0x2002, DW_AT_MIPS_tail_loop_begin = 0x2003, DW_AT_MIPS_epilog_begin = 0x2004, @@ -246,6 +257,12 @@ enum dwarf_constants { DW_AT_MIPS_ptr_dopetype = 0x200e, DW_AT_MIPS_allocatable_dopetype = 0x200f, DW_AT_MIPS_assumed_shape_dopetype = 0x2010, + + // This one appears to have only been implemented by Open64 for + // fortran and may conflict with other extensions. + DW_AT_MIPS_assumed_size = 0x2011, + + // GNU extensions DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, @@ -254,9 +271,14 @@ enum dwarf_constants { DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, DW_AT_GNU_template_name = 0x2110, - DW_AT_MIPS_assumed_size = 0x2011, - DW_AT_lo_user = 0x2000, - DW_AT_hi_user = 0x3fff, + + // Extensions for Fission proposal. + DW_AT_GNU_dwo_name = 0x2130, + DW_AT_GNU_dwo_id = 0x2131, + DW_AT_GNU_ranges_base = 0x2132, + DW_AT_GNU_addr_base = 0x2133, + DW_AT_GNU_pubnames = 0x2134, + DW_AT_GNU_pubtypes = 0x2135, // Apple extensions. DW_AT_APPLE_optimized = 0x3fe1, @@ -300,6 +322,10 @@ enum dwarf_constants { DW_FORM_flag_present = 0x19, DW_FORM_ref_sig8 = 0x20, + // Extensions for Fission proposal + DW_FORM_GNU_addr_index = 0x1f01, + DW_FORM_GNU_str_index = 0x1f02, + // Operation encodings DW_OP_addr = 0x03, DW_OP_deref = 0x06, @@ -458,6 +484,10 @@ enum dwarf_constants { DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff, + // Extensions for Fission proposal. + DW_OP_GNU_addr_index = 0xfb, + DW_OP_GNU_const_index = 0xfc, + // Encoding attribute values DW_ATE_address = 0x01, DW_ATE_boolean = 0x02, diff --git a/contrib/llvm/include/llvm/Support/DynamicLibrary.h b/contrib/llvm/include/llvm/Support/DynamicLibrary.h index 0f59cbf..1e2d16c 100644 --- a/contrib/llvm/include/llvm/Support/DynamicLibrary.h +++ b/contrib/llvm/include/llvm/Support/DynamicLibrary.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H -#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H +#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H +#define LLVM_SYSTEM_DYNAMICLIBRARY_H #include <string> diff --git a/contrib/llvm/include/llvm/Support/ELF.h b/contrib/llvm/include/llvm/Support/ELF.h index 2cd2671..ea597fc 100644 --- a/contrib/llvm/include/llvm/Support/ELF.h +++ b/contrib/llvm/include/llvm/Support/ELF.h @@ -271,6 +271,7 @@ enum { EM_SLE9X = 179, // Infineon Technologies SLE9X core EM_L10M = 180, // Intel L10M EM_K10M = 181, // Intel K10M + EM_AARCH64 = 183, // ARM AArch64 EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller EM_TILE64 = 187, // Tilera TILE64 multicore architecture family @@ -366,7 +367,8 @@ enum { R_X86_64_SIZE64 = 33, R_X86_64_GOTPC32_TLSDESC = 34, R_X86_64_TLSDESC_CALL = 35, - R_X86_64_TLSDESC = 36 + R_X86_64_TLSDESC = 36, + R_X86_64_IRELATIVE = 37 }; // i386 relocations. @@ -464,20 +466,140 @@ enum { // ELF Relocation types for PPC64 enum { + R_PPC64_ADDR32 = 1, R_PPC64_ADDR16_LO = 4, R_PPC64_ADDR16_HI = 5, R_PPC64_ADDR14 = 7, R_PPC64_REL24 = 10, + R_PPC64_REL32 = 26, R_PPC64_ADDR64 = 38, R_PPC64_ADDR16_HIGHER = 39, R_PPC64_ADDR16_HIGHEST = 41, + R_PPC64_REL64 = 44, R_PPC64_TOC16 = 47, + R_PPC64_TOC16_LO = 48, + R_PPC64_TOC16_HA = 50, R_PPC64_TOC = 51, - R_PPC64_TOC16_DS = 63 + R_PPC64_ADDR16_DS = 56, + R_PPC64_ADDR16_LO_DS = 57, + R_PPC64_TOC16_DS = 63, + R_PPC64_TOC16_LO_DS = 64, + R_PPC64_TLS = 67, + R_PPC64_TPREL16_LO = 70, + R_PPC64_DTPREL16_LO = 75, + R_PPC64_DTPREL16_HA = 77, + R_PPC64_GOT_TLSGD16_LO = 80, + R_PPC64_GOT_TLSGD16_HA = 82, + R_PPC64_GOT_TLSLD16_LO = 84, + R_PPC64_GOT_TLSLD16_HA = 86, + R_PPC64_GOT_TPREL16_LO_DS = 88, + R_PPC64_GOT_TPREL16_HA = 90, + R_PPC64_TLSGD = 107, + R_PPC64_TLSLD = 108 +}; + +// ELF Relocation types for AArch64 + +enum { + R_AARCH64_NONE = 0x100, + + R_AARCH64_ABS64 = 0x101, + R_AARCH64_ABS32 = 0x102, + R_AARCH64_ABS16 = 0x103, + R_AARCH64_PREL64 = 0x104, + R_AARCH64_PREL32 = 0x105, + R_AARCH64_PREL16 = 0x106, + + R_AARCH64_MOVW_UABS_G0 = 0x107, + R_AARCH64_MOVW_UABS_G0_NC = 0x108, + R_AARCH64_MOVW_UABS_G1 = 0x109, + R_AARCH64_MOVW_UABS_G1_NC = 0x10a, + R_AARCH64_MOVW_UABS_G2 = 0x10b, + R_AARCH64_MOVW_UABS_G2_NC = 0x10c, + R_AARCH64_MOVW_UABS_G3 = 0x10d, + R_AARCH64_MOVW_SABS_G0 = 0x10e, + R_AARCH64_MOVW_SABS_G1 = 0x10f, + R_AARCH64_MOVW_SABS_G2 = 0x110, + + R_AARCH64_LD_PREL_LO19 = 0x111, + R_AARCH64_ADR_PREL_LO21 = 0x112, + R_AARCH64_ADR_PREL_PG_HI21 = 0x113, + R_AARCH64_ADD_ABS_LO12_NC = 0x115, + R_AARCH64_LDST8_ABS_LO12_NC = 0x116, + + R_AARCH64_TSTBR14 = 0x117, + R_AARCH64_CONDBR19 = 0x118, + R_AARCH64_JUMP26 = 0x11a, + R_AARCH64_CALL26 = 0x11b, + + R_AARCH64_LDST16_ABS_LO12_NC = 0x11c, + R_AARCH64_LDST32_ABS_LO12_NC = 0x11d, + R_AARCH64_LDST64_ABS_LO12_NC = 0x11e, + + R_AARCH64_LDST128_ABS_LO12_NC = 0x12b, + + R_AARCH64_ADR_GOT_PAGE = 0x137, + R_AARCH64_LD64_GOT_LO12_NC = 0x138, + + R_AARCH64_TLSLD_MOVW_DTPREL_G2 = 0x20b, + R_AARCH64_TLSLD_MOVW_DTPREL_G1 = 0x20c, + R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC = 0x20d, + R_AARCH64_TLSLD_MOVW_DTPREL_G0 = 0x20e, + R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC = 0x20f, + R_AARCH64_TLSLD_ADD_DTPREL_HI12 = 0x210, + R_AARCH64_TLSLD_ADD_DTPREL_LO12 = 0x211, + R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC = 0x212, + R_AARCH64_TLSLD_LDST8_DTPREL_LO12 = 0x213, + R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC = 0x214, + R_AARCH64_TLSLD_LDST16_DTPREL_LO12 = 0x215, + R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 0x216, + R_AARCH64_TLSLD_LDST32_DTPREL_LO12 = 0x217, + R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 0x218, + R_AARCH64_TLSLD_LDST64_DTPREL_LO12 = 0x219, + R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 0x21a, + + R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 0x21b, + R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 0x21c, + R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 0x21d, + R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 0x21e, + R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 0x21f, + + R_AARCH64_TLSLE_MOVW_TPREL_G2 = 0x220, + R_AARCH64_TLSLE_MOVW_TPREL_G1 = 0x221, + R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 0x222, + R_AARCH64_TLSLE_MOVW_TPREL_G0 = 0x223, + R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 0x224, + R_AARCH64_TLSLE_ADD_TPREL_HI12 = 0x225, + R_AARCH64_TLSLE_ADD_TPREL_LO12 = 0x226, + R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 0x227, + R_AARCH64_TLSLE_LDST8_TPREL_LO12 = 0x228, + R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC = 0x229, + R_AARCH64_TLSLE_LDST16_TPREL_LO12 = 0x22a, + R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC = 0x22b, + R_AARCH64_TLSLE_LDST32_TPREL_LO12 = 0x22c, + R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC = 0x22d, + R_AARCH64_TLSLE_LDST64_TPREL_LO12 = 0x22e, + R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC = 0x22f, + + R_AARCH64_TLSDESC_ADR_PAGE = 0x232, + R_AARCH64_TLSDESC_LD64_LO12_NC = 0x233, + R_AARCH64_TLSDESC_ADD_LO12_NC = 0x234, + + R_AARCH64_TLSDESC_CALL = 0x239 }; // ARM Specific e_flags -enum { EF_ARM_EABIMASK = 0xFF000000U }; +enum { + EF_ARM_SOFT_FLOAT = 0x00000200U, + EF_ARM_VFP_FLOAT = 0x00000400U, + EF_ARM_EABI_UNKNOWN = 0x00000000U, + EF_ARM_EABI_VER1 = 0x01000000U, + EF_ARM_EABI_VER2 = 0x02000000U, + EF_ARM_EABI_VER3 = 0x03000000U, + EF_ARM_EABI_VER4 = 0x04000000U, + EF_ARM_EABI_VER5 = 0x05000000U, + EF_ARM_EABIMASK = 0xFF000000U +}; // ELF Relocation types for ARM // Meets 2.08 ABI Specs. @@ -621,6 +743,13 @@ enum { EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions EF_MIPS_PIC = 0x00000002, // Position independent code EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code + EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI + + //ARCH_ASE + EF_MIPS_MICROMIPS = 0x02000000, // microMIPS + EF_MIPS_ARCH_ASE_M16 = + 0x04000000, // Has Mips-16 ISA extensions + //ARCH EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set @@ -691,6 +820,11 @@ enum { R_MIPS_NUM = 218 }; +// Special values for the st_other field in the symbol table entry for MIPS. +enum { + STO_MIPS_MICROMIPS = 0x80 // MIPS Specific ISA for MicroMips +}; + // Hexagon Specific e_flags // Release 5 ABI enum { @@ -710,14 +844,14 @@ enum { }; // Hexagon specific Section indexes for common small data -// Release 5 ABI +// Release 5 ABI enum { SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access SHN_HEXAGON_SCOMMON_2 = 0xff02, // Half-word-sized access SHN_HEXAGON_SCOMMON_4 = 0xff03, // Word-sized access SHN_HEXAGON_SCOMMON_8 = 0xff04 // Double-word-size access -}; +}; // ELF Relocation types for Hexagon // Release 5 ABI @@ -878,7 +1012,7 @@ enum { SHT_GNU_verneed = 0x6ffffffe, // GNU version references. SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. - SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type. + SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type. // Fixme: All this is duplicated in MCSectionELF. Why?? // Exception Index table SHT_ARM_EXIDX = 0x70000001U, @@ -888,10 +1022,14 @@ enum { SHT_ARM_ATTRIBUTES = 0x70000003U, SHT_ARM_DEBUGOVERLAY = 0x70000004U, SHT_ARM_OVERLAYSECTION = 0x70000005U, - + SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in + // this section based on their sizes SHT_X86_64_UNWIND = 0x70000001, // Unwind information - SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type. + SHT_MIPS_REGINFO = 0x70000006, // Register usage information + SHT_MIPS_OPTIONS = 0x7000000d, // General options + + SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. SHT_HIUSER = 0xffffffff // Highest type reserved for applications. }; @@ -953,7 +1091,14 @@ enum { // sets this flag besides being able to refer to data in a section that does // not set it; likewise, a small code model object can refer only to code in a // section that does not set this flag. - SHF_X86_64_LARGE = 0x10000000 + SHF_X86_64_LARGE = 0x10000000, + + // All sections with the GPREL flag are grouped into a global data area + // for faster accesses + SHF_HEX_GPREL = 0x10000000, + + // Do not strip this section. FIXME: We need target specific SHF_ enums. + SHF_MIPS_NOSTRIP = 0x8000000 }; // Section Group Flags @@ -988,7 +1133,7 @@ struct Elf64_Sym { Elf64_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved - Elf64_Half st_shndx; // Which section (header table index) it's defined in + Elf64_Half st_shndx; // Which section (header tbl index) it's defined in Elf64_Addr st_value; // Value or address associated with the symbol Elf64_Xword st_size; // Size of the symbol @@ -1043,6 +1188,11 @@ enum { STV_PROTECTED = 3 // Visible in other components but not preemptable }; +// Symbol number. +enum { + STN_UNDEF = 0 +}; + // Relocation entry, without explicit addend. struct Elf32_Rel { Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) @@ -1083,14 +1233,14 @@ struct Elf64_Rel { // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: - Elf64_Xword getSymbol() const { return (r_info >> 32); } - unsigned char getType() const { - return (unsigned char) (r_info & 0xffffffffL); + Elf64_Word getSymbol() const { return (r_info >> 32); } + Elf64_Word getType() const { + return (Elf64_Word) (r_info & 0xffffffffL); } - void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); } - void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } - void setSymbolAndType(Elf64_Xword s, unsigned char t) { - r_info = (s << 32) + (t&0xffffffffL); + void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); } + void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); } + void setSymbolAndType(Elf64_Word s, Elf64_Word t) { + r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL); } }; @@ -1102,14 +1252,14 @@ struct Elf64_Rela { // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: - Elf64_Xword getSymbol() const { return (r_info >> 32); } - unsigned char getType() const { - return (unsigned char) (r_info & 0xffffffffL); + Elf64_Word getSymbol() const { return (r_info >> 32); } + Elf64_Word getType() const { + return (Elf64_Word) (r_info & 0xffffffffL); } - void setSymbol(Elf64_Xword s) { setSymbolAndType(s, getType()); } - void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } - void setSymbolAndType(Elf64_Xword s, unsigned char t) { - r_info = (s << 32) + (t&0xffffffffL); + void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); } + void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); } + void setSymbolAndType(Elf64_Word s, Elf64_Word t) { + r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL); } }; @@ -1131,7 +1281,7 @@ struct Elf64_Phdr { Elf64_Word p_flags; // Segment flags Elf64_Off p_offset; // File offset where segment is located, in bytes Elf64_Addr p_vaddr; // Virtual address of beginning of segment - Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific) + Elf64_Addr p_paddr; // Physical addr of beginning of segment (OS-specific) Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero) Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero) Elf64_Xword p_align; // Segment alignment constraint @@ -1162,7 +1312,7 @@ enum { PT_GNU_RELRO = 0x6474e552, // Read-only after relocation. // ARM program header types. - PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility information + PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info // These all contain stack unwind tables. PT_ARM_EXIDX = 0x70000001, PT_ARM_UNWIND = 0x70000001 diff --git a/contrib/llvm/include/llvm/Support/Endian.h b/contrib/llvm/include/llvm/Support/Endian.h index 8d5649d..d438fac 100644 --- a/contrib/llvm/include/llvm/Support/Endian.h +++ b/contrib/llvm/include/llvm/Support/Endian.h @@ -14,136 +14,78 @@ #ifndef LLVM_SUPPORT_ENDIAN_H #define LLVM_SUPPORT_ENDIAN_H +#include "llvm/Support/AlignOf.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" namespace llvm { namespace support { +enum endianness {big, little, native}; -enum endianness {big, little}; -enum alignment {unaligned, aligned}; +// These are named values for common alignments. +enum {aligned = 0, unaligned = 1}; namespace detail { - -template<typename value_type, alignment align> -struct alignment_access_helper; - -template<typename value_type> -struct alignment_access_helper<value_type, aligned> -{ - value_type val; -}; - -// Provides unaligned loads and stores. -#pragma pack(push) -#pragma pack(1) -template<typename value_type> -struct alignment_access_helper<value_type, unaligned> -{ - value_type val; -}; -#pragma pack(pop) - + /// \brief ::value is either alignment, or alignof(T) if alignment is 0. + template<class T, int alignment> + struct PickAlignment { + enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment}; + }; } // end namespace detail namespace endian { - template<typename value_type, alignment align> - inline value_type read_le(const void *memory) { - value_type t = - reinterpret_cast<const detail::alignment_access_helper - <value_type, align> *>(memory)->val; - if (sys::isBigEndianHost()) - return sys::SwapByteOrder(t); - return t; - } - - template<typename value_type, alignment align> - inline void write_le(void *memory, value_type value) { - if (sys::isBigEndianHost()) - value = sys::SwapByteOrder(value); - reinterpret_cast<detail::alignment_access_helper<value_type, align> *> - (memory)->val = value; - } +template<typename value_type, endianness endian> +inline value_type byte_swap(value_type value) { + if (endian != native && sys::isBigEndianHost() != (endian == big)) + return sys::SwapByteOrder(value); + return value; +} - template<typename value_type, alignment align> - inline value_type read_be(const void *memory) { - value_type t = - reinterpret_cast<const detail::alignment_access_helper - <value_type, align> *>(memory)->val; - if (sys::isLittleEndianHost()) - return sys::SwapByteOrder(t); - return t; - } +template<typename value_type, + endianness endian, + std::size_t alignment> +inline value_type read(const void *memory) { + value_type ret; + + memcpy(&ret, + LLVM_ASSUME_ALIGNED(memory, + (detail::PickAlignment<value_type, alignment>::value)), + sizeof(value_type)); + return byte_swap<value_type, endian>(ret); +} - template<typename value_type, alignment align> - inline void write_be(void *memory, value_type value) { - if (sys::isLittleEndianHost()) - value = sys::SwapByteOrder(value); - reinterpret_cast<detail::alignment_access_helper<value_type, align> *> - (memory)->val = value; - } +template<typename value_type, + endianness endian, + std::size_t alignment> +inline void write(void *memory, value_type value) { + value = byte_swap<value_type, endian>(value); + memcpy(LLVM_ASSUME_ALIGNED(memory, + (detail::PickAlignment<value_type, alignment>::value)), + &value, + sizeof(value_type)); } +} // end namespace endian namespace detail { - template<typename value_type, endianness endian, - alignment align> -class packed_endian_specific_integral; - -template<typename value_type> -class packed_endian_specific_integral<value_type, little, unaligned> { -public: - operator value_type() const { - return endian::read_le<value_type, unaligned>(Value); - } - void operator=(value_type newValue) { - endian::write_le<value_type, unaligned>((void *)&Value, newValue); - } -private: - uint8_t Value[sizeof(value_type)]; -}; - -template<typename value_type> -class packed_endian_specific_integral<value_type, big, unaligned> { -public: + std::size_t alignment> +struct packed_endian_specific_integral { operator value_type() const { - return endian::read_be<value_type, unaligned>(Value); + return endian::read<value_type, endian, alignment>( + (const void*)Value.buffer); } - void operator=(value_type newValue) { - endian::write_be<value_type, unaligned>((void *)&Value, newValue); - } -private: - uint8_t Value[sizeof(value_type)]; -}; -template<typename value_type> -class packed_endian_specific_integral<value_type, little, aligned> { -public: - operator value_type() const { - return endian::read_le<value_type, aligned>(&Value); - } void operator=(value_type newValue) { - endian::write_le<value_type, aligned>((void *)&Value, newValue); + endian::write<value_type, endian, alignment>( + (void*)Value.buffer, newValue); } -private: - value_type Value; -}; -template<typename value_type> -class packed_endian_specific_integral<value_type, big, aligned> { -public: - operator value_type() const { - return endian::read_be<value_type, aligned>(&Value); - } - void operator=(value_type newValue) { - endian::write_be<value_type, aligned>((void *)&Value, newValue); - } private: - value_type Value; + AlignedCharArray<PickAlignment<value_type, alignment>::value, + sizeof(value_type)> Value; }; - } // end namespace detail typedef detail::packed_endian_specific_integral @@ -218,6 +160,19 @@ typedef detail::packed_endian_specific_integral typedef detail::packed_endian_specific_integral <int64_t, big, aligned> aligned_big64_t; +typedef detail::packed_endian_specific_integral + <uint16_t, native, unaligned> unaligned_uint16_t; +typedef detail::packed_endian_specific_integral + <uint32_t, native, unaligned> unaligned_uint32_t; +typedef detail::packed_endian_specific_integral + <uint64_t, native, unaligned> unaligned_uint64_t; + +typedef detail::packed_endian_specific_integral + <int16_t, native, unaligned> unaligned_int16_t; +typedef detail::packed_endian_specific_integral + <int32_t, native, unaligned> unaligned_int32_t; +typedef detail::packed_endian_specific_integral + <int64_t, native, unaligned> unaligned_int64_t; } // end namespace llvm } // end namespace support diff --git a/contrib/llvm/include/llvm/Support/Errno.h b/contrib/llvm/include/llvm/Support/Errno.h index 150bdb7..8e145c7 100644 --- a/contrib/llvm/include/llvm/Support/Errno.h +++ b/contrib/llvm/include/llvm/Support/Errno.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_ERRNO_H -#define LLVM_SYSTEM_ERRNO_H +#ifndef LLVM_SUPPORT_ERRNO_H +#define LLVM_SUPPORT_ERRNO_H #include <string> diff --git a/contrib/llvm/include/llvm/Support/ErrorHandling.h b/contrib/llvm/include/llvm/Support/ErrorHandling.h index 95b0109..b948d97 100644 --- a/contrib/llvm/include/llvm/Support/ErrorHandling.h +++ b/contrib/llvm/include/llvm/Support/ErrorHandling.h @@ -15,8 +15,8 @@ #ifndef LLVM_SUPPORT_ERRORHANDLING_H #define LLVM_SUPPORT_ERRORHANDLING_H -#include "llvm/Support/Compiler.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" #include <string> namespace llvm { @@ -24,7 +24,8 @@ namespace llvm { /// An error handler callback. typedef void (*fatal_error_handler_t)(void *user_data, - const std::string& reason); + const std::string& reason, + bool gen_crash_diag); /// install_fatal_error_handler - Installs a new error handler to be used /// whenever a serious (non-recoverable) error is encountered by LLVM. @@ -73,10 +74,14 @@ namespace llvm { /// standard error, followed by a newline. /// After the error handler is called this function will call exit(1), it /// does not return. - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason); + LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, + bool gen_crash_diag = true); + LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason, + bool gen_crash_diag = true); + LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason, + bool gen_crash_diag = true); + LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason, + bool gen_crash_diag = true); /// This function calls abort(), and prints the optional message to stderr. /// Use the llvm_unreachable macro (that adds location info), instead of diff --git a/contrib/llvm/include/llvm/Support/ErrorOr.h b/contrib/llvm/include/llvm/Support/ErrorOr.h new file mode 100644 index 0000000..f3ac305 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ErrorOr.h @@ -0,0 +1,514 @@ +//===- llvm/Support/ErrorOr.h - Error Smart Pointer -----------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Provides ErrorOr<T> smart pointer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ERROR_OR_H +#define LLVM_SUPPORT_ERROR_OR_H + +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/system_error.h" +#include "llvm/Support/type_traits.h" + +#include <cassert> +#if LLVM_HAS_CXX11_TYPETRAITS +#include <type_traits> +#endif + +namespace llvm { +struct ErrorHolderBase { + error_code Error; + uint16_t RefCount; + bool HasUserData; + + ErrorHolderBase() : RefCount(1) {} + + void aquire() { + ++RefCount; + } + + void release() { + if (--RefCount == 0) + delete this; + } + +protected: + virtual ~ErrorHolderBase() {} +}; + +template<class T> +struct ErrorHolder : ErrorHolderBase { +#if LLVM_HAS_RVALUE_REFERENCES + ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {} +#else + ErrorHolder(T &UD) : UserData(UD) {} +#endif + T UserData; +}; + +template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {}; + +#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES +template<class T, class V> +typename std::enable_if< std::is_constructible<T, V>::value + , typename std::remove_reference<V>::type>::type && + moveIfMoveConstructible(V &Val) { + return std::move(Val); +} + +template<class T, class V> +typename std::enable_if< !std::is_constructible<T, V>::value + , typename std::remove_reference<V>::type>::type & +moveIfMoveConstructible(V &Val) { + return Val; +} +#else +template<class T, class V> +V &moveIfMoveConstructible(V &Val) { + return Val; +} +#endif + +/// \brief Stores a reference that can be changed. +template <typename T> +class ReferenceStorage { + T *Storage; + +public: + ReferenceStorage(T &Ref) : Storage(&Ref) {} + + operator T &() const { return *Storage; } + T &get() const { return *Storage; } +}; + +/// \brief Represents either an error or a value T. +/// +/// ErrorOr<T> is a pointer-like class that represents the result of an +/// operation. The result is either an error, or a value of type T. This is +/// designed to emulate the usage of returning a pointer where nullptr indicates +/// failure. However instead of just knowing that the operation failed, we also +/// have an error_code and optional user data that describes why it failed. +/// +/// It is used like the following. +/// \code +/// ErrorOr<Buffer> getBuffer(); +/// void handleError(error_code ec); +/// +/// auto buffer = getBuffer(); +/// if (!buffer) +/// handleError(buffer); +/// buffer->write("adena"); +/// \endcode +/// +/// ErrorOr<T> also supports user defined data for specific error_codes. To use +/// this feature you must first add a template specialization of +/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld +/// namespace. This specialization must have a static error_code error() +/// function that returns the error_code this data is used with. +/// +/// getError<UserData>() may be called to get either the stored user data, or +/// a default constructed UserData if none was stored. +/// +/// Example: +/// \code +/// struct InvalidArgError { +/// InvalidArgError() {} +/// InvalidArgError(std::string S) : ArgName(S) {} +/// std::string ArgName; +/// }; +/// +/// namespace llvm { +/// template<> +/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type { +/// static error_code error() { +/// return make_error_code(errc::invalid_argument); +/// } +/// }; +/// } // end namespace llvm +/// +/// using namespace llvm; +/// +/// ErrorOr<int> foo() { +/// return InvalidArgError("adena"); +/// } +/// +/// int main() { +/// auto a = foo(); +/// if (!a && error_code(a) == errc::invalid_argument) +/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n"; +/// } +/// \endcode +/// +/// An implicit conversion to bool provides a way to check if there was an +/// error. The unary * and -> operators provide pointer like access to the +/// value. Accessing the value when there is an error has undefined behavior. +/// +/// When T is a reference type the behaivor is slightly different. The reference +/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and +/// there is special handling to make operator -> work as if T was not a +/// reference. +/// +/// T cannot be a rvalue reference. +template<class T> +class ErrorOr { + template <class OtherT> friend class ErrorOr; + static const bool isRef = is_reference<T>::value; + typedef ReferenceStorage<typename remove_reference<T>::type> wrap; + +public: + typedef typename + conditional< isRef + , wrap + , T + >::type storage_type; + +private: + typedef typename remove_reference<T>::type &reference; + typedef typename remove_reference<T>::type *pointer; + +public: + ErrorOr() : IsValid(false) {} + + template <class E> + ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value || + is_error_condition_enum<E>::value, + void *>::type = 0) + : HasError(true), IsValid(true) { + Error = new ErrorHolderBase; + Error->Error = make_error_code(ErrorCode); + Error->HasUserData = false; + } + + ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) { + Error = new ErrorHolderBase; + Error->Error = EC; + Error->HasUserData = false; + } + + template<class UserDataT> + ErrorOr(UserDataT UD, typename + enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0) + : HasError(true), IsValid(true) { + Error = new ErrorHolder<UserDataT>(llvm_move(UD)); + Error->Error = ErrorOrUserDataTraits<UserDataT>::error(); + Error->HasUserData = true; + } + + ErrorOr(T Val) : HasError(false), IsValid(true) { + new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val)); + } + + ErrorOr(const ErrorOr &Other) : IsValid(false) { + copyConstruct(Other); + } + + template <class OtherT> + ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) { + copyConstruct(Other); + } + + ErrorOr &operator =(const ErrorOr &Other) { + copyAssign(Other); + return *this; + } + + template <class OtherT> + ErrorOr &operator =(const ErrorOr<OtherT> &Other) { + copyAssign(Other); + return *this; + } + +#if LLVM_HAS_RVALUE_REFERENCES + ErrorOr(ErrorOr &&Other) : IsValid(false) { + moveConstruct(std::move(Other)); + } + + template <class OtherT> + ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) { + moveConstruct(std::move(Other)); + } + + ErrorOr &operator =(ErrorOr &&Other) { + moveAssign(std::move(Other)); + return *this; + } + + template <class OtherT> + ErrorOr &operator =(ErrorOr<OtherT> &&Other) { + moveAssign(std::move(Other)); + return *this; + } +#endif + + ~ErrorOr() { + if (!IsValid) + return; + if (HasError) + Error->release(); + else + get()->~storage_type(); + } + + template<class ET> + ET getError() const { + assert(IsValid && "Cannot get the error of a default constructed ErrorOr!"); + assert(HasError && "Cannot get an error if none exists!"); + assert(ErrorOrUserDataTraits<ET>::error() == Error->Error && + "Incorrect user error data type for error!"); + if (!Error->HasUserData) + return ET(); + return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData; + } + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + /// \brief Return false if there is an error. + operator unspecified_bool_type() const { + assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); + return HasError ? 0 : unspecified_bool_true; + } + + operator llvm::error_code() const { + assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); + return HasError ? Error->Error : llvm::error_code::success(); + } + + pointer operator ->() { + return toPointer(get()); + } + + reference operator *() { + return *get(); + } + +private: + template <class OtherT> + void copyConstruct(const ErrorOr<OtherT> &Other) { + // Construct an invalid ErrorOr if other is invalid. + if (!Other.IsValid) + return; + IsValid = true; + if (!Other.HasError) { + // Get the other value. + HasError = false; + new (get()) storage_type(*Other.get()); + } else { + // Get other's error. + Error = Other.Error; + HasError = true; + Error->aquire(); + } + } + + template <class T1> + static bool compareThisIfSameType(const T1 &a, const T1 &b) { + return &a == &b; + } + + template <class T1, class T2> + static bool compareThisIfSameType(const T1 &a, const T2 &b) { + return false; + } + + template <class OtherT> + void copyAssign(const ErrorOr<OtherT> &Other) { + if (compareThisIfSameType(*this, Other)) + return; + + this->~ErrorOr(); + new (this) ErrorOr(Other); + } + +#if LLVM_HAS_RVALUE_REFERENCES + template <class OtherT> + void moveConstruct(ErrorOr<OtherT> &&Other) { + // Construct an invalid ErrorOr if other is invalid. + if (!Other.IsValid) + return; + IsValid = true; + if (!Other.HasError) { + // Get the other value. + HasError = false; + new (get()) storage_type(std::move(*Other.get())); + // Tell other not to do any destruction. + Other.IsValid = false; + } else { + // Get other's error. + Error = Other.Error; + HasError = true; + // Tell other not to do any destruction. + Other.IsValid = false; + } + } + + template <class OtherT> + void moveAssign(ErrorOr<OtherT> &&Other) { + if (compareThisIfSameType(*this, Other)) + return; + + this->~ErrorOr(); + new (this) ErrorOr(std::move(Other)); + } +#endif + + pointer toPointer(pointer Val) { + return Val; + } + + pointer toPointer(wrap *Val) { + return &Val->get(); + } + + storage_type *get() { + assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); + assert(!HasError && "Cannot get value when an error exists!"); + return reinterpret_cast<storage_type*>(TStorage.buffer); + } + + const storage_type *get() const { + assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); + assert(!HasError && "Cannot get value when an error exists!"); + return reinterpret_cast<const storage_type*>(TStorage.buffer); + } + + union { + AlignedCharArrayUnion<storage_type> TStorage; + ErrorHolderBase *Error; + }; + bool HasError : 1; + bool IsValid : 1; +}; + +// ErrorOr specialization for void. +template <> +class ErrorOr<void> { +public: + ErrorOr() : Error(0, 0) {} + + template <class E> + ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value || + is_error_condition_enum<E>::value, + void *> ::type = 0) + : Error(0, 0) { + error_code EC = make_error_code(ErrorCode); + if (EC == errc::success) { + Error.setInt(1); + return; + } + ErrorHolderBase *EHB = new ErrorHolderBase; + EHB->Error = EC; + EHB->HasUserData = false; + Error.setPointer(EHB); + } + + ErrorOr(llvm::error_code EC) : Error(0, 0) { + if (EC == errc::success) { + Error.setInt(1); + return; + } + ErrorHolderBase *E = new ErrorHolderBase; + E->Error = EC; + E->HasUserData = false; + Error.setPointer(E); + } + + template<class UserDataT> + ErrorOr(UserDataT UD, typename + enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0) + : Error(0, 0) { + ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD)); + E->Error = ErrorOrUserDataTraits<UserDataT>::error(); + E->HasUserData = true; + Error.setPointer(E); + } + + ErrorOr(const ErrorOr &Other) : Error(0, 0) { + Error = Other.Error; + if (Other.Error.getPointer()->Error) { + Error.getPointer()->aquire(); + } + } + + ErrorOr &operator =(const ErrorOr &Other) { + if (this == &Other) + return *this; + + this->~ErrorOr(); + new (this) ErrorOr(Other); + + return *this; + } + +#if LLVM_HAS_RVALUE_REFERENCES + ErrorOr(ErrorOr &&Other) : Error(0) { + // Get other's error. + Error = Other.Error; + // Tell other not to do any destruction. + Other.Error.setPointer(0); + } + + ErrorOr &operator =(ErrorOr &&Other) { + if (this == &Other) + return *this; + + this->~ErrorOr(); + new (this) ErrorOr(std::move(Other)); + + return *this; + } +#endif + + ~ErrorOr() { + if (Error.getPointer()) + Error.getPointer()->release(); + } + + template<class ET> + ET getError() const { + assert(ErrorOrUserDataTraits<ET>::error() == *this && + "Incorrect user error data type for error!"); + if (!Error.getPointer()->HasUserData) + return ET(); + return reinterpret_cast<const ErrorHolder<ET> *>( + Error.getPointer())->UserData; + } + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + /// \brief Return false if there is an error. + operator unspecified_bool_type() const { + return Error.getInt() ? unspecified_bool_true : 0; + } + + operator llvm::error_code() const { + return Error.getInt() ? make_error_code(errc::success) + : Error.getPointer()->Error; + } + +private: + // If the bit is 1, the error is success. + llvm::PointerIntPair<ErrorHolderBase *, 1> Error; +}; + +template<class T, class E> +typename enable_if_c<is_error_code_enum<E>::value || + is_error_condition_enum<E>::value, bool>::type +operator ==(ErrorOr<T> &Err, E Code) { + return error_code(Err) == Code; +} +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Support/FEnv.h b/contrib/llvm/include/llvm/Support/FEnv.h index f6f4333..8560ee0 100644 --- a/contrib/llvm/include/llvm/Support/FEnv.h +++ b/contrib/llvm/include/llvm/Support/FEnv.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_FENV_H -#define LLVM_SYSTEM_FENV_H +#ifndef LLVM_SUPPORT_FENV_H +#define LLVM_SUPPORT_FENV_H #include "llvm/Config/config.h" #include <cerrno> @@ -32,7 +32,7 @@ namespace sys { /// llvm_fenv_clearexcept - Clear the floating-point exception state. static inline void llvm_fenv_clearexcept() { -#ifdef HAVE_FENV_H +#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT feclearexcept(FE_ALL_EXCEPT); #endif errno = 0; @@ -43,7 +43,7 @@ static inline bool llvm_fenv_testexcept() { int errno_val = errno; if (errno_val == ERANGE || errno_val == EDOM) return true; -#ifdef HAVE_FENV_H +#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT)) return true; #endif diff --git a/contrib/llvm/include/llvm/Support/FileOutputBuffer.h b/contrib/llvm/include/llvm/Support/FileOutputBuffer.h index bcd35e3..cbc9c46 100644 --- a/contrib/llvm/include/llvm/Support/FileOutputBuffer.h +++ b/contrib/llvm/include/llvm/Support/FileOutputBuffer.h @@ -14,85 +14,79 @@ #ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H #define LLVM_SUPPORT_FILEOUTPUTBUFFER_H +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/FileSystem.h" namespace llvm { - class error_code; -template<class T> class OwningPtr; /// FileOutputBuffer - This interface provides simple way to create an in-memory -/// buffer which will be written to a file. During the lifetime of these +/// buffer which will be written to a file. During the lifetime of these /// objects, the content or existence of the specified file is undefined. That /// is, creating an OutputBuffer for a file may immediately remove the file. -/// If the FileOutputBuffer is committed, the target file's content will become -/// the buffer content at the time of the commit. If the FileOutputBuffer is +/// If the FileOutputBuffer is committed, the target file's content will become +/// the buffer content at the time of the commit. If the FileOutputBuffer is /// not committed, the file will be deleted in the FileOutputBuffer destructor. class FileOutputBuffer { public: enum { F_executable = 1 /// set the 'x' bit on the resulting file - }; + }; /// Factory method to create an OutputBuffer object which manages a read/write /// buffer of the specified size. When committed, the buffer will be written - /// to the file at the specified path. - static error_code create(StringRef FilePath, size_t Size, - OwningPtr<FileOutputBuffer> &Result, - unsigned Flags=0); - + /// to the file at the specified path. + static error_code create(StringRef FilePath, size_t Size, + OwningPtr<FileOutputBuffer> &Result, + unsigned Flags = 0); /// Returns a pointer to the start of the buffer. - uint8_t *getBufferStart() const { - return BufferStart; + uint8_t *getBufferStart() { + return (uint8_t*)Region->data(); } - + /// Returns a pointer to the end of the buffer. - uint8_t *getBufferEnd() const { - return BufferEnd; + uint8_t *getBufferEnd() { + return (uint8_t*)Region->data() + Region->size(); } - + /// Returns size of the buffer. size_t getBufferSize() const { - return BufferEnd - BufferStart; + return Region->size(); } - + /// Returns path where file will show up if buffer is committed. StringRef getPath() const { return FinalPath; } - - /// Flushes the content of the buffer to its file and deallocates the + + /// Flushes the content of the buffer to its file and deallocates the /// buffer. If commit() is not called before this object's destructor /// is called, the file is deleted in the destructor. The optional parameter /// is used if it turns out you want the file size to be smaller than /// initially requested. error_code commit(int64_t NewSmallerSize = -1); - + /// If this object was previously committed, the destructor just deletes /// this object. If this object was not committed, the destructor /// deallocates the buffer and the target file is never written. ~FileOutputBuffer(); - private: FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; -protected: - FileOutputBuffer(uint8_t *Start, uint8_t *End, - StringRef Path, StringRef TempPath); - - uint8_t *BufferStart; - uint8_t *BufferEnd; + + FileOutputBuffer(llvm::sys::fs::mapped_file_region *R, + StringRef Path, StringRef TempPath); + + OwningPtr<llvm::sys::fs::mapped_file_region> Region; SmallString<128> FinalPath; SmallString<128> TempPath; }; - - - } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/FileSystem.h b/contrib/llvm/include/llvm/Support/FileSystem.h index b455b28..ffa6427 100644 --- a/contrib/llvm/include/llvm/Support/FileSystem.h +++ b/contrib/llvm/include/llvm/Support/FileSystem.h @@ -24,8 +24,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_FILE_SYSTEM_H -#define LLVM_SUPPORT_FILE_SYSTEM_H +#ifndef LLVM_SUPPORT_FILESYSTEM_H +#define LLVM_SUPPORT_FILESYSTEM_H #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" @@ -602,12 +602,12 @@ private: void *FileMappingHandle; #endif - error_code init(int FD, uint64_t Offset); + error_code init(int FD, bool CloseFD, uint64_t Offset); public: typedef char char_type; -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES mapped_file_region(mapped_file_region&&); mapped_file_region &operator =(mapped_file_region&&); #endif @@ -633,8 +633,10 @@ public: error_code &ec); /// \param fd An open file descriptor to map. mapped_file_region takes - /// ownership. It must have been opended in the correct mode. + /// ownership if closefd is true. It must have been opended in the correct + /// mode. mapped_file_region(int fd, + bool closefd, mapmode mode, uint64_t length, uint64_t offset, diff --git a/contrib/llvm/include/llvm/Support/FormattedStream.h b/contrib/llvm/include/llvm/Support/FormattedStream.h index 21635dc..2e4bd5a 100644 --- a/contrib/llvm/include/llvm/Support/FormattedStream.h +++ b/contrib/llvm/include/llvm/Support/FormattedStream.h @@ -17,125 +17,125 @@ #include "llvm/Support/raw_ostream.h" -namespace llvm -{ - /// formatted_raw_ostream - Formatted raw_fd_ostream to handle - /// asm-specific constructs. +namespace llvm { + +/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track +/// of column position, allowing padding out to specific column boundaries. +/// +class formatted_raw_ostream : public raw_ostream { +public: + /// DELETE_STREAM - Tell the destructor to delete the held stream. /// - class formatted_raw_ostream : public raw_ostream { - public: - /// DELETE_STREAM - Tell the destructor to delete the held stream. - /// - static const bool DELETE_STREAM = true; - - /// PRESERVE_STREAM - Tell the destructor to not delete the held - /// stream. - /// - static const bool PRESERVE_STREAM = false; - - private: - /// TheStream - The real stream we output to. We set it to be - /// unbuffered, since we're already doing our own buffering. - /// - raw_ostream *TheStream; - - /// DeleteStream - Do we need to delete TheStream in the - /// destructor? - /// - bool DeleteStream; - - /// ColumnScanned - The current output column of the data that's - /// been flushed and the portion of the buffer that's been - /// scanned. The column scheme is zero-based. - /// - unsigned ColumnScanned; - - /// Scanned - This points to one past the last character in the - /// buffer we've scanned. - /// - const char *Scanned; - - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; - - /// current_pos - Return the current position within the stream, - /// not counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE { - // Our current position in the stream is all the contents which have been - // written to the underlying stream (*not* the current position of the - // underlying stream). - return TheStream->tell(); - } - - /// ComputeColumn - Examine the given output buffer and figure out which - /// column we end up in after output. - /// - void ComputeColumn(const char *Ptr, size_t size); - - public: - /// formatted_raw_ostream - Open the specified file for - /// writing. If an error occurs, information about the error is - /// put into ErrorInfo, and the stream should be immediately - /// destroyed; the string will be empty if no error occurred. - /// - /// As a side effect, the given Stream is set to be Unbuffered. - /// This is because formatted_raw_ostream does its own buffering, - /// so it doesn't want another layer of buffering to be happening - /// underneath it. - /// - formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) - : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { - setStream(Stream, Delete); - } - explicit formatted_raw_ostream() - : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { - Scanned = 0; - } - - ~formatted_raw_ostream() { - flush(); - releaseStream(); - } - - void setStream(raw_ostream &Stream, bool Delete = false) { - releaseStream(); - - TheStream = &Stream; - DeleteStream = Delete; - - // This formatted_raw_ostream inherits from raw_ostream, so it'll do its - // own buffering, and it doesn't need or want TheStream to do another - // layer of buffering underneath. Resize the buffer to what TheStream - // had been using, and tell TheStream not to do its own buffering. - if (size_t BufferSize = TheStream->GetBufferSize()) - SetBufferSize(BufferSize); - else - SetUnbuffered(); - TheStream->SetUnbuffered(); + static const bool DELETE_STREAM = true; + + /// PRESERVE_STREAM - Tell the destructor to not delete the held + /// stream. + /// + static const bool PRESERVE_STREAM = false; + +private: + /// TheStream - The real stream we output to. We set it to be + /// unbuffered, since we're already doing our own buffering. + /// + raw_ostream *TheStream; - Scanned = 0; - } - - /// PadToColumn - Align the output to some column number. If the current - /// column is already equal to or more than NewCol, PadToColumn inserts one - /// space. - /// - /// \param NewCol - The column to move to. - formatted_raw_ostream &PadToColumn(unsigned NewCol); - - private: - void releaseStream() { - // Delete the stream if needed. Otherwise, transfer the buffer - // settings from this raw_ostream back to the underlying stream. - if (!TheStream) - return; - if (DeleteStream) - delete TheStream; - else if (size_t BufferSize = GetBufferSize()) - TheStream->SetBufferSize(BufferSize); - else - TheStream->SetUnbuffered(); - } - }; + /// DeleteStream - Do we need to delete TheStream in the + /// destructor? + /// + bool DeleteStream; + + /// ColumnScanned - The current output column of the data that's + /// been flushed and the portion of the buffer that's been + /// scanned. The column scheme is zero-based. + /// + unsigned ColumnScanned; + + /// Scanned - This points to one past the last character in the + /// buffer we've scanned. + /// + const char *Scanned; + + virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + + /// current_pos - Return the current position within the stream, + /// not counting the bytes currently in the buffer. + virtual uint64_t current_pos() const LLVM_OVERRIDE { + // Our current position in the stream is all the contents which have been + // written to the underlying stream (*not* the current position of the + // underlying stream). + return TheStream->tell(); + } + + /// ComputeColumn - Examine the given output buffer and figure out which + /// column we end up in after output. + /// + void ComputeColumn(const char *Ptr, size_t size); + +public: + /// formatted_raw_ostream - Open the specified file for + /// writing. If an error occurs, information about the error is + /// put into ErrorInfo, and the stream should be immediately + /// destroyed; the string will be empty if no error occurred. + /// + /// As a side effect, the given Stream is set to be Unbuffered. + /// This is because formatted_raw_ostream does its own buffering, + /// so it doesn't want another layer of buffering to be happening + /// underneath it. + /// + formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) + : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + setStream(Stream, Delete); + } + explicit formatted_raw_ostream() + : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + Scanned = 0; + } + + ~formatted_raw_ostream() { + flush(); + releaseStream(); + } + + void setStream(raw_ostream &Stream, bool Delete = false) { + releaseStream(); + + TheStream = &Stream; + DeleteStream = Delete; + + // This formatted_raw_ostream inherits from raw_ostream, so it'll do its + // own buffering, and it doesn't need or want TheStream to do another + // layer of buffering underneath. Resize the buffer to what TheStream + // had been using, and tell TheStream not to do its own buffering. + if (size_t BufferSize = TheStream->GetBufferSize()) + SetBufferSize(BufferSize); + else + SetUnbuffered(); + TheStream->SetUnbuffered(); + + Scanned = 0; + } + + /// PadToColumn - Align the output to some column number. If the current + /// column is already equal to or more than NewCol, PadToColumn inserts one + /// space. + /// + /// \param NewCol - The column to move to. + formatted_raw_ostream &PadToColumn(unsigned NewCol); + +private: + void releaseStream() { + // Delete the stream if needed. Otherwise, transfer the buffer + // settings from this raw_ostream back to the underlying stream. + if (!TheStream) + return; + if (DeleteStream) + delete TheStream; + else if (size_t BufferSize = GetBufferSize()) + TheStream->SetBufferSize(BufferSize); + else + TheStream->SetUnbuffered(); + } +}; /// fouts() - This returns a reference to a formatted_raw_ostream for /// standard output. Use it like: fouts() << "foo" << "bar"; diff --git a/contrib/llvm/include/llvm/Support/GCOV.h b/contrib/llvm/include/llvm/Support/GCOV.h index e552315..f1040f5 100644 --- a/contrib/llvm/include/llvm/Support/GCOV.h +++ b/contrib/llvm/include/llvm/Support/GCOV.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_GCOV_H -#define LLVM_GCOV_H +#ifndef LLVM_SUPPORT_GCOV_H +#define LLVM_SUPPORT_GCOV_H #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" diff --git a/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h index ef92c95..5a90553 100644 --- a/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H -#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H +#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H +#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H -#include "llvm/User.h" -#include "llvm/DerivedTypes.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/User.h" namespace llvm { template<typename ItTy = User::const_op_iterator> @@ -83,15 +83,15 @@ namespace llvm { typedef generic_gep_type_iterator<> gep_type_iterator; inline gep_type_iterator gep_type_begin(const User *GEP) { - return gep_type_iterator::begin(GEP->getOperand(0)->getType(), - GEP->op_begin()+1); + return gep_type_iterator::begin + (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); } inline gep_type_iterator gep_type_end(const User *GEP) { return gep_type_iterator::end(GEP->op_end()); } inline gep_type_iterator gep_type_begin(const User &GEP) { - return gep_type_iterator::begin(GEP.getOperand(0)->getType(), - GEP.op_begin()+1); + return gep_type_iterator::begin + (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); } inline gep_type_iterator gep_type_end(const User &GEP) { return gep_type_iterator::end(GEP.op_end()); diff --git a/contrib/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm/include/llvm/Support/GraphWriter.h index f178b0c..22181d4 100644 --- a/contrib/llvm/include/llvm/Support/GraphWriter.h +++ b/contrib/llvm/include/llvm/Support/GraphWriter.h @@ -23,17 +23,21 @@ #ifndef LLVM_SUPPORT_GRAPHWRITER_H #define LLVM_SUPPORT_GRAPHWRITER_H -#include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/Support/DOTGraphTraits.h" #include "llvm/Support/Path.h" -#include <vector> +#include "llvm/Support/raw_ostream.h" #include <cassert> +#include <vector> namespace llvm { namespace DOT { // Private functions... std::string EscapeString(const std::string &Label); + + /// \brief Get a color string for this node number. Simply round-robin selects + /// from a reasonable number of colors. + StringRef getColorString(unsigned NodeNumber); } namespace GraphProgram { @@ -173,6 +177,10 @@ public: // If we should include the address of the node in the label, do so now. if (DTraits.hasNodeAddressLabel(Node, G)) O << "|" << static_cast<const void*>(Node); + + std::string NodeDesc = DTraits.getNodeDescription(Node, G); + if (!NodeDesc.empty()) + O << "|" << DOT::EscapeString(NodeDesc); } std::string edgeSourceLabels; @@ -193,6 +201,10 @@ public: // If we should include the address of the node in the label, do so now. if (DTraits.hasNodeAddressLabel(Node, G)) O << "|" << static_cast<const void*>(Node); + + std::string NodeDesc = DTraits.getNodeDescription(Node, G); + if (!NodeDesc.empty()) + O << "|" << DOT::EscapeString(NodeDesc); } if (DTraits.hasEdgeDestLabels()) { diff --git a/contrib/llvm/include/llvm/Support/Host.h b/contrib/llvm/include/llvm/Support/Host.h index b331016..3a44405 100644 --- a/contrib/llvm/include/llvm/Support/Host.h +++ b/contrib/llvm/include/llvm/Support/Host.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_HOST_H -#define LLVM_SYSTEM_HOST_H +#ifndef LLVM_SUPPORT_HOST_H +#define LLVM_SUPPORT_HOST_H #include "llvm/ADT/StringMap.h" #include <string> @@ -42,6 +42,10 @@ namespace sys { /// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM std::string getDefaultTargetTriple(); + /// getProcessTriple() - Return an appropriate target triple for generating + /// code to be loaded into the current process, e.g. when using the JIT. + std::string getProcessTriple(); + /// getHostCPUName - Get the LLVM name for the host CPU. The particular format /// of the name is target dependent, and suitable for passing as -mcpu to the /// target which matches the host. diff --git a/contrib/llvm/include/llvm/Support/IRReader.h b/contrib/llvm/include/llvm/Support/IRReader.h deleted file mode 100644 index 6d8a9b3..0000000 --- a/contrib/llvm/include/llvm/Support/IRReader.h +++ /dev/null @@ -1,112 +0,0 @@ -//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- 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 functions for reading LLVM IR. They support both -// Bitcode and Assembly, automatically detecting the input format. -// -// These functions must be defined in a header file in order to avoid -// library dependencies, since they reference both Bitcode and Assembly -// functions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_IRREADER_H -#define LLVM_SUPPORT_IRREADER_H - -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Assembly/Parser.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/system_error.h" - -namespace llvm { - - /// If the given MemoryBuffer holds a bitcode image, return a Module for it - /// which does lazy deserialization of function bodies. Otherwise, attempt to - /// parse it as LLVM Assembly and return a fully populated Module. This - /// function *always* takes ownership of the given MemoryBuffer. - inline Module *getLazyIRModule(MemoryBuffer *Buffer, - SMDiagnostic &Err, - LLVMContext &Context) { - if (isBitcode((const unsigned char *)Buffer->getBufferStart(), - (const unsigned char *)Buffer->getBufferEnd())) { - std::string ErrMsg; - Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg); - if (M == 0) { - Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, - ErrMsg); - // ParseBitcodeFile does not take ownership of the Buffer in the - // case of an error. - delete Buffer; - } - return M; - } - - return ParseAssembly(Buffer, 0, Err, Context); - } - - /// If the given file holds a bitcode image, return a Module - /// for it which does lazy deserialization of function bodies. Otherwise, - /// attempt to parse it as LLVM Assembly and return a fully populated - /// Module. - inline Module *getLazyIRFileModule(const std::string &Filename, - SMDiagnostic &Err, - LLVMContext &Context) { - OwningPtr<MemoryBuffer> File; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) { - Err = SMDiagnostic(Filename, SourceMgr::DK_Error, - "Could not open input file: " + ec.message()); - return 0; - } - - return getLazyIRModule(File.take(), Err, Context); - } - - /// If the given MemoryBuffer holds a bitcode image, return a Module - /// for it. Otherwise, attempt to parse it as LLVM Assembly and return - /// a Module for it. This function *always* takes ownership of the given - /// MemoryBuffer. - inline Module *ParseIR(MemoryBuffer *Buffer, - SMDiagnostic &Err, - LLVMContext &Context) { - if (isBitcode((const unsigned char *)Buffer->getBufferStart(), - (const unsigned char *)Buffer->getBufferEnd())) { - std::string ErrMsg; - Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg); - if (M == 0) - Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, - ErrMsg); - // ParseBitcodeFile does not take ownership of the Buffer. - delete Buffer; - return M; - } - - return ParseAssembly(Buffer, 0, Err, Context); - } - - /// If the given file holds a bitcode image, return a Module for it. - /// Otherwise, attempt to parse it as LLVM Assembly and return a Module - /// for it. - inline Module *ParseIRFile(const std::string &Filename, - SMDiagnostic &Err, - LLVMContext &Context) { - OwningPtr<MemoryBuffer> File; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) { - Err = SMDiagnostic(Filename, SourceMgr::DK_Error, - "Could not open input file: " + ec.message()); - return 0; - } - - return ParseIR(File.take(), Err, Context); - } - -} - -#endif diff --git a/contrib/llvm/include/llvm/Support/IncludeFile.h b/contrib/llvm/include/llvm/Support/IncludeFile.h index a931972..2067e34 100644 --- a/contrib/llvm/include/llvm/Support/IncludeFile.h +++ b/contrib/llvm/include/llvm/Support/IncludeFile.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_INCLUDEFILE_H -#define LLVM_SYSTEM_INCLUDEFILE_H +#ifndef LLVM_SUPPORT_INCLUDEFILE_H +#define LLVM_SUPPORT_INCLUDEFILE_H /// This macro is the public interface that IncludeFile.h exports. This gives /// us the option to implement the "link the definition" capability in any diff --git a/contrib/llvm/include/llvm/Support/InstIterator.h b/contrib/llvm/include/llvm/Support/InstIterator.h index 7d3f883..ac936a1 100644 --- a/contrib/llvm/include/llvm/Support/InstIterator.h +++ b/contrib/llvm/include/llvm/Support/InstIterator.h @@ -19,8 +19,8 @@ #ifndef LLVM_SUPPORT_INSTITERATOR_H #define LLVM_SUPPORT_INSTITERATOR_H -#include "llvm/BasicBlock.h" -#include "llvm/Function.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/IntegersSubset.h b/contrib/llvm/include/llvm/Support/IntegersSubset.h index 03039fd..ce34d78 100644 --- a/contrib/llvm/include/llvm/Support/IntegersSubset.h +++ b/contrib/llvm/include/llvm/Support/IntegersSubset.h @@ -15,15 +15,14 @@ // //===----------------------------------------------------------------------===// -#ifndef CONSTANTRANGESSET_H_ -#define CONSTANTRANGESSET_H_ +#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H +#define LLVM_SUPPORT_INTEGERSSUBSET_H +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" #include <list> -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" - namespace llvm { // The IntItem is a wrapper for APInt. @@ -538,4 +537,4 @@ public: } -#endif /* CONSTANTRANGESSET_H_ */ +#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */ diff --git a/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h b/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h index 7635d5e..641ce78 100644 --- a/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h +++ b/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h @@ -17,8 +17,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CRSBUILDER_H_ -#define CRSBUILDER_H_ +#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H +#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H #include "llvm/Support/IntegersSubset.h" #include <list> @@ -585,4 +585,4 @@ typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB; } -#endif /* CRSBUILDER_H_ */ +#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */ diff --git a/contrib/llvm/include/llvm/Support/LEB128.h b/contrib/llvm/include/llvm/Support/LEB128.h index b52e5bc..802b4f3 100644 --- a/contrib/llvm/include/llvm/Support/LEB128.h +++ b/contrib/llvm/include/llvm/Support/LEB128.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_LEB128_H -#define LLVM_SYSTEM_LEB128_H +#ifndef LLVM_SUPPORT_LEB128_H +#define LLVM_SUPPORT_LEB128_H #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/include/llvm/Support/Locale.h b/contrib/llvm/include/llvm/Support/Locale.h index b0f1295..b384d58 100644 --- a/contrib/llvm/include/llvm/Support/Locale.h +++ b/contrib/llvm/include/llvm/Support/Locale.h @@ -1,5 +1,5 @@ -#ifndef LLVM_SUPPORT_LOCALE -#define LLVM_SUPPORT_LOCALE +#ifndef LLVM_SUPPORT_LOCALE_H +#define LLVM_SUPPORT_LOCALE_H #include "llvm/ADT/StringRef.h" @@ -14,4 +14,4 @@ bool isPrint(int c); } } -#endif // LLVM_SUPPORT_LOCALE +#endif // LLVM_SUPPORT_LOCALE_H diff --git a/contrib/llvm/include/llvm/Support/LockFileManager.h b/contrib/llvm/include/llvm/Support/LockFileManager.h index 8c4a760..9df8675 100644 --- a/contrib/llvm/include/llvm/Support/LockFileManager.h +++ b/contrib/llvm/include/llvm/Support/LockFileManager.h @@ -41,6 +41,7 @@ public: }; private: + SmallString<128> FileName; SmallString<128> LockFileName; SmallString<128> UniqueLockFileName; diff --git a/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h index 11f9e63..d6ae58d 100644 --- a/contrib/llvm/include/llvm/Support/MathExtras.h +++ b/contrib/llvm/include/llvm/Support/MathExtras.h @@ -16,6 +16,10 @@ #include "llvm/Support/SwapByteOrder.h" +#ifdef _MSC_VER +# include <intrin.h> +#endif + namespace llvm { // NOTE: The following support functions use the _32/_64 extensions instead of @@ -61,7 +65,7 @@ inline bool isShiftedInt(int64_t x) { /// isUInt - Checks if an unsigned integer fits into the given bit width. template<unsigned N> inline bool isUInt(uint64_t x) { - return N >= 64 || x < (UINT64_C(1)<<N); + return N >= 64 || x < (UINT64_C(1)<<(N)); } // Template specializations to get better code for common cases. template<> @@ -254,7 +258,10 @@ inline unsigned CountTrailingZeros_32(uint32_t Value) { 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; - return Mod37BitPosition[(-Value & Value) % 37]; + // Replace "-Value" by "1+~Value" in the following commented code to avoid + // MSVC warning C4146 + // return Mod37BitPosition[(-Value & Value) % 37]; + return Mod37BitPosition[((1 + ~Value) & Value) % 37]; #endif } @@ -281,7 +288,10 @@ inline unsigned CountTrailingZeros_64(uint64_t Value) { 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, 7, 48, 35, 6, 34, 33, 0 }; - return Mod67Position[(-Value & Value) % 67]; + // Replace "-Value" by "1+~Value" in the following commented code to avoid + // MSVC warning C4146 + // return Mod67Position[(-Value & Value) % 67]; + return Mod67Position[((1 + ~Value) & Value) % 67]; #endif } @@ -416,7 +426,11 @@ int IsInf(double d); /// alignment that may be assumed after adding the two together. inline uint64_t MinAlign(uint64_t A, uint64_t B) { // The largest power of 2 that divides both A and B. - return (A | B) & -(A | B); + // + // Replace "-Value" by "1+~Value" in the following commented code to avoid + // MSVC warning C4146 + // return (A | B) & -(A | B); + return (A | B) & (1 + ~(A | B)); } /// NextPowerOf2 - Returns the next power of two (in 64-bits) diff --git a/contrib/llvm/include/llvm/Support/Memory.h b/contrib/llvm/include/llvm/Support/Memory.h index 025eee7..a08c796 100644 --- a/contrib/llvm/include/llvm/Support/Memory.h +++ b/contrib/llvm/include/llvm/Support/Memory.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_MEMORY_H -#define LLVM_SYSTEM_MEMORY_H +#ifndef LLVM_SUPPORT_MEMORY_H +#define LLVM_SUPPORT_MEMORY_H #include "llvm/Support/DataTypes.h" #include "llvm/Support/system_error.h" diff --git a/contrib/llvm/include/llvm/Support/MemoryObject.h b/contrib/llvm/include/llvm/Support/MemoryObject.h index b778b08..732b0f0 100644 --- a/contrib/llvm/include/llvm/Support/MemoryObject.h +++ b/contrib/llvm/include/llvm/Support/MemoryObject.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MEMORYOBJECT_H -#define MEMORYOBJECT_H +#ifndef LLVM_SUPPORT_MEMORYOBJECT_H +#define LLVM_SUPPORT_MEMORYOBJECT_H #include "llvm/Support/DataTypes.h" diff --git a/contrib/llvm/include/llvm/Support/Mutex.h b/contrib/llvm/include/llvm/Support/Mutex.h index 6abc533..496a438 100644 --- a/contrib/llvm/include/llvm/Support/Mutex.h +++ b/contrib/llvm/include/llvm/Support/Mutex.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_MUTEX_H -#define LLVM_SYSTEM_MUTEX_H +#ifndef LLVM_SUPPORT_MUTEX_H +#define LLVM_SUPPORT_MUTEX_H #include "llvm/Support/Compiler.h" #include "llvm/Support/Threading.h" diff --git a/contrib/llvm/include/llvm/Support/NoFolder.h b/contrib/llvm/include/llvm/Support/NoFolder.h index 8e41a64..ecfbbaa 100644 --- a/contrib/llvm/include/llvm/Support/NoFolder.h +++ b/contrib/llvm/include/llvm/Support/NoFolder.h @@ -23,8 +23,8 @@ #define LLVM_SUPPORT_NOFOLDER_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/PassNameParser.h b/contrib/llvm/include/llvm/Support/PassNameParser.h index a24a6f0..317416c 100644 --- a/contrib/llvm/include/llvm/Support/PassNameParser.h +++ b/contrib/llvm/include/llvm/Support/PassNameParser.h @@ -20,11 +20,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H -#define LLVM_SUPPORT_PASS_NAME_PARSER_H +#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H +#define LLVM_SUPPORT_PASSNAMEPARSER_H -#include "llvm/Pass.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/include/llvm/Support/PathV1.h b/contrib/llvm/include/llvm/Support/PathV1.h index 643ee8c..86328f0 100644 --- a/contrib/llvm/include/llvm/Support/PathV1.h +++ b/contrib/llvm/include/llvm/Support/PathV1.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_PATH_H -#define LLVM_SYSTEM_PATH_H +#ifndef LLVM_SUPPORT_PATHV1_H +#define LLVM_SUPPORT_PATHV1_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/include/llvm/Support/PatternMatch.h b/contrib/llvm/include/llvm/Support/PatternMatch.h index 221fa8b..9fbe434 100644 --- a/contrib/llvm/include/llvm/Support/PatternMatch.h +++ b/contrib/llvm/include/llvm/Support/PatternMatch.h @@ -29,9 +29,11 @@ #ifndef LLVM_SUPPORT_PATTERNMATCH_H #define LLVM_SUPPORT_PATTERNMATCH_H -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/Operator.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Operator.h" +#include "llvm/Support/CallSite.h" namespace llvm { namespace PatternMatch { @@ -41,13 +43,13 @@ 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); @@ -56,8 +58,8 @@ struct OneUse_match { template<typename T> inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; } - - + + template<typename Class> struct class_match { template<typename ITy> @@ -74,7 +76,53 @@ inline class_match<ConstantInt> m_ConstantInt() { inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } inline class_match<Constant> m_Constant() { return class_match<Constant>(); } - + +/// Matching combinators +template<typename LTy, typename RTy> +struct match_combine_or { + LTy L; + RTy R; + + match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { } + + template<typename ITy> + bool match(ITy *V) { + if (L.match(V)) + return true; + if (R.match(V)) + return true; + return false; + } +}; + +template<typename LTy, typename RTy> +struct match_combine_and { + LTy L; + RTy R; + + match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) { } + + template<typename ITy> + bool match(ITy *V) { + if (L.match(V)) + if (R.match(V)) + return true; + return false; + } +}; + +/// Combine two pattern matchers matching L || R +template<typename LTy, typename RTy> +inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) { + return match_combine_or<LTy, RTy>(L, R); +} + +/// Combine two pattern matchers matching L && R +template<typename LTy, typename RTy> +inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) { + return match_combine_and<LTy, RTy>(L, R); +} + struct match_zero { template<typename ITy> bool match(ITy *V) { @@ -83,12 +131,33 @@ struct match_zero { return false; } }; - + /// m_Zero() - Match an arbitrary zero/null constant. This includes /// zero_initializer for vectors and ConstantPointerNull for pointers. inline match_zero m_Zero() { return match_zero(); } - - + +struct match_neg_zero { + template<typename ITy> + bool match(ITy *V) { + if (const Constant *C = dyn_cast<Constant>(V)) + return C->isNegativeZeroValue(); + return false; + } +}; + +/// m_NegZero() - Match an arbitrary zero/null constant. This includes +/// zero_initializer for vectors and ConstantPointerNull for pointers. For +/// floating point constants, this will match negative zero but not positive +/// zero +inline match_neg_zero m_NegZero() { return match_neg_zero(); } + +/// m_AnyZero() - Match an arbitrary zero/null constant. This includes +/// zero_initializer for vectors and ConstantPointerNull for pointers. For +/// floating point constants, this will match negative zero and positive zero +inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() { + return m_CombineOr(m_Zero(), m_NegZero()); +} + struct apint_match { const APInt *&Res; apint_match(const APInt *&R) : Res(R) {} @@ -98,28 +167,22 @@ struct apint_match { Res = &CI->getValue(); return true; } - // FIXME: Remove this. - if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) - if (ConstantInt *CI = - dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) { - Res = &CI->getValue(); - return true; - } - if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) - if (ConstantInt *CI = - dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) { - Res = &CI->getValue(); - return true; - } + if (V->getType()->isVectorTy()) + if (const Constant *C = dyn_cast<Constant>(V)) + if (ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(C->getSplatValue())) { + Res = &CI->getValue(); + return true; + } return false; } }; - + /// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the /// specified pointer to the contained APInt. inline apint_match m_APInt(const APInt *&Res) { return Res; } - + template<int64_t Val> struct constantint_match { template<typename ITy> @@ -151,17 +214,15 @@ struct cst_pred_ty : public Predicate { bool match(ITy *V) { if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) return this->isValue(CI->getValue()); - // FIXME: Remove this. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) - if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) - return this->isValue(CI->getValue()); - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) - if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) - return this->isValue(CI->getValue()); + if (V->getType()->isVectorTy()) + if (const Constant *C = dyn_cast<Constant>(V)) + if (const ConstantInt *CI = + dyn_cast_or_null<ConstantInt>(C->getSplatValue())) + return this->isValue(CI->getValue()); return false; } }; - + /// api_pred_ty - This helper class is used to match scalar and vector constants /// that satisfy a specified predicate, and bind them to an APInt. template<typename Predicate> @@ -175,27 +236,19 @@ struct api_pred_ty : public Predicate { Res = &CI->getValue(); return true; } - - // FIXME: remove. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) - if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - - if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V)) - if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } + if (V->getType()->isVectorTy()) + if (const Constant *C = dyn_cast<Constant>(V)) + if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) + if (this->isValue(CI->getValue())) { + Res = &CI->getValue(); + return true; + } return false; } }; - - + + struct is_one { bool isValue(const APInt &C) { return C == 1; } }; @@ -203,11 +256,11 @@ struct is_one { /// m_One() - Match an integer 1 or a vector with all elements equal to 1. inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); } inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; } - + struct is_all_ones { bool isValue(const APInt &C) { return C.isAllOnesValue(); } }; - + /// m_AllOnes() - Match an integer or vector with all bits set to true. inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();} inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; } @@ -252,6 +305,9 @@ inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } /// m_Constant - Match a Constant, capturing the value if we match. inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } +/// m_ConstantFP - Match a ConstantFP, capturing the value if we match. +inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } + /// specificval_ty - Match a specified Value*. struct specificval_ty { const Value *Val; @@ -266,10 +322,35 @@ struct specificval_ty { /// m_Specific - Match if we have a specific specified value. inline specificval_ty m_Specific(const Value *V) { return V; } +/// Match a specified floating point value or vector of all elements of that +/// value. +struct specific_fpval { + double Val; + specific_fpval(double V) : Val(V) {} + + template<typename ITy> + bool match(ITy *V) { + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) + return CFP->isExactlyValue(Val); + if (V->getType()->isVectorTy()) + if (const Constant *C = dyn_cast<Constant>(V)) + if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue())) + return CFP->isExactlyValue(Val); + return false; + } +}; + +/// Match a specific floating point value or vector with all elements equal to +/// the value. +inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); } + +/// Match a float 1.0 or vector with all elements equal to 1.0. +inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); } + struct bind_const_intval_ty { uint64_t &VR; bind_const_intval_ty(uint64_t &V) : VR(V) {} - + template<typename ITy> bool match(ITy *V) { if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) @@ -284,7 +365,7 @@ struct bind_const_intval_ty { /// 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. // @@ -583,7 +664,7 @@ inline CastClass_match<OpTy, Instruction::BitCast> m_BitCast(const OpTy &Op) { return CastClass_match<OpTy, Instruction::BitCast>(Op); } - + /// m_PtrToInt template<typename OpTy> inline CastClass_match<OpTy, Instruction::PtrToInt> @@ -611,7 +692,7 @@ inline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) { return CastClass_match<OpTy, Instruction::ZExt>(Op); } - + //===----------------------------------------------------------------------===// // Matchers for unary operators @@ -700,6 +781,25 @@ inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; } // Matchers for control flow. // +struct br_match { + BasicBlock *&Succ; + br_match(BasicBlock *&Succ) + : Succ(Succ) { + } + + template<typename OpTy> + bool match(OpTy *V) { + if (BranchInst *BI = dyn_cast<BranchInst>(V)) + if (BI->isUnconditional()) { + Succ = BI->getSuccessor(0); + return true; + } + return false; + } +}; + +inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); } + template<typename Cond_t> struct brc_match { Cond_t Cond; @@ -818,6 +918,102 @@ m_UMin(const LHS &L, const RHS &R) { return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R); } +template<typename Opnd_t> +struct Argument_match { + unsigned OpI; + Opnd_t Val; + Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { } + + template<typename OpTy> + bool match(OpTy *V) { + CallSite CS(V); + return CS.isCall() && Val.match(CS.getArgument(OpI)); + } +}; + +/// Match an argument +template<unsigned OpI, typename Opnd_t> +inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) { + return Argument_match<Opnd_t>(OpI, Op); +} + +/// Intrinsic matchers. +struct IntrinsicID_match { + unsigned ID; + IntrinsicID_match(unsigned IntrID) : ID(IntrID) { } + + template<typename OpTy> + bool match(OpTy *V) { + IntrinsicInst *II = dyn_cast<IntrinsicInst>(V); + return II && II->getIntrinsicID() == ID; + } +}; + +/// Intrinsic matches are combinations of ID matchers, and argument +/// matchers. Higher arity matcher are defined recursively in terms of and-ing +/// them with lower arity matchers. Here's some convenient typedefs for up to +/// several arguments, and more can be added as needed +template <typename T0 = void, typename T1 = void, typename T2 = void, + typename T3 = void, typename T4 = void, typename T5 = void, + typename T6 = void, typename T7 = void, typename T8 = void, + typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty; +template <typename T0> +struct m_Intrinsic_Ty<T0> { + typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty; +}; +template <typename T0, typename T1> +struct m_Intrinsic_Ty<T0, T1> { + typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, + Argument_match<T1> > Ty; +}; +template <typename T0, typename T1, typename T2> +struct m_Intrinsic_Ty<T0, T1, T2> { + typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, + Argument_match<T2> > Ty; +}; +template <typename T0, typename T1, typename T2, typename T3> +struct m_Intrinsic_Ty<T0, T1, T2, T3> { + typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, + Argument_match<T3> > Ty; +}; + +/// Match intrinsic calls like this: +/// m_Intrinsic<Intrinsic::fabs>(m_Value(X)) +template <unsigned IntrID> +inline IntrinsicID_match +m_Intrinsic() { return IntrinsicID_match(IntrID); } + +template<unsigned IntrID, typename T0> +inline typename m_Intrinsic_Ty<T0>::Ty +m_Intrinsic(const T0 &Op0) { + return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0)); +} + +template<unsigned IntrID, typename T0, typename T1> +inline typename m_Intrinsic_Ty<T0, T1>::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1) { + return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1)); +} + +template<unsigned IntrID, typename T0, typename T1, typename T2> +inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) { + return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2)); +} + +template<unsigned IntrID, typename T0, typename T1, typename T2, typename T3> +inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty +m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { + return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3)); +} + +// Helper intrinsic matching specializations +template<typename Opnd0> +inline typename m_Intrinsic_Ty<Opnd0>::Ty +m_BSwap(const Opnd0 &Op0) { + return m_Intrinsic<Intrinsic::bswap>(Op0); +} + } // end namespace PatternMatch } // end namespace llvm diff --git a/contrib/llvm/include/llvm/Support/PredIteratorCache.h b/contrib/llvm/include/llvm/Support/PredIteratorCache.h index bb66a8e..c5fb780 100644 --- a/contrib/llvm/include/llvm/Support/PredIteratorCache.h +++ b/contrib/llvm/include/llvm/Support/PredIteratorCache.h @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Allocator.h" -#include "llvm/Support/CFG.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/CFG.h" #ifndef LLVM_SUPPORT_PREDITERATORCACHE_H #define LLVM_SUPPORT_PREDITERATORCACHE_H diff --git a/contrib/llvm/include/llvm/Support/Process.h b/contrib/llvm/include/llvm/Support/Process.h index 088897c..4256d4a 100644 --- a/contrib/llvm/include/llvm/Support/Process.h +++ b/contrib/llvm/include/llvm/Support/Process.h @@ -6,152 +6,246 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file declares the llvm::sys::Process class. -// +/// \file +/// +/// Provides a library for accessing information about this process and other +/// processes on the operating system. Also provides means of spawning +/// subprocess for commands. The design of this library is modeled after the +/// proposed design of the Boost.Process library, and is design specifically to +/// follow the style of standard libraries and potentially become a proposal +/// for a standard library. +/// +/// This file declares the llvm::sys::Process class which contains a collection +/// of legacy static interfaces for extracting various information about the +/// current process. The goal is to migrate users of this API over to the new +/// interfaces. +/// //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_PROCESS_H -#define LLVM_SYSTEM_PROCESS_H +#ifndef LLVM_SUPPORT_PROCESS_H +#define LLVM_SUPPORT_PROCESS_H +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/TimeValue.h" namespace llvm { namespace sys { - /// This class provides an abstraction for getting information about the - /// currently executing process. - /// @since 1.4 - /// @brief An abstraction for operating system processes. - class Process { - /// @name Accessors - /// @{ - public: - /// This static function will return the operating system's virtual memory - /// page size. - /// @returns The number of bytes in a virtual memory page. - /// @brief Get the virtual memory page size - static unsigned GetPageSize(); - - /// This static function will return the total amount of memory allocated - /// by the process. This only counts the memory allocated via the malloc, - /// calloc and realloc functions and includes any "free" holes in the - /// allocated space. - /// @brief Return process memory usage. - static size_t GetMallocUsage(); - - /// This static function will return the total memory usage of the - /// process. This includes code, data, stack and mapped pages usage. Notei - /// that the value returned here is not necessarily the Running Set Size, - /// it is the total virtual memory usage, regardless of mapped state of - /// that memory. - static size_t GetTotalMemoryUsage(); - - /// This static function will set \p user_time to the amount of CPU time - /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU - /// time spent in system (kernel) mode. If the operating system does not - /// support collection of these metrics, a zero TimeValue will be for both - /// values. - static void GetTimeUsage( - TimeValue& elapsed, - ///< Returns the TimeValue::now() giving current time - TimeValue& user_time, - ///< Returns the current amount of user time for the process - TimeValue& sys_time - ///< Returns the current amount of system time for the process - ); - - /// This static function will return the process' current user id number. - /// Not all operating systems support this feature. Where it is not - /// supported, the function should return 65536 as the value. - static int GetCurrentUserId(); - - /// This static function will return the process' current group id number. - /// Not all operating systems support this feature. Where it is not - /// supported, the function should return 65536 as the value. - static int GetCurrentGroupId(); - - /// This function makes the necessary calls to the operating system to - /// prevent core files or any other kind of large memory dumps that can - /// occur when a program fails. - /// @brief Prevent core file generation. - static void PreventCoreFiles(); - - /// This function determines if the standard input is connected directly - /// to a user's input (keyboard probably), rather than coming from a file - /// or pipe. - static bool StandardInIsUserInput(); - - /// This function determines if the standard output is connected to a - /// "tty" or "console" window. That is, the output would be displayed to - /// the user rather than being put on a pipe or stored in a file. - static bool StandardOutIsDisplayed(); - - /// This function determines if the standard error is connected to a - /// "tty" or "console" window. That is, the output would be displayed to - /// the user rather than being put on a pipe or stored in a file. - static bool StandardErrIsDisplayed(); - - /// This function determines if the given file descriptor is connected to - /// a "tty" or "console" window. That is, the output would be displayed to - /// the user rather than being put on a pipe or stored in a file. - static bool FileDescriptorIsDisplayed(int fd); - - /// This function determines if the given file descriptor is displayd and - /// supports colors. - static bool FileDescriptorHasColors(int fd); - - /// This function determines the number of columns in the window - /// if standard output is connected to a "tty" or "console" - /// window. If standard output is not connected to a tty or - /// console, or if the number of columns cannot be determined, - /// this routine returns zero. - static unsigned StandardOutColumns(); - - /// This function determines the number of columns in the window - /// if standard error is connected to a "tty" or "console" - /// window. If standard error is not connected to a tty or - /// console, or if the number of columns cannot be determined, - /// this routine returns zero. - static unsigned StandardErrColumns(); - - /// This function determines whether the terminal connected to standard - /// output supports colors. If standard output is not connected to a - /// terminal, this function returns false. - static bool StandardOutHasColors(); - - /// This function determines whether the terminal connected to standard - /// error supports colors. If standard error is not connected to a - /// terminal, this function returns false. - static bool StandardErrHasColors(); - - /// Whether changing colors requires the output to be flushed. - /// This is needed on systems that don't support escape sequences for - /// changing colors. - static bool ColorNeedsFlush(); - - /// This function returns the colorcode escape sequences. - /// If ColorNeedsFlush() is true then this function will change the colors - /// and return an empty escape sequence. In that case it is the - /// responsibility of the client to flush the output stream prior to - /// calling this function. - static const char *OutputColor(char c, bool bold, bool bg); - - /// Same as OutputColor, but only enables the bold attribute. - static const char *OutputBold(bool bg); - - /// This function returns the escape sequence to reverse forground and - /// background colors. - static const char *OutputReverse(); - - /// Resets the terminals colors, or returns an escape sequence to do so. - static const char *ResetColor(); - - /// Get the result of a process wide random number generator. The - /// generator will be automatically seeded in non-deterministic fashion. - static unsigned GetRandomNumber(); - /// @} - }; +class self_process; + +/// \brief Generic base class which exposes information about an operating +/// system process. +/// +/// This base class is the core interface behind any OS process. It exposes +/// methods to query for generic information about a particular process. +/// +/// Subclasses implement this interface based on the mechanisms available, and +/// can optionally expose more interfaces unique to certain process kinds. +class process { +protected: + /// \brief Only specific subclasses of process objects can be destroyed. + virtual ~process(); + +public: + /// \brief Operating system specific type to identify a process. + /// + /// Note that the windows one is defined to 'void *' as this is the + /// documented type for HANDLE on windows, and we don't want to pull in the + /// Windows headers here. +#if defined(LLVM_ON_UNIX) + typedef pid_t id_type; +#elif defined(LLVM_ON_WIN32) + typedef void *id_type; // Must match the type of HANDLE. +#else +#error Unsupported operating system. +#endif + + /// \brief Get the operating system specific identifier for this process. + virtual id_type get_id() = 0; + + /// \brief Get the user time consumed by this process. + /// + /// Note that this is often an approximation and may be zero on platforms + /// where we don't have good support for the functionality. + virtual TimeValue get_user_time() const = 0; + + /// \brief Get the system time consumed by this process. + /// + /// Note that this is often an approximation and may be zero on platforms + /// where we don't have good support for the functionality. + virtual TimeValue get_system_time() const = 0; + + /// \brief Get the wall time consumed by this process. + /// + /// Note that this is often an approximation and may be zero on platforms + /// where we don't have good support for the functionality. + virtual TimeValue get_wall_time() const = 0; + + /// \name Static factory routines for processes. + /// @{ + + /// \brief Get the process object for the current process. + static self_process *get_self(); + + /// @} + +}; + +/// \brief The specific class representing the current process. +/// +/// The current process can both specialize the implementation of the routines +/// and can expose certain information not available for other OS processes. +class self_process : public process { + friend class process; + + /// \brief Private destructor, as users shouldn't create objects of this + /// type. + virtual ~self_process(); + +public: + virtual id_type get_id(); + virtual TimeValue get_user_time() const; + virtual TimeValue get_system_time() const; + virtual TimeValue get_wall_time() const; + + /// \name Process configuration (sysconf on POSIX) + /// @{ + + /// \brief Get the virtual memory page size. + /// + /// Query the operating system for this process's page size. + size_t page_size() const { return PageSize; }; + + /// @} + +private: + /// \name Cached process state. + /// @{ + + /// \brief Cached page size, this cannot vary during the life of the process. + size_t PageSize; + + /// @} + + /// \brief Constructor, used by \c process::get_self() only. + self_process(); +}; + + +/// \brief A collection of legacy interfaces for querying information about the +/// current executing process. +class Process { +public: + /// \brief Return process memory usage. + /// This static function will return the total amount of memory allocated + /// by the process. This only counts the memory allocated via the malloc, + /// calloc and realloc functions and includes any "free" holes in the + /// allocated space. + static size_t GetMallocUsage(); + + /// This static function will set \p user_time to the amount of CPU time + /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU + /// time spent in system (kernel) mode. If the operating system does not + /// support collection of these metrics, a zero TimeValue will be for both + /// values. + /// \param elapsed Returns the TimeValue::now() giving current time + /// \param user_time Returns the current amount of user time for the process + /// \param sys_time Returns the current amount of system time for the process + static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time, + TimeValue &sys_time); + + /// This static function will return the process' current user id number. + /// Not all operating systems support this feature. Where it is not + /// supported, the function should return 65536 as the value. + static int GetCurrentUserId(); + + /// This static function will return the process' current group id number. + /// Not all operating systems support this feature. Where it is not + /// supported, the function should return 65536 as the value. + static int GetCurrentGroupId(); + + /// This function makes the necessary calls to the operating system to + /// prevent core files or any other kind of large memory dumps that can + /// occur when a program fails. + /// @brief Prevent core file generation. + static void PreventCoreFiles(); + + /// This function determines if the standard input is connected directly + /// to a user's input (keyboard probably), rather than coming from a file + /// or pipe. + static bool StandardInIsUserInput(); + + /// This function determines if the standard output is connected to a + /// "tty" or "console" window. That is, the output would be displayed to + /// the user rather than being put on a pipe or stored in a file. + static bool StandardOutIsDisplayed(); + + /// This function determines if the standard error is connected to a + /// "tty" or "console" window. That is, the output would be displayed to + /// the user rather than being put on a pipe or stored in a file. + static bool StandardErrIsDisplayed(); + + /// This function determines if the given file descriptor is connected to + /// a "tty" or "console" window. That is, the output would be displayed to + /// the user rather than being put on a pipe or stored in a file. + static bool FileDescriptorIsDisplayed(int fd); + + /// This function determines if the given file descriptor is displayd and + /// supports colors. + static bool FileDescriptorHasColors(int fd); + + /// This function determines the number of columns in the window + /// if standard output is connected to a "tty" or "console" + /// window. If standard output is not connected to a tty or + /// console, or if the number of columns cannot be determined, + /// this routine returns zero. + static unsigned StandardOutColumns(); + + /// This function determines the number of columns in the window + /// if standard error is connected to a "tty" or "console" + /// window. If standard error is not connected to a tty or + /// console, or if the number of columns cannot be determined, + /// this routine returns zero. + static unsigned StandardErrColumns(); + + /// This function determines whether the terminal connected to standard + /// output supports colors. If standard output is not connected to a + /// terminal, this function returns false. + static bool StandardOutHasColors(); + + /// This function determines whether the terminal connected to standard + /// error supports colors. If standard error is not connected to a + /// terminal, this function returns false. + static bool StandardErrHasColors(); + + /// Whether changing colors requires the output to be flushed. + /// This is needed on systems that don't support escape sequences for + /// changing colors. + static bool ColorNeedsFlush(); + + /// This function returns the colorcode escape sequences. + /// If ColorNeedsFlush() is true then this function will change the colors + /// and return an empty escape sequence. In that case it is the + /// responsibility of the client to flush the output stream prior to + /// calling this function. + static const char *OutputColor(char c, bool bold, bool bg); + + /// Same as OutputColor, but only enables the bold attribute. + static const char *OutputBold(bool bg); + + /// This function returns the escape sequence to reverse forground and + /// background colors. + static const char *OutputReverse(); + + /// Resets the terminals colors, or returns an escape sequence to do so. + static const char *ResetColor(); + + /// Get the result of a process wide random number generator. The + /// generator will be automatically seeded in non-deterministic fashion. + static unsigned GetRandomNumber(); +}; + } } diff --git a/contrib/llvm/include/llvm/Support/Program.h b/contrib/llvm/include/llvm/Support/Program.h index 7c9a951..bf65011 100644 --- a/contrib/llvm/include/llvm/Support/Program.h +++ b/contrib/llvm/include/llvm/Support/Program.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_PROGRAM_H -#define LLVM_SYSTEM_PROGRAM_H +#ifndef LLVM_SUPPORT_PROGRAM_H +#define LLVM_SUPPORT_PROGRAM_H #include "llvm/Support/Path.h" @@ -39,14 +39,10 @@ namespace sys { /// @name Methods /// @{ - public: Program(); ~Program(); - /// Return process ID of this program. - unsigned GetPid() const; - /// This function executes the program using the \p arguments provided. The /// invoked program will inherit the stdin, stdout, and stderr file /// descriptors, the environment and other configuration settings of the @@ -103,17 +99,7 @@ namespace sys { ///< is non-empty upon return an error occurred while waiting. ); - /// This function terminates the program. - /// @returns true if an error occurred. - /// @see Execute - /// @brief Terminates the program. - bool Kill - ( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string - ///< instance in which error messages will be returned. If the string - ///< is non-empty upon return an error occurred while killing the - ///< program. - ); - + public: /// This static constructor (factory) will attempt to locate a program in /// the operating system's file system using some pre-determined set of /// locations to search (e.g. the PATH on Unix). Paths with slashes are @@ -139,7 +125,8 @@ namespace sys { const sys::Path** redirects = 0, unsigned secondsToWait = 0, unsigned memoryLimit = 0, - std::string* ErrMsg = 0); + std::string* ErrMsg = 0, + bool *ExecutionFailed = 0); /// A convenience function equivalent to Program prg; prg.Execute(..); /// @see Execute diff --git a/contrib/llvm/include/llvm/Support/Recycler.h b/contrib/llvm/include/llvm/Support/Recycler.h index fa6e189..bcc561d 100644 --- a/contrib/llvm/include/llvm/Support/Recycler.h +++ b/contrib/llvm/include/llvm/Support/Recycler.h @@ -22,6 +22,8 @@ namespace llvm { +class BumpPtrAllocator; + /// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for /// printing statistics. /// @@ -87,6 +89,15 @@ public: } } + /// Special case for BumpPtrAllocator which has an empty Deallocate() + /// function. + /// + /// There is no need to traverse the free list, pulling all the objects into + /// cache. + void clear(BumpPtrAllocator&) { + FreeList.clearAndLeakNodesUnsafely(); + } + template<class SubClass, class AllocatorType> SubClass *Allocate(AllocatorType &Allocator) { assert(sizeof(SubClass) <= Size && diff --git a/contrib/llvm/include/llvm/Support/Regex.h b/contrib/llvm/include/llvm/Support/Regex.h index ffe09b1..82df2c6 100644 --- a/contrib/llvm/include/llvm/Support/Regex.h +++ b/contrib/llvm/include/llvm/Support/Regex.h @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// // -// This file implements a POSIX regular expression matcher. +// This file implements a POSIX regular expression matcher. Both Basic and +// Extended POSIX regular expressions (ERE) are supported. EREs were extended +// to support backreferences in matches. +// This implementation also supports matching strings with embedded NUL chars. // //===----------------------------------------------------------------------===// @@ -33,12 +36,14 @@ namespace llvm { /// null string after any newline in the string in addition to its normal /// function, and the $ anchor matches the null string before any /// newline in the string in addition to its normal function. - Newline=2 + Newline=2, + /// By default, the POSIX extended regular expression (ERE) syntax is + /// assumed. Pass this flag to turn on basic regular expressions (BRE) + /// instead. + BasicRegex=4 }; - /// Compiles the given POSIX Extended Regular Expression \p Regex. - /// This implementation supports regexes and matching strings with embedded - /// NUL characters. + /// Compiles the given regular expression \p Regex. Regex(StringRef Regex, unsigned Flags = NoFlags); ~Regex(); diff --git a/contrib/llvm/include/llvm/Support/RegistryParser.h b/contrib/llvm/include/llvm/Support/RegistryParser.h index 2cc5783..a6997b6 100644 --- a/contrib/llvm/include/llvm/Support/RegistryParser.h +++ b/contrib/llvm/include/llvm/Support/RegistryParser.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H -#define LLVM_SUPPORT_REGISTRY_PARSER_H +#ifndef LLVM_SUPPORT_REGISTRYPARSER_H +#define LLVM_SUPPORT_REGISTRYPARSER_H #include "llvm/Support/CommandLine.h" #include "llvm/Support/Registry.h" @@ -52,4 +52,4 @@ namespace llvm { } -#endif // LLVM_SUPPORT_REGISTRY_PARSER_H +#endif // LLVM_SUPPORT_REGISTRYPARSER_H diff --git a/contrib/llvm/include/llvm/Support/SMLoc.h b/contrib/llvm/include/llvm/Support/SMLoc.h index 1bf810b..0906471 100644 --- a/contrib/llvm/include/llvm/Support/SMLoc.h +++ b/contrib/llvm/include/llvm/Support/SMLoc.h @@ -12,14 +12,14 @@ // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_SMLOC_H -#define SUPPORT_SMLOC_H +#ifndef LLVM_SUPPORT_SMLOC_H +#define LLVM_SUPPORT_SMLOC_H #include <cassert> namespace llvm { -/// SMLoc - Represents a location in source code. +/// Represents a location in source code. class SMLoc { const char *Ptr; public: @@ -39,9 +39,11 @@ public: } }; -/// SMRange - Represents a range in source code. Note that unlike standard STL -/// ranges, the locations specified are considered to be *inclusive*. For -/// example, [X,X] *does* include X, it isn't an empty range. +/// Represents a range in source code. +/// +/// SMRange is implemented using a half-open range, as is the convention in C++. +/// In the string "abc", the range (1,3] represents the substring "bc", and the +/// range (2,2] represents an empty range between the characters "b" and "c". class SMRange { public: SMLoc Start, End; diff --git a/contrib/llvm/include/llvm/Support/SaveAndRestore.h b/contrib/llvm/include/llvm/Support/SaveAndRestore.h index ffa99b9..6330bec 100644 --- a/contrib/llvm/include/llvm/Support/SaveAndRestore.h +++ b/contrib/llvm/include/llvm/Support/SaveAndRestore.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_SAVERESTORE -#define LLVM_ADT_SAVERESTORE +#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H +#define LLVM_SUPPORT_SAVEANDRESTORE_H namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/Signals.h b/contrib/llvm/include/llvm/Support/Signals.h index 634f4cf..465656b 100644 --- a/contrib/llvm/include/llvm/Support/Signals.h +++ b/contrib/llvm/include/llvm/Support/Signals.h @@ -12,10 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_SIGNALS_H -#define LLVM_SYSTEM_SIGNALS_H +#ifndef LLVM_SUPPORT_SIGNALS_H +#define LLVM_SUPPORT_SIGNALS_H #include "llvm/Support/Path.h" +#include <cstdio> namespace llvm { namespace sys { @@ -38,6 +39,9 @@ namespace sys { /// @brief Print a stack trace if a fatal signal occurs. void PrintStackTraceOnErrorSignal(); + /// \brief Print the stack trace using the given \c FILE object. + void PrintStackTrace(FILE *); + /// AddSignalHandler - Add a function to be called when an abort/kill signal /// is delivered to the process. The handler can have a cookie passed to it /// to identify what instance of the handler it is. diff --git a/contrib/llvm/include/llvm/Support/Solaris.h b/contrib/llvm/include/llvm/Support/Solaris.h index 57eee2c..6228c4b 100644 --- a/contrib/llvm/include/llvm/Support/Solaris.h +++ b/contrib/llvm/include/llvm/Support/Solaris.h @@ -11,8 +11,8 @@ * *===----------------------------------------------------------------------===*/ -#ifndef LLVM_SYSTEM_SOLARIS_H -#define LLVM_SYSTEM_SOLARIS_H +#ifndef LLVM_SUPPORT_SOLARIS_H +#define LLVM_SUPPORT_SOLARIS_H #include <sys/types.h> #include <sys/regset.h> diff --git a/contrib/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm/include/llvm/Support/SourceMgr.h index bcf95f2..02abf92 100644 --- a/contrib/llvm/include/llvm/Support/SourceMgr.h +++ b/contrib/llvm/include/llvm/Support/SourceMgr.h @@ -13,17 +13,20 @@ // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_SOURCEMGR_H -#define SUPPORT_SOURCEMGR_H +#ifndef LLVM_SUPPORT_SOURCEMGR_H +#define LLVM_SUPPORT_SOURCEMGR_H -#include "llvm/Support/SMLoc.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/SMLoc.h" #include <string> namespace llvm { class MemoryBuffer; class SourceMgr; class SMDiagnostic; + class SMFixIt; class Twine; class raw_ostream; @@ -95,6 +98,10 @@ public: return Buffers[i].Buffer; } + unsigned getNumBuffers() const { + return Buffers.size(); + } + SMLoc getParentIncludeLoc(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i].IncludeLoc; @@ -139,6 +146,7 @@ public: /// the default error handler is used. void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>(), bool ShowColors = true) const; @@ -148,7 +156,8 @@ public: /// @param Msg If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, - ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const; + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()) const; /// PrintIncludeStack - Prints the names of included files and the line of the /// file they were included from. A diagnostic handler can use this before @@ -160,6 +169,38 @@ public: }; +/// Represents a single fixit, a replacement of one range of text with another. +class SMFixIt { + SMRange Range; + + std::string Text; + +public: + // FIXME: Twine.str() is not very efficient. + SMFixIt(SMLoc Loc, const Twine &Insertion) + : Range(Loc, Loc), Text(Insertion.str()) { + assert(Loc.isValid()); + } + + // FIXME: Twine.str() is not very efficient. + SMFixIt(SMRange R, const Twine &Replacement) + : Range(R), Text(Replacement.str()) { + assert(R.isValid()); + } + + StringRef getText() const { return Text; } + SMRange getRange() const { return Range; } + + bool operator<(const SMFixIt &Other) const { + if (Range.Start.getPointer() != Other.Range.Start.getPointer()) + return Range.Start.getPointer() < Other.Range.Start.getPointer(); + if (Range.End.getPointer() != Other.Range.End.getPointer()) + return Range.End.getPointer() < Other.Range.End.getPointer(); + return Text < Other.Text; + } +}; + + /// SMDiagnostic - Instances of this class encapsulate one diagnostic report, /// allowing printing to a raw_ostream as a caret diagnostic. class SMDiagnostic { @@ -170,35 +211,46 @@ class SMDiagnostic { SourceMgr::DiagKind Kind; std::string Message, LineContents; std::vector<std::pair<unsigned, unsigned> > Ranges; + SmallVector<SMFixIt, 4> FixIts; public: // Null diagnostic. SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {} // Diagnostic with no location (e.g. file not found, command line arg error). - SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd, - const std::string &Msg) + SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg) : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {} // Diagnostic with a location. - SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, + SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col, SourceMgr::DiagKind Kind, - const std::string &Msg, const std::string &LineStr, - ArrayRef<std::pair<unsigned,unsigned> > Ranges); + StringRef Msg, StringRef LineStr, + ArrayRef<std::pair<unsigned,unsigned> > Ranges, + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()); const SourceMgr *getSourceMgr() const { return SM; } SMLoc getLoc() const { return Loc; } - const std::string &getFilename() const { return Filename; } + StringRef getFilename() const { return Filename; } int getLineNo() const { return LineNo; } int getColumnNo() const { return ColumnNo; } SourceMgr::DiagKind getKind() const { return Kind; } - const std::string &getMessage() const { return Message; } - const std::string &getLineContents() const { return LineContents; } - const std::vector<std::pair<unsigned, unsigned> > &getRanges() const { + StringRef getMessage() const { return Message; } + StringRef getLineContents() const { return LineContents; } + ArrayRef<std::pair<unsigned, unsigned> > getRanges() const { return Ranges; } - void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const; + + void addFixIt(const SMFixIt &Hint) { + FixIts.push_back(Hint); + } + + ArrayRef<SMFixIt> getFixIts() const { + return FixIts; + } + + void print(const char *ProgName, raw_ostream &S, + bool ShowColors = true) const; }; } // end llvm namespace diff --git a/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h index a2b4bcb..3855485 100644 --- a/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h +++ b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// -#ifndef STREAMABLEMEMORYOBJECT_H_ -#define STREAMABLEMEMORYOBJECT_H_ +#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H +#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryObject.h" #include "llvm/Support/DataStream.h" +#include "llvm/Support/MemoryObject.h" #include <vector> namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/StringPool.h b/contrib/llvm/include/llvm/Support/StringPool.h index de05e0b..71adbc5 100644 --- a/contrib/llvm/include/llvm/Support/StringPool.h +++ b/contrib/llvm/include/llvm/Support/StringPool.h @@ -30,8 +30,8 @@ #define LLVM_SUPPORT_STRINGPOOL_H #include "llvm/ADT/StringMap.h" -#include <new> #include <cassert> +#include <new> namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/SwapByteOrder.h b/contrib/llvm/include/llvm/Support/SwapByteOrder.h index 6c0592c..e65f9cc 100644 --- a/contrib/llvm/include/llvm/Support/SwapByteOrder.h +++ b/contrib/llvm/include/llvm/Support/SwapByteOrder.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H -#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H +#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H +#define LLVM_SUPPORT_SWAPBYTEORDER_H #include "llvm/Support/DataTypes.h" #include <cstddef> diff --git a/contrib/llvm/include/llvm/Support/TargetFolder.h b/contrib/llvm/include/llvm/Support/TargetFolder.h index 45f7816..5c1978d 100644 --- a/contrib/llvm/include/llvm/Support/TargetFolder.h +++ b/contrib/llvm/include/llvm/Support/TargetFolder.h @@ -19,10 +19,10 @@ #ifndef LLVM_SUPPORT_TARGETFOLDER_H #define LLVM_SUPPORT_TARGETFOLDER_H -#include "llvm/Constants.h" -#include "llvm/InstrTypes.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/InstrTypes.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h index ca58bfb..b06676d 100644 --- a/contrib/llvm/include/llvm/Support/TargetRegistry.h +++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h @@ -19,10 +19,10 @@ #ifndef LLVM_SUPPORT_TARGETREGISTRY_H #define LLVM_SUPPORT_TARGETREGISTRY_H -#include "llvm/Support/CodeGen.h" #include "llvm/ADT/Triple.h" -#include <string> +#include "llvm/Support/CodeGen.h" #include <cassert> +#include <string> namespace llvm { class AsmPrinter; @@ -41,7 +41,6 @@ namespace llvm { class MCRegisterInfo; class MCStreamer; class MCSubtargetInfo; - class MCTargetAsmLexer; class MCTargetAsmParser; class TargetMachine; class TargetOptions; @@ -96,9 +95,6 @@ namespace llvm { typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT, StringRef CPU); - typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T, - const MCRegisterInfo &MRI, - const MCAsmInfo &MAI); typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, MCAsmParser &P); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, @@ -182,10 +178,6 @@ namespace llvm { /// MCAsmBackend, if registered. MCAsmBackendCtorTy MCAsmBackendCtorFn; - /// MCAsmLexerCtorFn - Construction function for this target's - /// MCTargetAsmLexer, if registered. - MCAsmLexerCtorTy MCAsmLexerCtorFn; - /// MCAsmParserCtorFn - Construction function for this target's /// MCTargetAsmParser, if registered. MCAsmParserCtorTy MCAsmParserCtorFn; @@ -242,9 +234,6 @@ namespace llvm { /// hasMCAsmBackend - Check if this target supports .o generation. bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; } - /// hasMCAsmLexer - Check if this target supports .s lexing. - bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; } - /// hasAsmParser - Check if this target supports .s parsing. bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; } @@ -360,15 +349,6 @@ namespace llvm { return MCAsmBackendCtorFn(*this, Triple, CPU); } - /// createMCAsmLexer - Create a target specific assembly lexer. - /// - MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI, - const MCAsmInfo &MAI) const { - if (!MCAsmLexerCtorFn) - return 0; - return MCAsmLexerCtorFn(*this, MRI, MAI); - } - /// createMCAsmParser - Create a target specific assembly parser. /// /// \param Parser The target independent parser implementation to use for @@ -676,20 +656,6 @@ namespace llvm { T.MCAsmBackendCtorFn = Fn; } - /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCAsmLexer for the target. - static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) { - if (!T.MCAsmLexerCtorFn) - T.MCAsmLexerCtorFn = Fn; - } - /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for /// the given target. /// @@ -1070,28 +1036,6 @@ namespace llvm { } }; - /// RegisterMCAsmLexer - Helper template for registering a target specific - /// assembly lexer, for use in the target machine initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooMCAsmLexer() { - /// extern Target TheFooTarget; - /// RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget); - /// } - template<class MCAsmLexerImpl> - struct RegisterMCAsmLexer { - RegisterMCAsmLexer(Target &T) { - TargetRegistry::RegisterMCAsmLexer(T, &Allocator); - } - - private: - static MCTargetAsmLexer *Allocator(const Target &T, - const MCRegisterInfo &MRI, - const MCAsmInfo &MAI) { - return new MCAsmLexerImpl(T, MRI, MAI); - } - }; - /// RegisterMCAsmParser - Helper template for registering a target specific /// assembly parser, for use in the target machine initialization /// function. Usage: diff --git a/contrib/llvm/include/llvm/Support/ThreadLocal.h b/contrib/llvm/include/llvm/Support/ThreadLocal.h index 62ec90a..7518626 100644 --- a/contrib/llvm/include/llvm/Support/ThreadLocal.h +++ b/contrib/llvm/include/llvm/Support/ThreadLocal.h @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_THREAD_LOCAL_H -#define LLVM_SYSTEM_THREAD_LOCAL_H +#ifndef LLVM_SUPPORT_THREADLOCAL_H +#define LLVM_SUPPORT_THREADLOCAL_H -#include "llvm/Support/Threading.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Threading.h" #include <cassert> namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/Threading.h b/contrib/llvm/include/llvm/Support/Threading.h index 9017afb..a7e8774 100644 --- a/contrib/llvm/include/llvm/Support/Threading.h +++ b/contrib/llvm/include/llvm/Support/Threading.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_THREADING_H -#define LLVM_SYSTEM_THREADING_H +#ifndef LLVM_SUPPORT_THREADING_H +#define LLVM_SUPPORT_THREADING_H namespace llvm { /// llvm_start_multithreaded - Allocate and initialize structures needed to diff --git a/contrib/llvm/include/llvm/Support/TimeValue.h b/contrib/llvm/include/llvm/Support/TimeValue.h index e780b50..4b48b84 100644 --- a/contrib/llvm/include/llvm/Support/TimeValue.h +++ b/contrib/llvm/include/llvm/Support/TimeValue.h @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_SUPPORT_TIMEVALUE_H +#define LLVM_SUPPORT_TIMEVALUE_H + #include "llvm/Support/DataTypes.h" #include <string> -#ifndef LLVM_SYSTEM_TIMEVALUE_H -#define LLVM_SYSTEM_TIMEVALUE_H - namespace llvm { namespace sys { /// This class is used where a precise fixed point in time is required. The @@ -82,6 +82,9 @@ namespace sys { /// @name Constructors /// @{ public: + /// \brief Default construct a time value, initializing to ZeroTime. + TimeValue() : seconds_(0), nanos_(0) {} + /// Caller provides the exact value in seconds and nanoseconds. The /// \p nanos argument defaults to zero for convenience. /// @brief Explicit constructor @@ -237,7 +240,7 @@ namespace sys { /// Posix, correcting for the difference in Posix zero time. /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970) uint64_t toPosixTime() const { - uint64_t result = seconds_ - PosixZeroTime.seconds_; + uint64_t result = seconds_ - PosixZeroTimeSeconds; result += nanos_ / NANOSECONDS_PER_POSIX_TICK; return result; } @@ -245,14 +248,14 @@ namespace sys { /// Converts the TimeValue into the corresponding number of seconds /// since the epoch (00:00:00 Jan 1,1970). uint64_t toEpochTime() const { - return seconds_ - PosixZeroTime.seconds_; + return seconds_ - PosixZeroTimeSeconds; } /// Converts the TimeValue into the corresponding number of "ticks" for /// Win32 platforms, correcting for the difference in Win32 zero time. /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601) uint64_t toWin32Time() const { - uint64_t result = seconds_ - Win32ZeroTime.seconds_; + uint64_t result = seconds_ - Win32ZeroTimeSeconds; result += nanos_ / NANOSECONDS_PER_WIN32_TICK; return result; } @@ -261,7 +264,7 @@ namespace sys { /// correction for the Posix zero time. /// @brief Convert to timespec time (ala POSIX.1b) void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { - seconds = seconds_ - PosixZeroTime.seconds_; + seconds = seconds_ - PosixZeroTimeSeconds; nanos = nanos_; } @@ -328,7 +331,7 @@ namespace sys { /// TimeValue and assigns that value to \p this. /// @brief Convert seconds form PosixTime to TimeValue void fromEpochTime( SecondsType seconds ) { - seconds_ = seconds + PosixZeroTime.seconds_; + seconds_ = seconds + PosixZeroTimeSeconds; nanos_ = 0; this->normalize(); } @@ -337,7 +340,7 @@ namespace sys { /// corresponding TimeValue and assigns that value to \p this. /// @brief Convert seconds form Windows FILETIME to TimeValue void fromWin32Time( uint64_t win32Time ) { - this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_; + this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds; this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100; } @@ -357,6 +360,9 @@ namespace sys { /// Store the values as a <timeval>. SecondsType seconds_;///< Stores the seconds part of the TimeVal NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal + + static const SecondsType PosixZeroTimeSeconds; + static const SecondsType Win32ZeroTimeSeconds; /// @} }; diff --git a/contrib/llvm/include/llvm/Support/Timer.h b/contrib/llvm/include/llvm/Support/Timer.h index a741882..d009d7f 100644 --- a/contrib/llvm/include/llvm/Support/Timer.h +++ b/contrib/llvm/include/llvm/Support/Timer.h @@ -6,22 +6,17 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines three classes: Timer, TimeRegion, and TimerGroup, -// documented below. -// -//===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_TIMER_H #define LLVM_SUPPORT_TIMER_H +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" -#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> -#include <vector> #include <utility> +#include <vector> namespace llvm { @@ -78,7 +73,7 @@ public: /// invocations of its startTimer()/stopTimer() methods. Given appropriate OS /// support it can also keep track of the RSS of the program at various points. /// By default, the Timer will print the amount of time it has captured to -/// standard error when the laster timer is destroyed, otherwise it is printed +/// standard error when the last timer is destroyed, otherwise it is printed /// when its TimerGroup is destroyed. Timers do not print their information /// if they are never started. /// @@ -126,7 +121,7 @@ private: /// The TimeRegion class is used as a helper class to call the startTimer() and /// stopTimer() methods of the Timer class. When the object is constructed, it -/// starts the timer specified as it's argument. When it is destroyed, it stops +/// starts the timer specified as its argument. When it is destroyed, it stops /// the relevant timer. This makes it easy to time a region of code. /// class TimeRegion { diff --git a/contrib/llvm/include/llvm/Support/ToolOutputFile.h b/contrib/llvm/include/llvm/Support/ToolOutputFile.h index 65b182a..b3b7c57 100644 --- a/contrib/llvm/include/llvm/Support/ToolOutputFile.h +++ b/contrib/llvm/include/llvm/Support/ToolOutputFile.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_TOOL_OUTPUT_FILE_H -#define LLVM_SUPPORT_TOOL_OUTPUT_FILE_H +#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H +#define LLVM_SUPPORT_TOOLOUTPUTFILE_H #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/include/llvm/Support/Valgrind.h b/contrib/llvm/include/llvm/Support/Valgrind.h index e147647..a1397db 100644 --- a/contrib/llvm/include/llvm/Support/Valgrind.h +++ b/contrib/llvm/include/llvm/Support/Valgrind.h @@ -16,8 +16,8 @@ #ifndef LLVM_SYSTEM_VALGRIND_H #define LLVM_SYSTEM_VALGRIND_H -#include "llvm/Support/Compiler.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Compiler.h" #include <stddef.h> #if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) diff --git a/contrib/llvm/include/llvm/Support/ValueHandle.h b/contrib/llvm/include/llvm/Support/ValueHandle.h index dbcf0fd..b49341c 100644 --- a/contrib/llvm/include/llvm/Support/ValueHandle.h +++ b/contrib/llvm/include/llvm/Support/ValueHandle.h @@ -16,10 +16,11 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/Value.h" +#include "llvm/IR/Value.h" namespace llvm { class ValueHandleBase; +template<typename From> struct simplify_type; // ValueHandleBase** is only 4-byte aligned. template<> @@ -162,14 +163,12 @@ public: // Specialize simplify_type to allow WeakVH to participate in // dyn_cast, isa, etc. -template<typename From> struct simplify_type; -template<> struct simplify_type<const WeakVH> { +template<> struct simplify_type<WeakVH> { typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const WeakVH &WVH) { - return static_cast<Value *>(WVH); + static SimpleType getSimplifiedValue(WeakVH &WVH) { + return WVH; } }; -template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {}; /// AssertingVH - This is a Value Handle that points to a value and asserts out /// if the value is destroyed while the handle is still live. This is very @@ -236,18 +235,6 @@ public: ValueTy &operator*() const { return *getValPtr(); } }; -// Specialize simplify_type to allow AssertingVH to participate in -// dyn_cast, isa, etc. -template<typename From> struct simplify_type; -template<> struct simplify_type<const AssertingVH<Value> > { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) { - return static_cast<Value *>(AVH); - } -}; -template<> struct simplify_type<AssertingVH<Value> > - : public simplify_type<const AssertingVH<Value> > {}; - // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. template<typename T> struct DenseMapInfo<AssertingVH<T> > { @@ -345,18 +332,6 @@ public: ValueTy &operator*() const { return *getValPtr(); } }; -// Specialize simplify_type to allow TrackingVH to participate in -// dyn_cast, isa, etc. -template<typename From> struct simplify_type; -template<> struct simplify_type<const TrackingVH<Value> > { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) { - return static_cast<Value *>(AVH); - } -}; -template<> struct simplify_type<TrackingVH<Value> > - : public simplify_type<const TrackingVH<Value> > {}; - /// CallbackVH - This is a value handle that allows subclasses to define /// callbacks that run when the underlying Value has RAUW called on it or is /// destroyed. This class can be used as the key of a map, as long as the user @@ -399,18 +374,6 @@ public: virtual void allUsesReplacedWith(Value *); }; -// Specialize simplify_type to allow CallbackVH to participate in -// dyn_cast, isa, etc. -template<typename From> struct simplify_type; -template<> struct simplify_type<const CallbackVH> { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const CallbackVH &CVH) { - return static_cast<Value *>(CVH); - } -}; -template<> struct simplify_type<CallbackVH> - : public simplify_type<const CallbackVH> {}; - } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Support/Watchdog.h b/contrib/llvm/include/llvm/Support/Watchdog.h new file mode 100644 index 0000000..b58496b --- /dev/null +++ b/contrib/llvm/include/llvm/Support/Watchdog.h @@ -0,0 +1,38 @@ +//===--- Watchdog.h - Watchdog timer ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the llvm::sys::Watchdog class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_WATCHDOG_H +#define LLVM_SUPPORT_WATCHDOG_H + +#include "llvm/Support/Compiler.h" + +namespace llvm { + namespace sys { + + /// This class provides an abstraction for a timeout around an operation + /// that must complete in a given amount of time. Failure to complete before + /// the timeout is an unrecoverable situation and no mechanisms to attempt + /// to handle it are provided. + class Watchdog { + public: + Watchdog(unsigned int seconds); + ~Watchdog(); + private: + // Noncopyable. + Watchdog(const Watchdog &other) LLVM_DELETED_FUNCTION; + Watchdog &operator=(const Watchdog &other) LLVM_DELETED_FUNCTION; + }; + } +} + +#endif diff --git a/contrib/llvm/include/llvm/Support/Win64EH.h b/contrib/llvm/include/llvm/Support/Win64EH.h index 8d74e10..ecce713 100644 --- a/contrib/llvm/include/llvm/Support/Win64EH.h +++ b/contrib/llvm/include/llvm/Support/Win64EH.h @@ -17,6 +17,7 @@ #define LLVM_SUPPORT_WIN64EH_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" namespace llvm { namespace Win64EH { @@ -39,11 +40,17 @@ enum UnwindOpcodes { /// or part thereof. union UnwindCode { struct { - uint8_t codeOffset; - uint8_t unwindOp:4, - opInfo:4; + support::ulittle8_t CodeOffset; + support::ulittle8_t UnwindOpAndOpInfo; } u; - uint16_t frameOffset; + support::ulittle16_t FrameOffset; + + uint8_t getUnwindOp() const { + return u.UnwindOpAndOpInfo & 0x0F; + } + uint8_t getOpInfo() const { + return (u.UnwindOpAndOpInfo >> 4) & 0x0F; + } }; enum { @@ -60,37 +67,75 @@ enum { /// RuntimeFunction - An entry in the table of functions with unwind info. struct RuntimeFunction { - uint64_t startAddress; - uint64_t endAddress; - uint64_t unwindInfoOffset; + support::ulittle32_t StartAddress; + support::ulittle32_t EndAddress; + support::ulittle32_t UnwindInfoOffset; }; /// UnwindInfo - An entry in the exception table. struct UnwindInfo { - uint8_t version:3, - flags:5; - uint8_t prologSize; - uint8_t numCodes; - uint8_t frameRegister:4, - frameOffset:4; - UnwindCode unwindCodes[1]; + support::ulittle8_t VersionAndFlags; + support::ulittle8_t PrologSize; + support::ulittle8_t NumCodes; + support::ulittle8_t FrameRegisterAndOffset; + UnwindCode UnwindCodes[1]; + uint8_t getVersion() const { + return VersionAndFlags & 0x07; + } + uint8_t getFlags() const { + return (VersionAndFlags >> 3) & 0x1f; + } + uint8_t getFrameRegister() const { + return FrameRegisterAndOffset & 0x0f; + } + uint8_t getFrameOffset() const { + return (FrameRegisterAndOffset >> 4) & 0x0f; + } + + // The data after unwindCodes depends on flags. + // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows + // the address of the language-specific exception handler. + // If UNW_ChainInfo is set then follows a RuntimeFunction which defines + // the chained unwind info. + // For more information please see MSDN at: + // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx + + /// \brief Return pointer to language specific data part of UnwindInfo. void *getLanguageSpecificData() { - return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]); + return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]); } - uint64_t getLanguageSpecificHandlerOffset() { - return *reinterpret_cast<uint64_t *>(getLanguageSpecificData()); + + /// \brief Return pointer to language specific data part of UnwindInfo. + const void *getLanguageSpecificData() const { + return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]); } - void setLanguageSpecificHandlerOffset(uint64_t offset) { - *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset; + + /// \brief Return image-relative offset of language-specific exception handler. + uint32_t getLanguageSpecificHandlerOffset() const { + return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData()); } - RuntimeFunction *getChainedFunctionEntry() { - return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); + + /// \brief Set image-relative offset of language-specific exception handler. + void setLanguageSpecificHandlerOffset(uint32_t offset) { + *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset; } + + /// \brief Return pointer to exception-specific data. void *getExceptionData() { - return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>( + return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>( getLanguageSpecificData())+1); } + + /// \brief Return pointer to chained unwind info. + RuntimeFunction *getChainedFunctionEntry() { + return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); + } + + /// \brief Return pointer to chained unwind info. + const RuntimeFunction *getChainedFunctionEntry() const { + return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData()); + } }; diff --git a/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h index 12958fa..6e4f57f 100644 --- a/contrib/llvm/include/llvm/Support/YAMLParser.h +++ b/contrib/llvm/include/llvm/Support/YAMLParser.h @@ -35,15 +35,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_YAML_PARSER_H -#define LLVM_SUPPORT_YAML_PARSER_H +#ifndef LLVM_SUPPORT_YAMLPARSER_H +#define LLVM_SUPPORT_YAMLPARSER_H #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/SMLoc.h" - #include <limits> #include <utility> @@ -77,7 +76,11 @@ std::string escape(StringRef Input); /// documents. class Stream { public: + /// @brief This keeps a reference to the string referenced by \p Input. Stream(StringRef Input, SourceMgr &); + + /// @brief This takes ownership of \p InputBuffer. + Stream(MemoryBuffer *InputBuffer, SourceMgr &); ~Stream(); document_iterator begin(); @@ -181,7 +184,7 @@ public: : Node(NK_Scalar, D, Anchor) , Value(Val) { SMLoc Start = SMLoc::getFromPointer(Val.begin()); - SMLoc End = SMLoc::getFromPointer(Val.end() - 1); + SMLoc End = SMLoc::getFromPointer(Val.end()); SourceRange = SMRange(Start, End); } diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h new file mode 100644 index 0000000..801868f --- /dev/null +++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h @@ -0,0 +1,1104 @@ +//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_YAMLTRAITS_H +#define LLVM_SUPPORT_YAMLTRAITS_H + + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" +#include "llvm/Support/type_traits.h" + + +namespace llvm { +namespace yaml { + + +/// This class should be specialized by any type that needs to be converted +/// to/from a YAML mapping. For example: +/// +/// struct ScalarBitSetTraits<MyStruct> { +/// static void mapping(IO &io, MyStruct &s) { +/// io.mapRequired("name", s.name); +/// io.mapRequired("size", s.size); +/// io.mapOptional("age", s.age); +/// } +/// }; +template<class T> +struct MappingTraits { + // Must provide: + // static void mapping(IO &io, T &fields); +}; + + +/// This class should be specialized by any integral type that converts +/// to/from a YAML scalar where there is a one-to-one mapping between +/// in-memory values and a string in YAML. For example: +/// +/// struct ScalarEnumerationTraits<Colors> { +/// static void enumeration(IO &io, Colors &value) { +/// io.enumCase(value, "red", cRed); +/// io.enumCase(value, "blue", cBlue); +/// io.enumCase(value, "green", cGreen); +/// } +/// }; +template<typename T> +struct ScalarEnumerationTraits { + // Must provide: + // static void enumeration(IO &io, T &value); +}; + + +/// This class should be specialized by any integer type that is a union +/// of bit values and the YAML representation is a flow sequence of +/// strings. For example: +/// +/// struct ScalarBitSetTraits<MyFlags> { +/// static void bitset(IO &io, MyFlags &value) { +/// io.bitSetCase(value, "big", flagBig); +/// io.bitSetCase(value, "flat", flagFlat); +/// io.bitSetCase(value, "round", flagRound); +/// } +/// }; +template<typename T> +struct ScalarBitSetTraits { + // Must provide: + // static void bitset(IO &io, T &value); +}; + + +/// This class should be specialized by type that requires custom conversion +/// to/from a yaml scalar. For example: +/// +/// template<> +/// struct ScalarTraits<MyType> { +/// static void output(const MyType &val, void*, llvm::raw_ostream &out) { +/// // stream out custom formatting +/// out << llvm::format("%x", val); +/// } +/// static StringRef input(StringRef scalar, void*, MyType &value) { +/// // parse scalar and set `value` +/// // return empty string on success, or error string +/// return StringRef(); +/// } +/// }; +template<typename T> +struct ScalarTraits { + // Must provide: + // + // Function to write the value as a string: + //static void output(const T &value, void *ctxt, llvm::raw_ostream &out); + // + // Function to convert a string to a value. Returns the empty + // StringRef on success or an error string if string is malformed: + //static StringRef input(StringRef scalar, void *ctxt, T &value); +}; + + +/// This class should be specialized by any type that needs to be converted +/// to/from a YAML sequence. For example: +/// +/// template<> +/// struct SequenceTraits< std::vector<MyType> > { +/// static size_t size(IO &io, std::vector<MyType> &seq) { +/// return seq.size(); +/// } +/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) { +/// if ( index >= seq.size() ) +/// seq.resize(index+1); +/// return seq[index]; +/// } +/// }; +template<typename T> +struct SequenceTraits { + // Must provide: + // static size_t size(IO &io, T &seq); + // static T::value_type& element(IO &io, T &seq, size_t index); + // + // The following is option and will cause generated YAML to use + // a flow sequence (e.g. [a,b,c]). + // static const bool flow = true; +}; + + +/// This class should be specialized by any type that needs to be converted +/// to/from a list of YAML documents. +template<typename T> +struct DocumentListTraits { + // Must provide: + // static size_t size(IO &io, T &seq); + // static T::value_type& element(IO &io, T &seq, size_t index); +}; + + +// Only used by compiler if both template types are the same +template <typename T, T> +struct SameType; + +// Only used for better diagnostics of missing traits +template <typename T> +struct MissingTrait; + + + +// Test if ScalarEnumerationTraits<T> is defined on type T. +template <class T> +struct has_ScalarEnumerationTraits +{ + typedef void (*Signature_enumeration)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_enumeration, &U::enumeration>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<ScalarEnumerationTraits<T> >(0)) == 1); +}; + + +// Test if ScalarBitSetTraits<T> is defined on type T. +template <class T> +struct has_ScalarBitSetTraits +{ + typedef void (*Signature_bitset)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_bitset, &U::bitset>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(0)) == 1); +}; + + +// Test if ScalarTraits<T> is defined on type T. +template <class T> +struct has_ScalarTraits +{ + typedef StringRef (*Signature_input)(StringRef, void*, T&); + typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&); + + template <typename U> + static char test(SameType<Signature_input, &U::input>*, + SameType<Signature_output, &U::output>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<ScalarTraits<T> >(0,0)) == 1); +}; + + +// Test if MappingTraits<T> is defined on type T. +template <class T> +struct has_MappingTraits +{ + typedef void (*Signature_mapping)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_mapping, &U::mapping>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1); +}; + + +// Test if SequenceTraits<T> is defined on type T. +template <class T> +struct has_SequenceMethodTraits +{ + typedef size_t (*Signature_size)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_size, &U::size>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1); +}; + + +// has_FlowTraits<int> will cause an error with some compilers because +// it subclasses int. Using this wrapper only instantiates the +// real has_FlowTraits only if the template type is a class. +template <typename T, bool Enabled = llvm::is_class<T>::value> +class has_FlowTraits +{ +public: + static const bool value = false; +}; + +// Some older gcc compilers don't support straight forward tests +// for members, so test for ambiguity cause by the base and derived +// classes both defining the member. +template <class T> +struct has_FlowTraits<T, true> +{ + struct Fallback { bool flow; }; + struct Derived : T, Fallback { }; + + template<typename C> + static char (&f(SameType<bool Fallback::*, &C::flow>*))[1]; + + template<typename C> + static char (&f(...))[2]; + +public: + static bool const value = sizeof(f<Derived>(0)) == 2; +}; + + + +// Test if SequenceTraits<T> is defined on type T +template<typename T> +struct has_SequenceTraits : public llvm::integral_constant<bool, + has_SequenceMethodTraits<T>::value > { }; + + +// Test if DocumentListTraits<T> is defined on type T +template <class T> +struct has_DocumentListTraits +{ + typedef size_t (*Signature_size)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_size, &U::size>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<DocumentListTraits<T> >(0)) == 1); +}; + + + + +template<typename T> +struct missingTraits : public llvm::integral_constant<bool, + !has_ScalarEnumerationTraits<T>::value + && !has_ScalarBitSetTraits<T>::value + && !has_ScalarTraits<T>::value + && !has_MappingTraits<T>::value + && !has_SequenceTraits<T>::value + && !has_DocumentListTraits<T>::value > {}; + + +// Base class for Input and Output. +class IO { +public: + + IO(void *Ctxt=NULL); + virtual ~IO(); + + virtual bool outputting() = 0; + + virtual unsigned beginSequence() = 0; + virtual bool preflightElement(unsigned, void *&) = 0; + virtual void postflightElement(void*) = 0; + virtual void endSequence() = 0; + + virtual unsigned beginFlowSequence() = 0; + virtual bool preflightFlowElement(unsigned, void *&) = 0; + virtual void postflightFlowElement(void*) = 0; + virtual void endFlowSequence() = 0; + + virtual void beginMapping() = 0; + virtual void endMapping() = 0; + virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0; + virtual void postflightKey(void*) = 0; + + virtual void beginEnumScalar() = 0; + virtual bool matchEnumScalar(const char*, bool) = 0; + virtual void endEnumScalar() = 0; + + virtual bool beginBitSetScalar(bool &) = 0; + virtual bool bitSetMatch(const char*, bool) = 0; + virtual void endBitSetScalar() = 0; + + virtual void scalarString(StringRef &) = 0; + + virtual void setError(const Twine &) = 0; + + template <typename T> + void enumCase(T &Val, const char* Str, const T ConstVal) { + if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) { + Val = ConstVal; + } + } + + // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF + template <typename T> + void enumCase(T &Val, const char* Str, const uint32_t ConstVal) { + if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) { + Val = ConstVal; + } + } + + template <typename T> + void bitSetCase(T &Val, const char* Str, const T ConstVal) { + if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) { + Val = Val | ConstVal; + } + } + + // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF + template <typename T> + void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) { + if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) { + Val = Val | ConstVal; + } + } + + void *getContext(); + void setContext(void *); + + template <typename T> + void mapRequired(const char* Key, T& Val) { + this->processKey(Key, Val, true); + } + + template <typename T> + typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type + mapOptional(const char* Key, T& Val) { + // omit key/value instead of outputting empty sequence + if ( this->outputting() && !(Val.begin() != Val.end()) ) + return; + this->processKey(Key, Val, false); + } + + template <typename T> + typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type + mapOptional(const char* Key, T& Val) { + this->processKey(Key, Val, false); + } + + template <typename T> + void mapOptional(const char* Key, T& Val, const T& Default) { + this->processKeyWithDefault(Key, Val, Default, false); + } + + +private: + template <typename T> + void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue, + bool Required) { + void *SaveInfo; + bool UseDefault; + const bool sameAsDefault = outputting() && Val == DefaultValue; + if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault, + SaveInfo) ) { + yamlize(*this, Val, Required); + this->postflightKey(SaveInfo); + } + else { + if ( UseDefault ) + Val = DefaultValue; + } + } + + template <typename T> + void processKey(const char *Key, T &Val, bool Required) { + void *SaveInfo; + bool UseDefault; + if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) { + yamlize(*this, Val, Required); + this->postflightKey(SaveInfo); + } + } + +private: + void *Ctxt; +}; + + + +template<typename T> +typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type +yamlize(IO &io, T &Val, bool) { + io.beginEnumScalar(); + ScalarEnumerationTraits<T>::enumeration(io, Val); + io.endEnumScalar(); +} + +template<typename T> +typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type +yamlize(IO &io, T &Val, bool) { + bool DoClear; + if ( io.beginBitSetScalar(DoClear) ) { + if ( DoClear ) + Val = static_cast<T>(0); + ScalarBitSetTraits<T>::bitset(io, Val); + io.endBitSetScalar(); + } +} + + +template<typename T> +typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type +yamlize(IO &io, T &Val, bool) { + if ( io.outputting() ) { + std::string Storage; + llvm::raw_string_ostream Buffer(Storage); + ScalarTraits<T>::output(Val, io.getContext(), Buffer); + StringRef Str = Buffer.str(); + io.scalarString(Str); + } + else { + StringRef Str; + io.scalarString(Str); + StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val); + if ( !Result.empty() ) { + io.setError(llvm::Twine(Result)); + } + } +} + + +template<typename T> +typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type +yamlize(IO &io, T &Val, bool) { + io.beginMapping(); + MappingTraits<T>::mapping(io, Val); + io.endMapping(); +} + +template<typename T> +typename llvm::enable_if_c<missingTraits<T>::value, void>::type +yamlize(IO &io, T &Val, bool) { + char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; +} + +template<typename T> +typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type +yamlize(IO &io, T &Seq, bool) { + if ( has_FlowTraits< SequenceTraits<T> >::value ) { + unsigned incnt = io.beginFlowSequence(); + unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt; + for(unsigned i=0; i < count; ++i) { + void *SaveInfo; + if ( io.preflightFlowElement(i, SaveInfo) ) { + yamlize(io, SequenceTraits<T>::element(io, Seq, i), true); + io.postflightFlowElement(SaveInfo); + } + } + io.endFlowSequence(); + } + else { + unsigned incnt = io.beginSequence(); + unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt; + for(unsigned i=0; i < count; ++i) { + void *SaveInfo; + if ( io.preflightElement(i, SaveInfo) ) { + yamlize(io, SequenceTraits<T>::element(io, Seq, i), true); + io.postflightElement(SaveInfo); + } + } + io.endSequence(); + } +} + + +template<> +struct ScalarTraits<bool> { + static void output(const bool &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, bool &); +}; + +template<> +struct ScalarTraits<StringRef> { + static void output(const StringRef &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, StringRef &); +}; + +template<> +struct ScalarTraits<uint8_t> { + static void output(const uint8_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, uint8_t &); +}; + +template<> +struct ScalarTraits<uint16_t> { + static void output(const uint16_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, uint16_t &); +}; + +template<> +struct ScalarTraits<uint32_t> { + static void output(const uint32_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, uint32_t &); +}; + +template<> +struct ScalarTraits<uint64_t> { + static void output(const uint64_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, uint64_t &); +}; + +template<> +struct ScalarTraits<int8_t> { + static void output(const int8_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, int8_t &); +}; + +template<> +struct ScalarTraits<int16_t> { + static void output(const int16_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, int16_t &); +}; + +template<> +struct ScalarTraits<int32_t> { + static void output(const int32_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, int32_t &); +}; + +template<> +struct ScalarTraits<int64_t> { + static void output(const int64_t &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, int64_t &); +}; + +template<> +struct ScalarTraits<float> { + static void output(const float &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, float &); +}; + +template<> +struct ScalarTraits<double> { + static void output(const double &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, double &); +}; + + + +// Utility for use within MappingTraits<>::mapping() method +// to [de]normalize an object for use with YAML conversion. +template <typename TNorm, typename TFinal> +struct MappingNormalization { + MappingNormalization(IO &i_o, TFinal &Obj) + : io(i_o), BufPtr(NULL), Result(Obj) { + if ( io.outputting() ) { + BufPtr = new (&Buffer) TNorm(io, Obj); + } + else { + BufPtr = new (&Buffer) TNorm(io); + } + } + + ~MappingNormalization() { + if ( ! io.outputting() ) { + Result = BufPtr->denormalize(io); + } + BufPtr->~TNorm(); + } + + TNorm* operator->() { return BufPtr; } + +private: + typedef llvm::AlignedCharArrayUnion<TNorm> Storage; + + Storage Buffer; + IO &io; + TNorm *BufPtr; + TFinal &Result; +}; + + + +// Utility for use within MappingTraits<>::mapping() method +// to [de]normalize an object for use with YAML conversion. +template <typename TNorm, typename TFinal> +struct MappingNormalizationHeap { + MappingNormalizationHeap(IO &i_o, TFinal &Obj) + : io(i_o), BufPtr(NULL), Result(Obj) { + if ( io.outputting() ) { + BufPtr = new (&Buffer) TNorm(io, Obj); + } + else { + BufPtr = new TNorm(io); + } + } + + ~MappingNormalizationHeap() { + if ( io.outputting() ) { + BufPtr->~TNorm(); + } + else { + Result = BufPtr->denormalize(io); + } + } + + TNorm* operator->() { return BufPtr; } + +private: + typedef llvm::AlignedCharArrayUnion<TNorm> Storage; + + Storage Buffer; + IO &io; + TNorm *BufPtr; + TFinal &Result; +}; + + + +/// +/// The Input class is used to parse a yaml document into in-memory structs +/// and vectors. +/// +/// It works by using YAMLParser to do a syntax parse of the entire yaml +/// document, then the Input class builds a graph of HNodes which wraps +/// each yaml Node. The extra layer is buffering. The low level yaml +/// parser only lets you look at each node once. The buffering layer lets +/// you search and interate multiple times. This is necessary because +/// the mapRequired() method calls may not be in the same order +/// as the keys in the document. +/// +class Input : public IO { +public: + // Construct a yaml Input object from a StringRef and optional user-data. + Input(StringRef InputContent, void *Ctxt=NULL); + ~Input(); + + // Check if there was an syntax or semantic error during parsing. + llvm::error_code error(); + + // To set alternate error reporting. + void setDiagHandler(llvm::SourceMgr::DiagHandlerTy Handler, void *Ctxt = 0); + +private: + virtual bool outputting(); + virtual void beginMapping(); + virtual void endMapping(); + virtual bool preflightKey(const char *, bool, bool, bool &, void *&); + virtual void postflightKey(void *); + virtual unsigned beginSequence(); + virtual void endSequence(); + virtual bool preflightElement(unsigned index, void *&); + virtual void postflightElement(void *); + virtual unsigned beginFlowSequence(); + virtual bool preflightFlowElement(unsigned , void *&); + virtual void postflightFlowElement(void *); + virtual void endFlowSequence(); + virtual void beginEnumScalar(); + virtual bool matchEnumScalar(const char*, bool); + virtual void endEnumScalar(); + virtual bool beginBitSetScalar(bool &); + virtual bool bitSetMatch(const char *, bool ); + virtual void endBitSetScalar(); + virtual void scalarString(StringRef &); + virtual void setError(const Twine &message); + + class HNode { + public: + HNode(Node *n) : _node(n) { } + virtual ~HNode() { } + static inline bool classof(const HNode *) { return true; } + + Node *_node; + }; + + class EmptyHNode : public HNode { + public: + EmptyHNode(Node *n) : HNode(n) { } + virtual ~EmptyHNode() {} + static inline bool classof(const HNode *n) { + return NullNode::classof(n->_node); + } + static inline bool classof(const EmptyHNode *) { return true; } + }; + + class ScalarHNode : public HNode { + public: + ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { } + virtual ~ScalarHNode() { } + + StringRef value() const { return _value; } + + static inline bool classof(const HNode *n) { + return ScalarNode::classof(n->_node); + } + static inline bool classof(const ScalarHNode *) { return true; } + protected: + StringRef _value; + }; + + class MapHNode : public HNode { + public: + MapHNode(Node *n) : HNode(n) { } + virtual ~MapHNode(); + + static inline bool classof(const HNode *n) { + return MappingNode::classof(n->_node); + } + static inline bool classof(const MapHNode *) { return true; } + + struct StrMappingInfo { + static StringRef getEmptyKey() { return StringRef(); } + static StringRef getTombstoneKey() { return StringRef(" ", 0); } + static unsigned getHashValue(StringRef const val) { + return llvm::HashString(val); } + static bool isEqual(StringRef const lhs, + StringRef const rhs) { return lhs.equals(rhs); } + }; + typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode; + + bool isValidKey(StringRef key); + + NameToNode Mapping; + llvm::SmallVector<const char*, 6> ValidKeys; + }; + + class SequenceHNode : public HNode { + public: + SequenceHNode(Node *n) : HNode(n) { } + virtual ~SequenceHNode(); + + static inline bool classof(const HNode *n) { + return SequenceNode::classof(n->_node); + } + static inline bool classof(const SequenceHNode *) { return true; } + + std::vector<HNode*> Entries; + }; + + Input::HNode *createHNodes(Node *node); + void setError(HNode *hnode, const Twine &message); + void setError(Node *node, const Twine &message); + + +public: + // These are only used by operator>>. They could be private + // if those templated things could be made friends. + bool setCurrentDocument(); + void nextDocument(); + +private: + llvm::SourceMgr SrcMgr; // must be before Strm + OwningPtr<llvm::yaml::Stream> Strm; + OwningPtr<HNode> TopNode; + llvm::error_code EC; + llvm::BumpPtrAllocator StringAllocator; + llvm::yaml::document_iterator DocIterator; + std::vector<bool> BitValuesUsed; + HNode *CurrentNode; + bool ScalarMatchFound; +}; + + + + +/// +/// The Output class is used to generate a yaml document from in-memory structs +/// and vectors. +/// +class Output : public IO { +public: + Output(llvm::raw_ostream &, void *Ctxt=NULL); + virtual ~Output(); + + virtual bool outputting(); + virtual void beginMapping(); + virtual void endMapping(); + virtual bool preflightKey(const char *key, bool, bool, bool &, void *&); + virtual void postflightKey(void *); + virtual unsigned beginSequence(); + virtual void endSequence(); + virtual bool preflightElement(unsigned, void *&); + virtual void postflightElement(void *); + virtual unsigned beginFlowSequence(); + virtual bool preflightFlowElement(unsigned, void *&); + virtual void postflightFlowElement(void *); + virtual void endFlowSequence(); + virtual void beginEnumScalar(); + virtual bool matchEnumScalar(const char*, bool); + virtual void endEnumScalar(); + virtual bool beginBitSetScalar(bool &); + virtual bool bitSetMatch(const char *, bool ); + virtual void endBitSetScalar(); + virtual void scalarString(StringRef &); + virtual void setError(const Twine &message); + +public: + // These are only used by operator<<. They could be private + // if that templated operator could be made a friend. + void beginDocuments(); + bool preflightDocument(unsigned); + void postflightDocument(); + void endDocuments(); + +private: + void output(StringRef s); + void outputUpToEndOfLine(StringRef s); + void newLineCheck(); + void outputNewLine(); + void paddedKey(StringRef key); + + enum InState { inSeq, inFlowSeq, inMapFirstKey, inMapOtherKey }; + + llvm::raw_ostream &Out; + SmallVector<InState, 8> StateStack; + int Column; + int ColumnAtFlowStart; + bool NeedBitValueComma; + bool NeedFlowSequenceComma; + bool EnumerationMatchFound; + bool NeedsNewLine; +}; + + + + +/// YAML I/O does conversion based on types. But often native data types +/// are just a typedef of built in intergral types (e.g. int). But the C++ +/// type matching system sees through the typedef and all the typedefed types +/// look like a built in type. This will cause the generic YAML I/O conversion +/// to be used. To provide better control over the YAML conversion, you can +/// use this macro instead of typedef. It will create a class with one field +/// and automatic conversion operators to and from the base type. +/// Based on BOOST_STRONG_TYPEDEF +#define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \ + struct _type { \ + _type() { } \ + _type(const _base v) : value(v) { } \ + _type(const _type &v) : value(v.value) {} \ + _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\ + _type &operator=(const _base &rhs) { value = rhs; return *this; } \ + operator const _base & () const { return value; } \ + bool operator==(const _type &rhs) const { return value == rhs.value; } \ + bool operator==(const _base &rhs) const { return value == rhs; } \ + bool operator<(const _type &rhs) const { return value < rhs.value; } \ + _base value; \ + }; + + + +/// +/// Use these types instead of uintXX_t in any mapping to have +/// its yaml output formatted as hexadecimal. +/// +LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8) +LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32) +LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64) + + +template<> +struct ScalarTraits<Hex8> { + static void output(const Hex8 &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, Hex8 &); +}; + +template<> +struct ScalarTraits<Hex16> { + static void output(const Hex16 &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, Hex16 &); +}; + +template<> +struct ScalarTraits<Hex32> { + static void output(const Hex32 &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, Hex32 &); +}; + +template<> +struct ScalarTraits<Hex64> { + static void output(const Hex64 &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, Hex64 &); +}; + + +// Define non-member operator>> so that Input can stream in a document list. +template <typename T> +inline +typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Input &>::type +operator>>(Input &yin, T &docList) { + int i = 0; + while ( yin.setCurrentDocument() ) { + yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true); + if ( yin.error() ) + return yin; + yin.nextDocument(); + ++i; + } + return yin; +} + +// Define non-member operator>> so that Input can stream in a map as a document. +template <typename T> +inline +typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type +operator>>(Input &yin, T &docMap) { + yin.setCurrentDocument(); + yamlize(yin, docMap, true); + return yin; +} + +// Define non-member operator>> so that Input can stream in a sequence as +// a document. +template <typename T> +inline +typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type +operator>>(Input &yin, T &docSeq) { + yin.setCurrentDocument(); + yamlize(yin, docSeq, true); + return yin; +} + +// Provide better error message about types missing a trait specialization +template <typename T> +inline +typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type +operator>>(Input &yin, T &docSeq) { + char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; + return yin; +} + + +// Define non-member operator<< so that Output can stream out document list. +template <typename T> +inline +typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Output &>::type +operator<<(Output &yout, T &docList) { + yout.beginDocuments(); + const size_t count = DocumentListTraits<T>::size(yout, docList); + for(size_t i=0; i < count; ++i) { + if ( yout.preflightDocument(i) ) { + yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true); + yout.postflightDocument(); + } + } + yout.endDocuments(); + return yout; +} + +// Define non-member operator<< so that Output can stream out a map. +template <typename T> +inline +typename llvm::enable_if_c<has_MappingTraits<T>::value,Output &>::type +operator<<(Output &yout, T &map) { + yout.beginDocuments(); + if ( yout.preflightDocument(0) ) { + yamlize(yout, map, true); + yout.postflightDocument(); + } + yout.endDocuments(); + return yout; +} + +// Define non-member operator<< so that Output can stream out a sequence. +template <typename T> +inline +typename llvm::enable_if_c<has_SequenceTraits<T>::value,Output &>::type +operator<<(Output &yout, T &seq) { + yout.beginDocuments(); + if ( yout.preflightDocument(0) ) { + yamlize(yout, seq, true); + yout.postflightDocument(); + } + yout.endDocuments(); + return yout; +} + +// Provide better error message about types missing a trait specialization +template <typename T> +inline +typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type +operator<<(Output &yout, T &seq) { + char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; + return yout; +} + + +} // namespace yaml +} // namespace llvm + + +/// Utility for declaring that a std::vector of a particular type +/// should be considered a YAML sequence. +#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \ + namespace llvm { \ + namespace yaml { \ + template<> \ + struct SequenceTraits< std::vector<_type> > { \ + static size_t size(IO &io, std::vector<_type> &seq) { \ + return seq.size(); \ + } \ + static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\ + if ( index >= seq.size() ) \ + seq.resize(index+1); \ + return seq[index]; \ + } \ + }; \ + } \ + } + +/// Utility for declaring that a std::vector of a particular type +/// should be considered a YAML flow sequence. +#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \ + namespace llvm { \ + namespace yaml { \ + template<> \ + struct SequenceTraits< std::vector<_type> > { \ + static size_t size(IO &io, std::vector<_type> &seq) { \ + return seq.size(); \ + } \ + static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\ + if ( index >= seq.size() ) \ + seq.resize(index+1); \ + return seq[index]; \ + } \ + static const bool flow = true; \ + }; \ + } \ + } + +/// Utility for declaring that a std::vector of a particular type +/// should be considered a YAML document list. +#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \ + namespace llvm { \ + namespace yaml { \ + template<> \ + struct DocumentListTraits< std::vector<_type> > { \ + static size_t size(IO &io, std::vector<_type> &seq) { \ + return seq.size(); \ + } \ + static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\ + if ( index >= seq.size() ) \ + seq.resize(index+1); \ + return seq[index]; \ + } \ + }; \ + } \ + } + + + +#endif // LLVM_SUPPORT_YAMLTRAITS_H diff --git a/contrib/llvm/include/llvm/Support/circular_raw_ostream.h b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h index 2823af3..9000306 100644 --- a/contrib/llvm/include/llvm/Support/circular_raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h @@ -71,7 +71,7 @@ namespace llvm /// flushBuffer - Dump the contents of the buffer to Stream. /// - void flushBuffer(void) { + void flushBuffer() { if (Filled) // Write the older portion of the buffer. TheStream->write(Cur, BufferArray + BufferSize - Cur); @@ -151,7 +151,7 @@ namespace llvm /// flushBufferWithBanner - Force output of the buffer along with /// a small header. /// - void flushBufferWithBanner(void); + void flushBufferWithBanner(); private: /// releaseStream - Delete the held stream if needed. Otherwise, diff --git a/contrib/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm/include/llvm/Support/raw_ostream.h index eab0f2d..d2b4a2a 100644 --- a/contrib/llvm/include/llvm/Support/raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/raw_ostream.h @@ -29,7 +29,6 @@ namespace llvm { /// a chunk at a time. class raw_ostream { private: - // Do not implement. raw_ostream is noncopyable. void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION; raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION; diff --git a/contrib/llvm/include/llvm/Support/system_error.h b/contrib/llvm/include/llvm/Support/system_error.h index 0d164f6..43dace6 100644 --- a/contrib/llvm/include/llvm/Support/system_error.h +++ b/contrib/llvm/include/llvm/Support/system_error.h @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H -#define LLVM_SYSTEM_SYSTEM_ERROR_H +#ifndef LLVM_SUPPORT_SYSTEM_ERROR_H +#define LLVM_SUPPORT_SYSTEM_ERROR_H #include "llvm/Support/Compiler.h" diff --git a/contrib/llvm/include/llvm/Support/type_traits.h b/contrib/llvm/include/llvm/Support/type_traits.h index f930639..906e97c 100644 --- a/contrib/llvm/include/llvm/Support/type_traits.h +++ b/contrib/llvm/include/llvm/Support/type_traits.h @@ -145,6 +145,10 @@ template <typename T> struct is_pointer<T* const> : true_type {}; template <typename T> struct is_pointer<T* volatile> : true_type {}; template <typename T> struct is_pointer<T* const volatile> : true_type {}; +/// \brief Metafunction that determines wheather the given type is a reference. +template <typename T> struct is_reference : false_type {}; +template <typename T> struct is_reference<T&> : true_type {}; + /// \brief Metafunction that determines whether the given type is either an /// integral type or an enumeration type. /// @@ -205,6 +209,26 @@ template <typename T> struct remove_pointer<T*volatile> { typedef T type; }; template <typename T> struct remove_pointer<T*const volatile> { typedef T type; }; +// If T is a pointer, just return it. If it is not, return T&. +template<typename T, typename Enable = void> +struct add_lvalue_reference_if_not_pointer { typedef T &type; }; + +template<typename T> +struct add_lvalue_reference_if_not_pointer<T, + typename enable_if<is_pointer<T> >::type> { + typedef T type; +}; + +// If T is a pointer to X, return a pointer to const X. If it is not, return +// const T. +template<typename T, typename Enable = void> +struct add_const_past_pointer { typedef const T type; }; + +template<typename T> +struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> { + typedef const typename remove_pointer<T>::type *type; +}; + template <bool, typename T, typename F> struct conditional { typedef T type; }; diff --git a/contrib/llvm/include/llvm/TableGen/Error.h b/contrib/llvm/include/llvm/TableGen/Error.h index 2f6b7e6..2d0a2b4 100644 --- a/contrib/llvm/include/llvm/TableGen/Error.h +++ b/contrib/llvm/include/llvm/TableGen/Error.h @@ -32,6 +32,7 @@ LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const std::string &Msg); extern SourceMgr SrcMgr; +extern unsigned ErrorsPrinted; } // end namespace "llvm" diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h index 319298c..76ee69d 100644 --- a/contrib/llvm/include/llvm/TableGen/Record.h +++ b/contrib/llvm/include/llvm/TableGen/Record.h @@ -19,9 +19,9 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <map> @@ -128,16 +128,8 @@ public: // These methods should only be called from subclasses of Init return convertValue((TypedInit*)FI); } -public: // These methods should only be called by subclasses of RecTy. - // baseClassOf - These virtual methods should be overloaded to return true iff - // all values of type 'RHS' can be converted to the 'this' type. - virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } +public: + virtual bool baseClassOf(const RecTy*) const; }; inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { @@ -179,19 +171,11 @@ public: virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } - virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } - virtual bool baseClassOf(const BitsRecTy *RHS) const; - virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } - + virtual bool baseClassOf(const RecTy*) const; }; -// BitsRecTy - 'bits<n>' - Represent a fixed number of bits -/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits +/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits /// class BitsRecTy : public RecTy { unsigned Size; @@ -226,16 +210,7 @@ public: virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } - virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { - return RHS->Size == Size; - } - virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } - + virtual bool baseClassOf(const RecTy*) const; }; @@ -273,14 +248,7 @@ public: return RHS->baseClassOf(this); } - virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } - + virtual bool baseClassOf(const RecTy*) const; }; /// StringRecTy - 'string' - Represent an string value @@ -317,20 +285,10 @@ public: virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } - - virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; -// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of -// the specified type. -/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must -/// be of the specified type. +/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of +/// the specified type. /// class ListRecTy : public RecTy { RecTy *Ty; @@ -366,15 +324,7 @@ public: return RHS->baseClassOf(this); } - virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { - return RHS->getElementType()->typeIsConvertibleTo(Ty); - } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } + virtual bool baseClassOf(const RecTy*) const; }; /// DagRecTy - 'dag' - Represent a dag fragment @@ -410,14 +360,6 @@ public: virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } - - virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return true; } - virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } }; @@ -458,13 +400,7 @@ public: virtual bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); } - virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } - virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } - virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } - virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } - virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } - virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } - virtual bool baseClassOf(const RecordRecTy *RHS) const; + virtual bool baseClassOf(const RecTy*) const; }; /// resolveTypes - Find a common type that T1 and T2 convert to. @@ -991,7 +927,7 @@ public: /// class BinOpInit : public OpInit { public: - enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; + enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; private: BinaryOp Opc; Init *LHS, *RHS; @@ -1448,12 +1384,14 @@ class Record { SmallVector<SMLoc, 4> Locs; std::vector<Init *> TemplateArgs; std::vector<RecordVal> Values; - std::vector<Record*> SuperClasses; + std::vector<Record *> SuperClasses; + std::vector<SMRange> SuperClassRanges; // Tracks Record instances. Not owned by Record. RecordKeeper &TrackedRecords; DefInit *TheInit; + bool IsAnonymous; void init(); void checkName(); @@ -1462,14 +1400,15 @@ public: // Constructs a record. explicit Record(const std::string &N, ArrayRef<SMLoc> locs, - RecordKeeper &records) : + RecordKeeper &records, bool Anonymous = false) : ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(0) { + TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { init(); } - explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records) : + explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, + bool Anonymous = false) : ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(0) { + TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { init(); } @@ -1478,7 +1417,8 @@ public: Record(const Record &O) : ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), Values(O.Values), SuperClasses(O.SuperClasses), - TrackedRecords(O.TrackedRecords), TheInit(O.TheInit) { } + SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords), + TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { } ~Record() {} @@ -1509,6 +1449,7 @@ public: } const std::vector<RecordVal> &getValues() const { return Values; } const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } + ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } bool isTemplateArg(Init *Name) const { for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) @@ -1583,9 +1524,10 @@ public: return false; } - void addSuperClass(Record *R) { + void addSuperClass(Record *R, SMRange Range) { assert(!isSubClassOf(R) && "Already subclassing record!"); SuperClasses.push_back(R); + SuperClassRanges.push_back(Range); } /// resolveReferences - If there are any field references that refer to fields @@ -1602,6 +1544,10 @@ public: return TrackedRecords; } + bool isAnonymous() const { + return IsAnonymous; + } + void dump() const; //===--------------------------------------------------------------------===// @@ -1613,6 +1559,11 @@ public: /// Init *getValueInit(StringRef FieldName) const; + /// Return true if the named field is unset. + bool isValueUnset(StringRef FieldName) const { + return getValueInit(FieldName) == UnsetInit::get(); + } + /// getValueAsString - This method looks up the specified field and returns /// its value as a string, throwing an exception if the field does not exist /// or if the value is not a string. diff --git a/contrib/llvm/include/llvm/TableGen/StringMatcher.h b/contrib/llvm/include/llvm/TableGen/StringMatcher.h index 1dadc76..99cbcad 100644 --- a/contrib/llvm/include/llvm/TableGen/StringMatcher.h +++ b/contrib/llvm/include/llvm/TableGen/StringMatcher.h @@ -11,13 +11,13 @@ // //===----------------------------------------------------------------------===// -#ifndef STRINGMATCHER_H -#define STRINGMATCHER_H +#ifndef LLVM_TABLEGEN_STRINGMATCHER_H +#define LLVM_TABLEGEN_STRINGMATCHER_H -#include <vector> +#include "llvm/ADT/StringRef.h" #include <string> #include <utility> -#include "llvm/ADT/StringRef.h" +#include <vector> namespace llvm { class raw_ostream; diff --git a/contrib/llvm/include/llvm/Target/CostTable.h b/contrib/llvm/include/llvm/Target/CostTable.h new file mode 100644 index 0000000..a974b56 --- /dev/null +++ b/contrib/llvm/include/llvm/Target/CostTable.h @@ -0,0 +1,64 @@ +//===-- CostTable.h - Instruction Cost Table handling -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Cost tables and simple lookup functions +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_COSTTABLE_H_ +#define LLVM_TARGET_COSTTABLE_H_ + +namespace llvm { + +/// Cost Table Entry +template <class TypeTy> +struct CostTblEntry { + int ISD; + TypeTy Type; + unsigned Cost; +}; + +/// Find in cost table, TypeTy must be comparable by == +template <class TypeTy> +int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, + unsigned len, int ISD, TypeTy Ty) { + for (unsigned int i = 0; i < len; ++i) + if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty) + return i; + + // Could not find an entry. + return -1; +} + +/// Type Conversion Cost Table +template <class TypeTy> +struct TypeConversionCostTblEntry { + int ISD; + TypeTy Dst; + TypeTy Src; + unsigned Cost; +}; + +/// Find in type conversion cost table, TypeTy must be comparable by == +template <class TypeTy> +int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl, + unsigned len, int ISD, TypeTy Dst, TypeTy Src) { + for (unsigned int i = 0; i < len; ++i) + if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst) + return i; + + // Could not find an entry. + return -1; +} + +} // namespace llvm + + +#endif /* LLVM_TARGET_COSTTABLE_H_ */ diff --git a/contrib/llvm/include/llvm/Target/Mangler.h b/contrib/llvm/include/llvm/Target/Mangler.h index a50f54a..9500f1c 100644 --- a/contrib/llvm/include/llvm/Target/Mangler.h +++ b/contrib/llvm/include/llvm/Target/Mangler.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_MANGLER_H -#define LLVM_SUPPORT_MANGLER_H +#ifndef LLVM_TARGET_MANGLER_H +#define LLVM_TARGET_MANGLER_H #include "llvm/ADT/DenseMap.h" @@ -69,4 +69,4 @@ public: } // End llvm namespace -#endif // LLVM_SUPPORT_MANGLER_H +#endif // LLVM_TARGET_MANGLER_H diff --git a/contrib/llvm/include/llvm/Target/Target.td b/contrib/llvm/include/llvm/Target/Target.td index 12f5c0e..deee2eb 100644 --- a/contrib/llvm/include/llvm/Target/Target.td +++ b/contrib/llvm/include/llvm/Target/Target.td @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// // Include all information about LLVM intrinsics. -include "llvm/Intrinsics.td" +include "llvm/IR/Intrinsics.td" //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target @@ -367,8 +367,9 @@ class Instruction { // hasSideEffects - The instruction has side effects that are not // captured by any operands of the instruction or other flags. // - // neverHasSideEffects - Set on an instruction with no pattern if it has no - // side effects. + // neverHasSideEffects (deprecated) - Set on an instruction with no pattern + // if it has no side effects. This is now equivalent to setting + // "hasSideEffects = 0". bit hasSideEffects = ?; bit neverHasSideEffects = 0; @@ -396,6 +397,9 @@ class Instruction { InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. + // Scheduling information from TargetSchedule.td. + list<SchedReadWrite> SchedRW; + string Constraints = ""; // OperandConstraint, e.g. $src = $dst. /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not diff --git a/contrib/llvm/include/llvm/Target/TargetFrameLowering.h b/contrib/llvm/include/llvm/Target/TargetFrameLowering.h index d56db7b..d5f30f4 100644 --- a/contrib/llvm/include/llvm/Target/TargetFrameLowering.h +++ b/contrib/llvm/include/llvm/Target/TargetFrameLowering.h @@ -15,7 +15,6 @@ #define LLVM_TARGET_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" - #include <utility> #include <vector> @@ -48,11 +47,12 @@ private: unsigned StackAlignment; unsigned TransientStackAlignment; int LocalAreaOffset; + bool StackRealignable; public: TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO, - unsigned TransAl = 1) + unsigned TransAl = 1, bool StackReal = true) : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl), - LocalAreaOffset(LAO) {} + LocalAreaOffset(LAO), StackRealignable(StackReal) {} virtual ~TargetFrameLowering(); @@ -77,6 +77,12 @@ public: return TransientStackAlignment; } + /// isStackRealignable - This method returns whether the stack can be + /// realigned. + bool isStackRealignable() const { + return StackRealignable; + } + /// getOffsetOfLocalArea - This method returns the offset of the local area /// from the stack pointer on entrance to a function. /// @@ -114,6 +120,10 @@ public: /// by adding a check even before the "normal" function prologue. virtual void adjustForSegmentedStacks(MachineFunction &MF) const { } + /// Adjust the prologue to add Erlang Run-Time System (ERTS) specific code in + /// the assembly prologue to explicitly handle the stack. + virtual void adjustForHiPEPrologue(MachineFunction &MF) const { } + /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee /// saved registers and returns true if it isn't possible / profitable to do /// so by issuing a series of store instructions via @@ -184,7 +194,23 @@ public: /// finalized. Once the frame is finalized, MO_FrameIndex operands are /// replaced with direct constants. This method is optional. /// - virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const { + virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, + RegScavenger *RS = NULL) const { + } + + /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog + /// code insertion to eliminate call frame setup and destroy pseudo + /// instructions (but only if the Target is using them). It is responsible + /// for eliminating these instructions, replacing them with concrete + /// instructions. This method need only be implemented if using call frame + /// setup/destroy pseudo instructions. + /// + virtual void + eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const { + llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " + "target!"); } }; diff --git a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h index 4570813..0ba75e5 100644 --- a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h @@ -15,9 +15,9 @@ #define LLVM_TARGET_TARGETINSTRINFO_H #include "llvm/ADT/SmallSet.h" -#include "llvm/MC/MCInstrInfo.h" #include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/MC/MCInstrInfo.h" namespace llvm { @@ -143,9 +143,7 @@ public: /// missed. virtual bool hasLoadFromStackSlot(const MachineInstr *MI, const MachineMemOperand *&MMO, - int &FrameIndex) const { - return 0; - } + int &FrameIndex) const; /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of @@ -173,9 +171,7 @@ public: /// stack. This is just a hint, as some cases may be missed. virtual bool hasStoreToStackSlot(const MachineInstr *MI, const MachineMemOperand *&MMO, - int &FrameIndex) const { - return 0; - } + int &FrameIndex) const; /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. @@ -186,7 +182,7 @@ public: MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, - const TargetRegisterInfo &TRI) const = 0; + const TargetRegisterInfo &TRI) const; /// duplicate - Create a duplicate of the Orig instruction in MF. This is like /// MachineFunction::CloneMachineInstr(), but the target may update operands @@ -194,7 +190,7 @@ public: /// /// The instruction must be duplicable as indicated by isNotDuplicable(). virtual MachineInstr *duplicate(MachineInstr *Orig, - MachineFunction &MF) const = 0; + MachineFunction &MF) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target @@ -221,13 +217,13 @@ public: /// method for a non-commutable instruction, but there may be some cases /// where this method fails and returns null. virtual MachineInstr *commuteInstruction(MachineInstr *MI, - bool NewMI = false) const = 0; + bool NewMI = false) const; /// findCommutedOpIndices - If specified MI is commutable, return the two /// operand indices that would swap value. Return false if the instruction /// is not in a form which this routine understands. virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, - unsigned &SrcOpIdx2) const = 0; + unsigned &SrcOpIdx2) const; /// produceSameValue - Return true if two machine instructions would produce /// identical values. By default, this is only true when the two instructions @@ -236,7 +232,7 @@ public: /// aggressive checks. virtual bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1, - const MachineRegisterInfo *MRI = 0) const = 0; + const MachineRegisterInfo *MRI = 0) const; /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't @@ -298,7 +294,7 @@ public: /// after it, replacing it with an unconditional branch to NewDest. This is /// used by the tail merging pass. virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, - MachineBasicBlock *NewDest) const = 0; + MachineBasicBlock *NewDest) const; /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic /// block at the specified instruction (i.e. instruction would be the start @@ -368,11 +364,10 @@ public: /// condition code in Cond. /// /// When successful, also return the latency in cycles from TrueReg, - /// FalseReg, and Cond to the destination register. The Cond latency should - /// compensate for a conditional branch being removed. For example, if a - /// conditional branch has a 3 cycle latency from the condition code read, - /// and a cmov instruction has a 2 cycle latency from the condition code - /// read, CondCycles should be returned as -1. + /// FalseReg, and Cond to the destination register. In most cases, a select + /// instruction will be 1 cycle, so CondCycles = TrueCycles = FalseCycles = 1 + /// + /// Some x86 implementations have 2-cycle cmov instructions. /// /// @param MBB Block where select instruction would be inserted. /// @param Cond Condition returned by AnalyzeBranch. @@ -435,7 +430,7 @@ public: SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const { - assert(MI && MI->isSelect() && "MI must be a select instruction"); + assert(MI && MI->getDesc().isSelect() && "MI must be a select instruction"); return true; } @@ -569,7 +564,7 @@ public: /// folding is possible. virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const =0; + const SmallVectorImpl<unsigned> &Ops) const; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is @@ -621,6 +616,26 @@ public: return false; } + /// \brief Get the base register and byte offset of a load/store instr. + virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt, + unsigned &BaseReg, unsigned &Offset, + const TargetRegisterInfo *TRI) const { + return false; + } + + virtual bool shouldClusterLoads(MachineInstr *FirstLdSt, + MachineInstr *SecondLdSt, + unsigned NumLoads) const { + return false; + } + + /// \brief Can this target fuse the given instructions if they are scheduled + /// adjacent. + virtual bool shouldScheduleAdjacent(MachineInstr* First, + MachineInstr *Second) const { + return false; + } + /// ReverseBranchCondition - Reverses the branch condition of the specified /// condition list, returning false on success and true if it cannot be /// reversed. @@ -649,13 +664,13 @@ public: /// isUnpredicatedTerminator - Returns true if the instruction is a /// terminator instruction that has not been predicated. - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0; + virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; /// PredicateInstruction - Convert the instruction into a predicated /// instruction. It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr *MI, - const SmallVectorImpl<MachineOperand> &Pred) const = 0; + const SmallVectorImpl<MachineOperand> &Pred) const; /// SubsumesPredicate - Returns true if the first specified predicate /// subsumes the second, e.g. GE subsumes GT. @@ -691,7 +706,7 @@ public: /// terminators. virtual bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, - const MachineFunction &MF) const = 0; + const MachineFunction &MF) const; /// Measure the specified inline asm to determine an approximation of its /// length. @@ -703,21 +718,25 @@ public: /// register allocation. virtual ScheduleHazardRecognizer* CreateTargetHazardRecognizer(const TargetMachine *TM, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; /// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer /// to use for this target when scheduling the machine instructions before /// register allocation. virtual ScheduleHazardRecognizer* CreateTargetMIHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard /// recognizer to use for this target when scheduling the machine instructions /// after register allocation. virtual ScheduleHazardRecognizer* CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG *DAG) const = 0; + const ScheduleDAG *DAG) const; + + /// Provide a global flag for disabling the PreRA hazard recognizer that + /// targets may choose to honor. + bool usePreRAHazardRecognizer() const; /// analyzeCompare - For a comparison instruction, return the source registers /// in SrcReg and SrcReg2 if having two register operands, and the value it @@ -765,7 +784,7 @@ public: /// IssueWidth is the number of microops that can be dispatched each /// cycle. An instruction with zero microops takes no dispatch resources. virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, - const MachineInstr *MI) const = 0; + const MachineInstr *MI) const; /// isZeroCost - Return true for pseudo instructions that don't consume any /// machine resources in their current form. These are common cases that the @@ -777,7 +796,7 @@ public: virtual int getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, - SDNode *UseNode, unsigned UseIdx) const = 0; + SDNode *UseNode, unsigned UseIdx) const; /// getOperandLatency - Compute and return the use operand latency of a given /// pair of def and use. @@ -790,7 +809,7 @@ public: virtual int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *UseMI, - unsigned UseIdx) const = 0; + unsigned UseIdx) const; /// computeOperandLatency - Compute and return the latency of the given data /// dependent def and use when the operand indices are already known. @@ -806,10 +825,10 @@ public: /// PredCost. virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr *MI, - unsigned *PredCost = 0) const = 0; + unsigned *PredCost = 0) const; virtual int getInstrLatency(const InstrItineraryData *ItinData, - SDNode *Node) const = 0; + SDNode *Node) const; /// Return the default expected latency for a def based on it's opcode. unsigned defaultDefLatency(const MCSchedModel *SchedModel, @@ -839,7 +858,7 @@ public: /// if the target considered it 'low'. virtual bool hasLowDefLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx) const = 0; + const MachineInstr *DefMI, unsigned DefIdx) const; /// verifyInstruction - Perform target specific instruction verification. virtual @@ -956,84 +975,6 @@ private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; -/// TargetInstrInfoImpl - This is the default implementation of -/// TargetInstrInfo, which just provides a couple of default implementations -/// for various methods. This separated out because it is implemented in -/// libcodegen, not in libtarget. -class TargetInstrInfoImpl : public TargetInstrInfo { -protected: - TargetInstrInfoImpl(int CallFrameSetupOpcode = -1, - int CallFrameDestroyOpcode = -1) - : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {} -public: - virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, - MachineBasicBlock *NewDest) const; - virtual MachineInstr *commuteInstruction(MachineInstr *MI, - bool NewMI = false) const; - virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, - unsigned &SrcOpIdx2) const; - virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const; - virtual bool hasLoadFromStackSlot(const MachineInstr *MI, - const MachineMemOperand *&MMO, - int &FrameIndex) const; - virtual bool hasStoreToStackSlot(const MachineInstr *MI, - const MachineMemOperand *&MMO, - int &FrameIndex) const; - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; - virtual bool PredicateInstruction(MachineInstr *MI, - const SmallVectorImpl<MachineOperand> &Pred) const; - virtual void reMaterialize(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SubReg, - const MachineInstr *Orig, - const TargetRegisterInfo &TRI) const; - virtual MachineInstr *duplicate(MachineInstr *Orig, - MachineFunction &MF) const; - virtual bool produceSameValue(const MachineInstr *MI0, - const MachineInstr *MI1, - const MachineRegisterInfo *MRI) const; - virtual bool isSchedulingBoundary(const MachineInstr *MI, - const MachineBasicBlock *MBB, - const MachineFunction &MF) const; - - virtual int getOperandLatency(const InstrItineraryData *ItinData, - SDNode *DefNode, unsigned DefIdx, - SDNode *UseNode, unsigned UseIdx) const; - - virtual int getInstrLatency(const InstrItineraryData *ItinData, - SDNode *Node) const; - - virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, - const MachineInstr *MI) const; - - virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, - const MachineInstr *MI, - unsigned *PredCost = 0) const; - - virtual - bool hasLowDefLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx) const; - - virtual int getOperandLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *UseMI, - unsigned UseIdx) const; - - bool usePreRAHazardRecognizer() const; - - virtual ScheduleHazardRecognizer * - CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const; - - virtual ScheduleHazardRecognizer * - CreateTargetMIHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG*) const; - - virtual ScheduleHazardRecognizer * - CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, - const ScheduleDAG*) const; -}; - } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Target/TargetJITInfo.h b/contrib/llvm/include/llvm/Target/TargetJITInfo.h index 044afd9..f9bd0fb 100644 --- a/contrib/llvm/include/llvm/Target/TargetJITInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetJITInfo.h @@ -17,8 +17,8 @@ #ifndef LLVM_TARGET_TARGETJITINFO_H #define LLVM_TARGET_TARGETJITINFO_H -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> namespace llvm { diff --git a/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h index a2c97d7..5f01c8d 100644 --- a/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h @@ -10,14 +10,18 @@ #ifndef LLVM_TARGET_TARGETLIBRARYINFO_H #define LLVM_TARGET_TARGETLIBRARYINFO_H -#include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Pass.h" namespace llvm { class Triple; namespace LibFunc { enum Func { + /// int _IO_getc(_IO_FILE * __fp); + under_IO_getc, + /// int _IO_putc(int __c, _IO_FILE * __fp); + under_IO_putc, /// void operator delete[](void*); ZdaPv, /// void operator delete(void*); @@ -47,8 +51,22 @@ namespace llvm { cxa_guard_acquire, /// void __cxa_guard_release(guard_t *guard); cxa_guard_release, + /// int __isoc99_scanf (const char *format, ...) + dunder_isoc99_scanf, + /// int __isoc99_sscanf(const char *s, const char *format, ...) + dunder_isoc99_sscanf, /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); memcpy_chk, + /// char * __strdup(const char *s); + dunder_strdup, + /// char *__strndup(const char *s, size_t n); + dunder_strndup, + /// char * __strtok_r(char *s, const char *delim, char **save_ptr); + dunder_strtok_r, + /// int abs(int j); + abs, + /// int access(const char *path, int amode); + access, /// double acos(double x); acos, /// float acosf(float x); @@ -91,6 +109,20 @@ namespace llvm { atanhl, /// long double atanl(long double x); atanl, + /// double atof(const char *str); + atof, + /// int atoi(const char *str); + atoi, + /// long atol(const char *str); + atol, + /// long long atoll(const char *nptr); + atoll, + /// int bcmp(const void *s1, const void *s2, size_t n); + bcmp, + /// void bcopy(const void *s1, void *s2, size_t n); + bcopy, + /// void bzero(void *s, size_t n); + bzero, /// void *calloc(size_t count, size_t size); calloc, /// double cbrt(double x); @@ -105,6 +137,14 @@ namespace llvm { ceilf, /// long double ceill(long double x); ceill, + /// int chmod(const char *path, mode_t mode); + chmod, + /// int chown(const char *path, uid_t owner, gid_t group); + chown, + /// void clearerr(FILE *stream); + clearerr, + /// int closedir(DIR *dirp); + closedir, /// double copysign(double x, double y); copysign, /// float copysignf(float x, float y); @@ -123,6 +163,8 @@ namespace llvm { coshl, /// long double cosl(long double x); cosl, + /// char *ctermid(char *s); + ctermid, /// double exp(double x); exp, /// double exp10(double x); @@ -153,8 +195,34 @@ namespace llvm { fabsf, /// long double fabsl(long double x); fabsl, + /// int fclose(FILE *stream); + fclose, + /// FILE *fdopen(int fildes, const char *mode); + fdopen, + /// int feof(FILE *stream); + feof, + /// int ferror(FILE *stream); + ferror, + /// int fflush(FILE *stream); + fflush, + /// int ffs(int i); + ffs, + /// int ffsl(long int i); + ffsl, + /// int ffsll(long long int i); + ffsll, + /// int fgetc(FILE *stream); + fgetc, + /// int fgetpos(FILE *stream, fpos_t *pos); + fgetpos, + /// char *fgets(char *s, int n, FILE *stream); + fgets, + /// int fileno(FILE *stream); + fileno, /// int fiprintf(FILE *stream, const char *format, ...); fiprintf, + /// void flockfile(FILE *file); + flockfile, /// double floor(double x); floor, /// float floorf(float x); @@ -167,17 +235,89 @@ namespace llvm { fmodf, /// long double fmodl(long double x, long double y); fmodl, + /// FILE *fopen(const char *filename, const char *mode); + fopen, + /// FILE *fopen64(const char *filename, const char *opentype) + fopen64, + /// int fprintf(FILE *stream, const char *format, ...); + fprintf, /// int fputc(int c, FILE *stream); fputc, /// int fputs(const char *s, FILE *stream); fputs, + /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); + fread, /// void free(void *ptr); free, + /// double frexp(double num, int *exp); + frexp, + /// float frexpf(float num, int *exp); + frexpf, + /// long double frexpl(long double num, int *exp); + frexpl, + /// int fscanf(FILE *stream, const char *format, ... ); + fscanf, + /// int fseek(FILE *stream, long offset, int whence); + fseek, + /// int fseeko(FILE *stream, off_t offset, int whence); + fseeko, + /// int fseeko64(FILE *stream, off64_t offset, int whence) + fseeko64, + /// int fsetpos(FILE *stream, const fpos_t *pos); + fsetpos, + /// int fstat(int fildes, struct stat *buf); + fstat, + /// int fstat64(int filedes, struct stat64 *buf) + fstat64, + /// int fstatvfs(int fildes, struct statvfs *buf); + fstatvfs, + /// int fstatvfs64(int fildes, struct statvfs64 *buf); + fstatvfs64, + /// long ftell(FILE *stream); + ftell, + /// off_t ftello(FILE *stream); + ftello, + /// off64_t ftello64(FILE *stream) + ftello64, + /// int ftrylockfile(FILE *file); + ftrylockfile, + /// void funlockfile(FILE *file); + funlockfile, /// size_t fwrite(const void *ptr, size_t size, size_t nitems, /// FILE *stream); fwrite, + /// int getc(FILE *stream); + getc, + /// int getc_unlocked(FILE *stream); + getc_unlocked, + /// int getchar(void); + getchar, + /// char *getenv(const char *name); + getenv, + /// int getitimer(int which, struct itimerval *value); + getitimer, + /// int getlogin_r(char *name, size_t namesize); + getlogin_r, + /// struct passwd *getpwnam(const char *name); + getpwnam, + /// char *gets(char *s); + gets, + /// uint32_t htonl(uint32_t hostlong); + htonl, + /// uint16_t htons(uint16_t hostshort); + htons, /// int iprintf(const char *format, ...); iprintf, + /// int isascii(int c); + isascii, + /// int isdigit(int c); + isdigit, + /// long int labs(long int j); + labs, + /// int lchown(const char *path, uid_t owner, gid_t group); + lchown, + /// long long int llabs(long long int j); + llabs, /// double log(double x); log, /// double log10(double x); @@ -208,8 +348,16 @@ namespace llvm { logf, /// long double logl(long double x); logl, + /// int lstat(const char *path, struct stat *buf); + lstat, + /// int lstat64(const char *path, struct stat64 *buf); + lstat64, /// void *malloc(size_t size); malloc, + /// void *memalign(size_t boundary, size_t size); + memalign, + /// void *memccpy(void *s1, const void *s2, int c, size_t n); + memccpy, /// void *memchr(const void *s, int c, size_t n); memchr, /// int memcmp(const void *s1, const void *s2, size_t n); @@ -218,16 +366,44 @@ namespace llvm { memcpy, /// void *memmove(void *s1, const void *s2, size_t n); memmove, + // void *memrchr(const void *s, int c, size_t n); + memrchr, /// void *memset(void *b, int c, size_t len); memset, /// void memset_pattern16(void *b, const void *pattern16, size_t len); memset_pattern16, + /// int mkdir(const char *path, mode_t mode); + mkdir, + /// time_t mktime(struct tm *timeptr); + mktime, + /// double modf(double x, double *iptr); + modf, + /// float modff(float, float *iptr); + modff, + /// long double modfl(long double value, long double *iptr); + modfl, /// double nearbyint(double x); nearbyint, /// float nearbyintf(float x); nearbyintf, /// long double nearbyintl(long double x); nearbyintl, + /// uint32_t ntohl(uint32_t netlong); + ntohl, + /// uint16_t ntohs(uint16_t netshort); + ntohs, + /// int open(const char *path, int oflag, ... ); + open, + /// int open64(const char *filename, int flags[, mode_t mode]) + open64, + /// DIR *opendir(const char *dirname); + opendir, + /// int pclose(FILE *stream); + pclose, + /// void perror(const char *s); + perror, + /// FILE *popen(const char *command, const char *mode); + popen, /// int posix_memalign(void **memptr, size_t alignment, size_t size); posix_memalign, /// double pow(double x, double y); @@ -236,26 +412,61 @@ namespace llvm { powf, /// long double powl(long double x, long double y); powl, + /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); + pread, + /// int printf(const char *format, ...); + printf, + /// int putc(int c, FILE *stream); + putc, /// int putchar(int c); putchar, /// int puts(const char *s); puts, + /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, + /// off_t offset); + pwrite, + /// void qsort(void *base, size_t nel, size_t width, + /// int (*compar)(const void *, const void *)); + qsort, + /// ssize_t read(int fildes, void *buf, size_t nbyte); + read, + /// ssize_t readlink(const char *path, char *buf, size_t bufsize); + readlink, /// void *realloc(void *ptr, size_t size); realloc, /// void *reallocf(void *ptr, size_t size); reallocf, + /// char *realpath(const char *file_name, char *resolved_name); + realpath, + /// int remove(const char *path); + remove, + /// int rename(const char *old, const char *new); + rename, + /// void rewind(FILE *stream); + rewind, /// double rint(double x); rint, /// float rintf(float x); rintf, /// long double rintl(long double x); rintl, + /// int rmdir(const char *path); + rmdir, /// double round(double x); round, /// float roundf(float x); roundf, /// long double roundl(long double x); roundl, + /// int scanf(const char *restrict format, ... ); + scanf, + /// void setbuf(FILE *stream, char *buf); + setbuf, + /// int setitimer(int which, const struct itimerval *value, + /// struct itimerval *ovalue); + setitimer, + /// int setvbuf(FILE *stream, char *buf, int type, size_t size); + setvbuf, /// double sin(double x); sin, /// float sinf(float x); @@ -270,20 +481,40 @@ namespace llvm { sinl, /// int siprintf(char *str, const char *format, ...); siprintf, + /// int snprintf(char *s, size_t n, const char *format, ...); + snprintf, + /// int sprintf(char *str, const char *format, ...); + sprintf, /// double sqrt(double x); sqrt, /// float sqrtf(float x); sqrtf, /// long double sqrtl(long double x); sqrtl, + /// int sscanf(const char *s, const char *format, ... ); + sscanf, + /// int stat(const char *path, struct stat *buf); + stat, + /// int stat64(const char *path, struct stat64 *buf); + stat64, + /// int statvfs(const char *path, struct statvfs *buf); + statvfs, + /// int statvfs64(const char *path, struct statvfs64 *buf) + statvfs64, /// char *stpcpy(char *s1, const char *s2); stpcpy, + /// char *stpncpy(char *s1, const char *s2, size_t n); + stpncpy, + /// int strcasecmp(const char *s1, const char *s2); + strcasecmp, /// char *strcat(char *s1, const char *s2); strcat, /// char *strchr(const char *s, int c); strchr, /// int strcmp(const char *s1, const char *s2); strcmp, + /// int strcoll(const char *s1, const char *s2); + strcoll, /// char *strcpy(char *s1, const char *s2); strcpy, /// size_t strcspn(const char *s1, const char *s2); @@ -292,6 +523,8 @@ namespace llvm { strdup, /// size_t strlen(const char *s); strlen, + /// int strncasecmp(const char *s1, const char *s2, size_t n); + strncasecmp, /// char *strncat(char *s1, const char *s2, size_t n); strncat, /// int strncmp(const char *s1, const char *s2, size_t n); @@ -314,6 +547,10 @@ namespace llvm { strtod, /// float strtof(const char *nptr, char **endptr); strtof, + // char *strtok(char *s1, const char *s2); + strtok, + // char *strtok_r(char *s, const char *sep, char **lasts); + strtok_r, /// long int strtol(const char *nptr, char **endptr, int base); strtol, /// long double strtold(const char *nptr, char **endptr); @@ -325,6 +562,10 @@ namespace llvm { /// unsigned long long int strtoull(const char *nptr, char **endptr, /// int base); strtoull, + /// size_t strxfrm(char *s1, const char *s2, size_t n); + strxfrm, + /// int system(const char *command); + system, /// double tan(double x); tan, /// float tanf(float x); @@ -337,14 +578,50 @@ namespace llvm { tanhl, /// long double tanl(long double x); tanl, + /// clock_t times(struct tms *buffer); + times, + /// FILE *tmpfile(void); + tmpfile, + /// FILE *tmpfile64(void) + tmpfile64, + /// int toascii(int c); + toascii, /// double trunc(double x); trunc, /// float truncf(float x); truncf, /// long double truncl(long double x); truncl, + /// int uname(struct utsname *name); + uname, + /// int ungetc(int c, FILE *stream); + ungetc, + /// int unlink(const char *path); + unlink, + /// int unsetenv(const char *name); + unsetenv, + /// int utime(const char *path, const struct utimbuf *times); + utime, + /// int utimes(const char *path, const struct timeval times[2]); + utimes, /// void *valloc(size_t size); valloc, + /// int vfprintf(FILE *stream, const char *format, va_list ap); + vfprintf, + /// int vfscanf(FILE *stream, const char *format, va_list arg); + vfscanf, + /// int vprintf(const char *restrict format, va_list ap); + vprintf, + /// int vscanf(const char *format, va_list arg); + vscanf, + /// int vsnprintf(char *s, size_t n, const char *format, va_list ap); + vsnprintf, + /// int vsprintf(char *s, const char *format, va_list ap); + vsprintf, + /// int vsscanf(const char *s, const char *format, va_list arg); + vsscanf, + /// ssize_t write(int fildes, const void *buf, size_t nbyte); + write, NumLibFuncs }; diff --git a/contrib/llvm/include/llvm/Target/TargetLowering.h b/contrib/llvm/include/llvm/Target/TargetLowering.h index 580a30f..1786bd2 100644 --- a/contrib/llvm/include/llvm/Target/TargetLowering.h +++ b/contrib/llvm/include/llvm/Target/TargetLowering.h @@ -22,14 +22,14 @@ #ifndef LLVM_TARGET_TARGETLOWERING_H #define LLVM_TARGET_TARGETLOWERING_H -#include "llvm/AddressingMode.h" -#include "llvm/CallingConv.h" -#include "llvm/InlineAsm.h" -#include "llvm/Attributes.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/Support/CallSite.h" -#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/CodeGen/DAGCombine.h" #include "llvm/CodeGen/RuntimeLibcalls.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Target/TargetCallingConv.h" #include "llvm/Target/TargetMachine.h" @@ -68,18 +68,12 @@ namespace llvm { }; } +/// TargetLoweringBase - This base class for TargetLowering contains the +/// SelectionDAG-independent parts that can be used from the rest of CodeGen. +class TargetLoweringBase { + TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; + void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; -//===----------------------------------------------------------------------===// -/// TargetLowering - This class defines information used to lower LLVM code to -/// legal SelectionDAG operators that the target instruction selector can accept -/// natively. -/// -/// This class also defines callbacks that targets must implement to lower -/// target-specific constructs to SelectionDAG operators. -/// -class TargetLowering { - TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION; - void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION; public: /// LegalizeAction - This enum indicates whether operations are valid for a /// target, and if not, what action should be used to make them valid. @@ -137,9 +131,9 @@ public: } /// NOTE: The constructor takes ownership of TLOF. - explicit TargetLowering(const TargetMachine &TM, - const TargetLoweringObjectFile *TLOF); - virtual ~TargetLowering(); + explicit TargetLoweringBase(const TargetMachine &TM, + const TargetLoweringObjectFile *TLOF); + virtual ~TargetLoweringBase(); const TargetMachine &getTargetMachine() const { return TM; } const DataLayout *getDataLayout() const { return TD; } @@ -151,7 +145,9 @@ public: // the pointer type from the data layout. // FIXME: The default needs to be removed once all the code is updated. virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; } - virtual MVT getShiftAmountTy(EVT LHSTy) const; + virtual MVT getScalarShiftAmountTy(EVT LHSTy) const; + + EVT getShiftAmountTy(EVT LHSTy) const; /// isSelectExpensive - Return true if the select operation is expensive for /// this target. @@ -159,6 +155,11 @@ public: virtual bool isSelectSupported(SelectSupportKind kind) const { return true; } + /// shouldSplitVectorElementType - Return true if a vector of the given type + /// should be split (TypeSplitVector) instead of promoted + /// (TypePromoteInteger) during type legalization. + virtual bool shouldSplitVectorElementType(EVT VT) const { return false; } + /// isIntDivCheap() - Return true if integer divide is usually cheaper than /// a sequence of several shifts, adds, and multiplies for this target. bool isIntDivCheap() const { return IntDivIsCheap; } @@ -184,7 +185,7 @@ public: /// isPredictableSelectExpensive - Return true if selects are only cheaper /// than branches if the branch is unlikely to be predicted right. bool isPredictableSelectExpensive() const { - return predictableSelectIsExpensive; + return PredictableSelectIsExpensive; } /// getSetCCResultType - Return the ValueType of the result of SETCC @@ -227,9 +228,8 @@ public: /// getRegClassFor - Return the register class that should be used for the /// specified value type. - virtual const TargetRegisterClass *getRegClassFor(EVT VT) const { - assert(VT.isSimple() && "getRegClassFor called on illegal type!"); - const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy]; + virtual const TargetRegisterClass *getRegClassFor(MVT VT) const { + const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy]; assert(RC && "This value type is not natively supported!"); return RC; } @@ -239,17 +239,15 @@ public: /// legal super-reg register class for the register class of the value type. /// For example, on i386 the rep register class for i8, i16, and i32 are GR32; /// while the rep register class is GR64 on x86_64. - virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const { - assert(VT.isSimple() && "getRepRegClassFor called on illegal type!"); - const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().SimpleTy]; + virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const { + const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy]; return RC; } /// getRepRegClassCostFor - Return the cost of the 'representative' register /// class for the specified value type. - virtual uint8_t getRepRegClassCostFor(EVT VT) const { - assert(VT.isSimple() && "getRepRegClassCostFor called on illegal type!"); - return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy]; + virtual uint8_t getRepRegClassCostFor(MVT VT) const { + return RepRegClassCostForVT[VT.SimpleTy]; } /// isTypeLegal - Return true if the target has native support for the @@ -275,8 +273,8 @@ public: return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy]; } - void setTypeAction(EVT VT, LegalizeTypeAction Action) { - unsigned I = VT.getSimpleVT().SimpleTy; + void setTypeAction(MVT VT, LegalizeTypeAction Action) { + unsigned I = VT.SimpleTy; ValueTypeActions[I] = Action; } }; @@ -337,7 +335,7 @@ public: unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, - EVT &RegisterVT) const; + MVT &RegisterVT) const; /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If @@ -411,6 +409,15 @@ public: getOperationAction(Op, VT) == Custom); } + /// isOperationLegalOrPromote - Return true if the specified operation is + /// legal on this target or can be made legal using promotion. This + /// is used to help guide high-level lowering decisions. + bool isOperationLegalOrPromote(unsigned Op, EVT VT) const { + return (VT == MVT::Other || isTypeLegal(VT)) && + (getOperationAction(Op, VT) == Legal || + getOperationAction(Op, VT) == Promote); + } + /// isOperationExpand - Return true if the specified operation is illegal on /// this target or unlikely to be made legal with custom lowering. This is /// used to help guide high-level lowering decisions. @@ -429,36 +436,35 @@ public: /// either it is legal, needs to be promoted to a larger size, needs to be /// expanded to some other code sequence, or the target has a custom expander /// for it. - LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const { - assert(ExtType < ISD::LAST_LOADEXT_TYPE && - VT.getSimpleVT() < MVT::LAST_VALUETYPE && + LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const { + assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE && "Table isn't big enough!"); - return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtType]; + return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType]; } /// isLoadExtLegal - Return true if the specified load with extension is legal /// on this target. bool isLoadExtLegal(unsigned ExtType, EVT VT) const { - return VT.isSimple() && getLoadExtAction(ExtType, VT) == Legal; + return VT.isSimple() && + getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal; } /// getTruncStoreAction - Return how this store with truncation should be /// treated: either it is legal, needs to be promoted to a larger size, needs /// to be expanded to some other code sequence, or the target has a custom /// expander for it. - LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const { - assert(ValVT.getSimpleVT() < MVT::LAST_VALUETYPE && - MemVT.getSimpleVT() < MVT::LAST_VALUETYPE && + LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const { + assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE && "Table isn't big enough!"); - return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy] - [MemVT.getSimpleVT().SimpleTy]; + return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy] + [MemVT.SimpleTy]; } /// isTruncStoreLegal - Return true if the specified store with truncation is /// legal on this target. bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const { return isTypeLegal(ValVT) && MemVT.isSimple() && - getTruncStoreAction(ValVT, MemVT) == Legal; + getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal; } /// getIndexedLoadAction - Return how the indexed load should be treated: @@ -466,11 +472,10 @@ public: /// expanded to some other code sequence, or the target has a custom expander /// for it. LegalizeAction - getIndexedLoadAction(unsigned IdxMode, EVT VT) const { - assert(IdxMode < ISD::LAST_INDEXED_MODE && - VT.getSimpleVT() < MVT::LAST_VALUETYPE && + getIndexedLoadAction(unsigned IdxMode, MVT VT) const { + assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE && "Table isn't big enough!"); - unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy; + unsigned Ty = (unsigned)VT.SimpleTy; return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4); } @@ -478,8 +483,8 @@ public: /// on this target. bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const { return VT.isSimple() && - (getIndexedLoadAction(IdxMode, VT) == Legal || - getIndexedLoadAction(IdxMode, VT) == Custom); + (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal || + getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom); } /// getIndexedStoreAction - Return how the indexed store should be treated: @@ -487,11 +492,10 @@ public: /// expanded to some other code sequence, or the target has a custom expander /// for it. LegalizeAction - getIndexedStoreAction(unsigned IdxMode, EVT VT) const { - assert(IdxMode < ISD::LAST_INDEXED_MODE && - VT.getSimpleVT() < MVT::LAST_VALUETYPE && + getIndexedStoreAction(unsigned IdxMode, MVT VT) const { + assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE && "Table isn't big enough!"); - unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy; + unsigned Ty = (unsigned)VT.SimpleTy; return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f); } @@ -499,54 +503,54 @@ public: /// on this target. bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const { return VT.isSimple() && - (getIndexedStoreAction(IdxMode, VT) == Legal || - getIndexedStoreAction(IdxMode, VT) == Custom); + (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal || + getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom); } /// getCondCodeAction - Return how the condition code should be treated: /// either it is legal, needs to be expanded to some other code sequence, /// or the target has a custom expander for it. LegalizeAction - getCondCodeAction(ISD::CondCode CC, EVT VT) const { + getCondCodeAction(ISD::CondCode CC, MVT VT) const { assert((unsigned)CC < array_lengthof(CondCodeActions) && - (unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0])*4 && + (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 && "Table isn't big enough!"); /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit /// value and the upper 27 bits index into the second dimension of the /// array to select what 64bit value to use. LegalizeAction Action = (LegalizeAction) - ((CondCodeActions[CC][VT.getSimpleVT().SimpleTy >> 5] - >> (2*(VT.getSimpleVT().SimpleTy & 0x1F))) & 3); + ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3); assert(Action != Promote && "Can't promote condition code!"); return Action; } /// isCondCodeLegal - Return true if the specified condition code is legal /// on this target. - bool isCondCodeLegal(ISD::CondCode CC, EVT VT) const { - return getCondCodeAction(CC, VT) == Legal || - getCondCodeAction(CC, VT) == Custom; + bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const { + return + getCondCodeAction(CC, VT) == Legal || + getCondCodeAction(CC, VT) == Custom; } /// getTypeToPromoteTo - If the action for this operation is to promote, this /// method returns the ValueType to promote to. - EVT getTypeToPromoteTo(unsigned Op, EVT VT) const { + MVT getTypeToPromoteTo(unsigned Op, MVT VT) const { assert(getOperationAction(Op, VT) == Promote && "This operation isn't promoted!"); // See if this has an explicit type specified. std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>::const_iterator PTTI = - PromoteToType.find(std::make_pair(Op, VT.getSimpleVT().SimpleTy)); + PromoteToType.find(std::make_pair(Op, VT.SimpleTy)); if (PTTI != PromoteToType.end()) return PTTI->second; assert((VT.isInteger() || VT.isFloatingPoint()) && "Cannot autopromote this type, add it with AddPromotedToType."); - EVT NVT = VT; + MVT NVT = VT; do { - NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1); + NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1); assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid && "Didn't find type to promote to!"); } while (!isTypeLegal(NVT) || @@ -573,7 +577,11 @@ public: } return EVT::getEVT(Ty, AllowUnknown); } - + + /// Return the MVT corresponding to this LLVM type. See getValueType. + MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const { + return getValueType(Ty, AllowUnknown).getSimpleVT(); + } /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate /// function arguments in the caller parameter area. This is the actual @@ -582,21 +590,22 @@ public: /// getRegisterType - Return the type of registers that this ValueType will /// eventually require. - EVT getRegisterType(MVT VT) const { + MVT getRegisterType(MVT VT) const { assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT)); return RegisterTypeForVT[VT.SimpleTy]; } /// getRegisterType - Return the type of registers that this ValueType will /// eventually require. - EVT getRegisterType(LLVMContext &Context, EVT VT) const { + MVT getRegisterType(LLVMContext &Context, EVT VT) const { if (VT.isSimple()) { assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegisterTypeForVT)); return RegisterTypeForVT[VT.getSimpleVT().SimpleTy]; } if (VT.isVector()) { - EVT VT1, RegisterVT; + EVT VT1; + MVT RegisterVT; unsigned NumIntermediates; (void)getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, RegisterVT); @@ -621,7 +630,8 @@ public: return NumRegistersForVT[VT.getSimpleVT().SimpleTy]; } if (VT.isVector()) { - EVT VT1, VT2; + EVT VT1; + MVT VT2; unsigned NumIntermediates; return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2); } @@ -651,7 +661,7 @@ public: /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memset unsigned getMaxStoresPerMemset(bool OptSize) const { - return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset; + return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset; } /// This function returns the maximum number of store operations permitted @@ -660,7 +670,7 @@ public: /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memcpy unsigned getMaxStoresPerMemcpy(bool OptSize) const { - return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy; + return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy; } /// This function returns the maximum number of store operations permitted @@ -669,46 +679,51 @@ public: /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memmove unsigned getMaxStoresPerMemmove(bool OptSize) const { - return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove; + return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove; } /// This function returns true if the target allows unaligned memory accesses. - /// of the specified type. This is used, for example, in situations where an - /// array copy/move/set is converted to a sequence of store operations. It's - /// use helps to ensure that such replacements don't generate code that causes - /// an alignment error (trap) on the target machine. + /// of the specified type. If true, it also returns whether the unaligned + /// memory access is "fast" in the second argument by reference. This is used, + /// for example, in situations where an array copy/move/set is converted to a + /// sequence of store operations. It's use helps to ensure that such + /// replacements don't generate code that causes an alignment error (trap) on + /// the target machine. /// @brief Determine if the target supports unaligned memory accesses. - virtual bool allowsUnalignedMemoryAccesses(EVT) const { + virtual bool allowsUnalignedMemoryAccesses(EVT, bool *Fast = 0) const { return false; } - /// This function returns true if the target would benefit from code placement - /// optimization. - /// @brief Determine if the target should perform code placement optimization. - bool shouldOptimizeCodePlacement() const { - return benefitFromCodePlacementOpt; - } - /// getOptimalMemOpType - Returns the target specific optimal type for load /// and store operations as a result of memset, memcpy, and memmove /// lowering. If DstAlign is zero that means it's safe to destination /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it /// means there isn't a need to check it against alignment requirement, - /// probably because the source does not need to be loaded. If - /// 'IsZeroVal' is true, that means it's safe to return a - /// non-scalar-integer type, e.g. empty string source, constant, or loaded - /// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is - /// constant so it does not need to be loaded. + /// probably because the source does not need to be loaded. If 'IsMemset' is + /// true, that means it's expanding a memset. If 'ZeroMemset' is true, that + /// means it's a memset of zero. 'MemcpyStrSrc' indicates whether the memcpy + /// source is constant so it does not need to be loaded. /// It returns EVT::Other if the type should be determined using generic /// target-independent logic. virtual EVT getOptimalMemOpType(uint64_t /*Size*/, unsigned /*DstAlign*/, unsigned /*SrcAlign*/, - bool /*IsZeroVal*/, + bool /*IsMemset*/, + bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/, MachineFunction &/*MF*/) const { return MVT::Other; } + /// isSafeMemOpType - Returns true if it's safe to use load / store of the + /// specified type to expand memcpy / memset inline. This is mostly true + /// for all types except for some special cases. For example, on X86 + /// targets without SSE2 f64 load / store are done with fldl / fstpl which + /// also does type conversion. Note the specified type doesn't have to be + /// legal as the hook is used before type legalization. + virtual bool isSafeMemOpType(MVT VT) const { + return true; + } + /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp /// to implement llvm.setjmp. bool usesUnderscoreSetJmp() const { @@ -804,55 +819,6 @@ public: return InsertFencesForAtomic; } - /// getPreIndexedAddressParts - returns true by value, base pointer and - /// offset pointer and addressing mode by reference if the node's address - /// can be legally represented as pre-indexed load / store address. - virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/, - SDValue &/*Offset*/, - ISD::MemIndexedMode &/*AM*/, - SelectionDAG &/*DAG*/) const { - return false; - } - - /// getPostIndexedAddressParts - returns true by value, base pointer and - /// offset pointer and addressing mode by reference if this node can be - /// combined with a load / store to form a post-indexed load / store. - virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, - SDValue &/*Base*/, SDValue &/*Offset*/, - ISD::MemIndexedMode &/*AM*/, - SelectionDAG &/*DAG*/) const { - return false; - } - - /// getJumpTableEncoding - Return the entry encoding for a jump table in the - /// current function. The returned value is a member of the - /// MachineJumpTableInfo::JTEntryKind enum. - virtual unsigned getJumpTableEncoding() const; - - virtual const MCExpr * - LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/, - const MachineBasicBlock * /*MBB*/, unsigned /*uid*/, - MCContext &/*Ctx*/) const { - llvm_unreachable("Need to implement this hook if target has custom JTIs"); - } - - /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC - /// jumptable. - virtual SDValue getPICJumpTableRelocBase(SDValue Table, - SelectionDAG &DAG) const; - - /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the - /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an - /// MCExpr. - virtual const MCExpr * - getPICJumpTableRelocBaseExpr(const MachineFunction *MF, - unsigned JTI, MCContext &Ctx) const; - - /// isOffsetFoldingLegal - Return true if folding a constant offset - /// with the given GlobalAddress is legal. It is frequently not legal in - /// PIC relocation models. - virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; - /// getStackCookieLocation - Return true if the target stores stack /// protector cookies at a fixed offset in some non-standard address /// space, and populates the address space and offset as @@ -869,148 +835,16 @@ public: } //===--------------------------------------------------------------------===// - // TargetLowering Optimization Methods - // - - /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two - /// SDValues for returning information from TargetLowering to its clients - /// that want to combine - struct TargetLoweringOpt { - SelectionDAG &DAG; - bool LegalTys; - bool LegalOps; - SDValue Old; - SDValue New; - - explicit TargetLoweringOpt(SelectionDAG &InDAG, - bool LT, bool LO) : - DAG(InDAG), LegalTys(LT), LegalOps(LO) {} - - bool LegalTypes() const { return LegalTys; } - bool LegalOperations() const { return LegalOps; } - - bool CombineTo(SDValue O, SDValue N) { - Old = O; - New = N; - return true; - } - - /// ShrinkDemandedConstant - Check to see if the specified operand of the - /// specified instruction is a constant integer. If so, check to see if - /// there are any bits set in the constant that are not demanded. If so, - /// shrink the constant and return true. - bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded); - - /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the - /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening - /// cast, but it could be generalized for targets with other types of - /// implicit widening casts. - bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, - DebugLoc dl); - }; - - /// SimplifyDemandedBits - Look at Op. At this point, we know that only the - /// DemandedMask bits of the result of Op are ever used downstream. If we can - /// use this information to simplify Op, create a new simplified DAG node and - /// return true, returning the original and new nodes in Old and New. - /// Otherwise, analyze the expression and return a mask of KnownOne and - /// KnownZero bits for the expression (used to simplify the caller). - /// The KnownZero/One bits may only be accurate for those bits in the - /// DemandedMask. - bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, - APInt &KnownZero, APInt &KnownOne, - TargetLoweringOpt &TLO, unsigned Depth = 0) const; - - /// computeMaskedBitsForTargetNode - Determine which of the bits specified in - /// Mask are known to be either zero or one and return them in the - /// KnownZero/KnownOne bitsets. - virtual void computeMaskedBitsForTargetNode(const SDValue Op, - APInt &KnownZero, - APInt &KnownOne, - const SelectionDAG &DAG, - unsigned Depth = 0) const; - - /// ComputeNumSignBitsForTargetNode - This method can be implemented by - /// targets that want to expose additional information about sign bits to the - /// DAG Combiner. - virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, - unsigned Depth = 0) const; - - struct DAGCombinerInfo { - void *DC; // The DAG Combiner object. - bool BeforeLegalize; - bool BeforeLegalizeOps; - bool CalledByLegalizer; - public: - SelectionDAG &DAG; - - DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc) - : DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo), - CalledByLegalizer(cl), DAG(dag) {} + /// \name Helpers for TargetTransformInfo implementations + /// @{ - bool isBeforeLegalize() const { return BeforeLegalize; } - bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; } - bool isCalledByLegalizer() const { return CalledByLegalizer; } + /// Get the ISD node that corresponds to the Instruction class opcode. + int InstructionOpcodeToISD(unsigned Opcode) const; - 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); - SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true); - - void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); - }; - - /// SimplifySetCC - Try to simplify a setcc built with the specified operands - /// and cc. If it is unable to simplify it, return a null SDValue. - SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, - ISD::CondCode Cond, bool foldBooleans, - DAGCombinerInfo &DCI, DebugLoc dl) const; + /// Estimate the cost of type-legalization and the legalized type. + std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; - /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the - /// node is a GlobalAddress + offset. - virtual bool - isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const; - - /// PerformDAGCombine - This method will be invoked for all target nodes and - /// for any target-independent nodes that the target has registered with - /// invoke it for. - /// - /// The semantics are as follows: - /// Return Value: - /// SDValue.Val == 0 - No change was made - /// SDValue.Val == N - N was replaced, is dead, and is already handled. - /// otherwise - N should be replaced by the returned Operand. - /// - /// In addition, methods provided by DAGCombinerInfo may be used to perform - /// more complex transformations. - /// - virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; - - /// isTypeDesirableForOp - Return true if the target has native support for - /// the specified value type and it is 'desirable' to use the type for the - /// given node type. e.g. On x86 i16 is legal, but undesirable since i16 - /// instruction encodings are longer and some i16 instructions are slow. - virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const { - // By default, assume all legal types are desirable. - return isTypeLegal(VT); - } - - /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner - /// to transform a floating point op of specified opcode to a equivalent op of - /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM. - virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/, - EVT /*VT*/) const { - return false; - } - - /// IsDesirableToPromoteOp - This method query the target whether it is - /// beneficial for dag combiner to promote the specified node. If true, it - /// should return the desired promotion type by reference. - virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const { - return false; - } + /// @} //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by @@ -1111,16 +945,23 @@ protected: /// addRegisterClass - Add the specified register class as an available /// regclass for the specified value type. This indicates the selector can /// handle values of that class natively. - void addRegisterClass(EVT VT, const TargetRegisterClass *RC) { - assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT)); + void addRegisterClass(MVT VT, const TargetRegisterClass *RC) { + assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT)); AvailableRegClasses.push_back(std::make_pair(VT, RC)); - RegClassForVT[VT.getSimpleVT().SimpleTy] = RC; + RegClassForVT[VT.SimpleTy] = RC; + } + + /// clearRegisterClasses - remove all register classes + void clearRegisterClasses() { + for (unsigned i = 0 ; i<array_lengthof(RegClassForVT); i++) + RegClassForVT[i] = 0; + AvailableRegClasses.clear(); } /// findRepresentativeClass - Return the largest legal super-reg register class /// of the register class for the specified type and its associated "cost". virtual std::pair<const TargetRegisterClass*, uint8_t> - findRepresentativeClass(EVT VT) const; + findRepresentativeClass(MVT VT) const; /// computeRegisterProperties - Once all of the register classes are added, /// this allows us to compute derived properties we expose. @@ -1263,387 +1104,6 @@ protected: public: //===--------------------------------------------------------------------===// - // Lowering methods - These methods must be implemented by targets so that - // the SelectionDAGBuilder code knows how to lower these. - // - - /// LowerFormalArguments - This hook must be implemented to lower the - /// incoming (formal) arguments, described by the Ins array, into the - /// specified DAG. The implementation should fill in the InVals array - /// with legal-type argument values, and return the resulting token - /// chain value. - /// - virtual SDValue - LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, - bool /*isVarArg*/, - const SmallVectorImpl<ISD::InputArg> &/*Ins*/, - DebugLoc /*dl*/, SelectionDAG &/*DAG*/, - SmallVectorImpl<SDValue> &/*InVals*/) const { - llvm_unreachable("Not Implemented"); - } - - struct ArgListEntry { - SDValue Node; - Type* Ty; - bool isSExt : 1; - bool isZExt : 1; - bool isInReg : 1; - bool isSRet : 1; - bool isNest : 1; - bool isByVal : 1; - uint16_t Alignment; - - ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), - isSRet(false), isNest(false), isByVal(false), Alignment(0) { } - }; - typedef std::vector<ArgListEntry> ArgListTy; - - /// CallLoweringInfo - This structure contains all information that is - /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the - /// SelectionDAG builder needs to lower a call, and targets will see this - /// struct in their LowerCall implementation. - struct CallLoweringInfo { - SDValue Chain; - Type *RetTy; - bool RetSExt : 1; - bool RetZExt : 1; - bool IsVarArg : 1; - bool IsInReg : 1; - bool DoesNotReturn : 1; - bool IsReturnValueUsed : 1; - - // IsTailCall should be modified by implementations of - // TargetLowering::LowerCall that perform tail call conversions. - bool IsTailCall; - - unsigned NumFixedArgs; - CallingConv::ID CallConv; - SDValue Callee; - ArgListTy &Args; - SelectionDAG &DAG; - DebugLoc DL; - ImmutableCallSite *CS; - SmallVector<ISD::OutputArg, 32> Outs; - SmallVector<SDValue, 32> OutVals; - SmallVector<ISD::InputArg, 32> Ins; - - - /// CallLoweringInfo - Constructs a call lowering context based on the - /// ImmutableCallSite \p cs. - CallLoweringInfo(SDValue chain, Type *retTy, - FunctionType *FTy, bool isTailCall, SDValue callee, - ArgListTy &args, SelectionDAG &dag, DebugLoc dl, - ImmutableCallSite &cs) - : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attributes::SExt)), - RetZExt(cs.paramHasAttr(0, Attributes::ZExt)), IsVarArg(FTy->isVarArg()), - IsInReg(cs.paramHasAttr(0, Attributes::InReg)), - DoesNotReturn(cs.doesNotReturn()), - IsReturnValueUsed(!cs.getInstruction()->use_empty()), - IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()), - CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag), - DL(dl), CS(&cs) {} - - /// CallLoweringInfo - Constructs a call lowering context based on the - /// provided call information. - CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt, - bool isVarArg, bool isInReg, unsigned numFixedArgs, - CallingConv::ID callConv, bool isTailCall, - bool doesNotReturn, bool isReturnValueUsed, SDValue callee, - ArgListTy &args, SelectionDAG &dag, DebugLoc dl) - : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt), - IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn), - IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall), - NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee), - Args(args), DAG(dag), DL(dl), CS(NULL) {} - }; - - /// LowerCallTo - This function lowers an abstract call to a function into an - /// actual call. This returns a pair of operands. The first element is the - /// return value for the function (if RetTy is not VoidTy). The second - /// element is the outgoing token chain. It calls LowerCall to do the actual - /// lowering. - std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const; - - /// LowerCall - This hook must be implemented to lower calls into the - /// the specified DAG. The outgoing arguments to the call are described - /// by the Outs array, and the values to be returned by the call are - /// described by the Ins array. The implementation should fill in the - /// InVals array with legal-type return values from the call, and return - /// the resulting token chain value. - virtual SDValue - LowerCall(CallLoweringInfo &/*CLI*/, - SmallVectorImpl<SDValue> &/*InVals*/) const { - llvm_unreachable("Not Implemented"); - } - - /// HandleByVal - Target-specific cleanup for formal ByVal parameters. - virtual void HandleByVal(CCState *, unsigned &, 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. - /// - virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/, - MachineFunction &/*MF*/, bool /*isVarArg*/, - const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, - LLVMContext &/*Context*/) const - { - // Return true by default to get preexisting behavior. - return true; - } - - /// LowerReturn - This hook must be implemented to lower outgoing - /// return values, described by the Outs array, into the specified - /// DAG. The implementation should return the resulting token chain - /// value. - /// - virtual SDValue - LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, - bool /*isVarArg*/, - const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, - const SmallVectorImpl<SDValue> &/*OutVals*/, - DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { - llvm_unreachable("Not Implemented"); - } - - /// isUsedByReturnOnly - Return true if result of the specified node is used - /// by a return node only. It also compute and return the input chain for the - /// tail call. - /// This is used to determine whether it is possible - /// to codegen a libcall as tail call at legalization time. - virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const { - 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 *) 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. - /// The reason we can not do away with LowerOperation entirely is that - /// LegalizeDAG isn't yet ready to use this callback. - /// TODO: Consider merging with ReplaceNodeResults. - - /// The target places new result values for the node in Results (their number - /// and types must exactly match those of the original return values of - /// the node), or leaves Results empty, which indicates that the node is not - /// to be custom lowered after all. - /// The default implementation calls LowerOperation. - virtual void LowerOperationWrapper(SDNode *N, - SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG) const; - - /// LowerOperation - This callback is invoked for operations that are - /// unsupported by the target, which are registered to use 'custom' lowering, - /// and whose defined values are all legal. - /// If the target has no operations that require custom lowering, it need not - /// implement this. The default implementation of this aborts. - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; - - /// ReplaceNodeResults - This callback is invoked when a node result type is - /// illegal for the target, and the operation was registered to use 'custom' - /// lowering for that result type. The target places new result values for - /// the node in Results (their number and types must exactly match those of - /// the original return values of the node), or leaves Results empty, which - /// indicates that the node is not to be custom lowered after all. - /// - /// If the target has no operations that require custom lowering, it need not - /// implement this. The default implementation aborts. - virtual void ReplaceNodeResults(SDNode * /*N*/, - SmallVectorImpl<SDValue> &/*Results*/, - SelectionDAG &/*DAG*/) const { - llvm_unreachable("ReplaceNodeResults not implemented for this target!"); - } - - /// getTargetNodeName() - This method returns the name of a target specific - /// DAG node. - virtual const char *getTargetNodeName(unsigned Opcode) const; - - /// createFastISel - This method returns a target specific FastISel object, - /// or null if the target does not support "fast" ISel. - virtual FastISel *createFastISel(FunctionLoweringInfo &, - const TargetLibraryInfo *) const { - return 0; - } - - //===--------------------------------------------------------------------===// - // Inline Asm Support hooks - // - - /// ExpandInlineAsm - This hook allows the target to expand an inline asm - /// call to be explicit llvm code if it wants to. This is useful for - /// turning simple inline asms into LLVM intrinsics, which gives the - /// compiler more information about the behavior of the code. - virtual bool ExpandInlineAsm(CallInst *) const { - return false; - } - - enum ConstraintType { - C_Register, // Constraint represents specific register(s). - C_RegisterClass, // Constraint represents any of register(s) in class. - C_Memory, // Memory constraint. - C_Other, // Something else. - C_Unknown // Unsupported constraint. - }; - - enum ConstraintWeight { - // Generic weights. - CW_Invalid = -1, // No match. - CW_Okay = 0, // Acceptable. - CW_Good = 1, // Good weight. - CW_Better = 2, // Better weight. - CW_Best = 3, // Best weight. - - // Well-known weights. - CW_SpecificReg = CW_Okay, // Specific register operands. - CW_Register = CW_Good, // Register operands. - CW_Memory = CW_Better, // Memory operands. - CW_Constant = CW_Best, // Constant operand. - CW_Default = CW_Okay // Default or don't know type. - }; - - /// AsmOperandInfo - This contains information for each constraint that we are - /// lowering. - struct AsmOperandInfo : public InlineAsm::ConstraintInfo { - /// ConstraintCode - This contains the actual string for the code, like "m". - /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that - /// most closely matches the operand. - std::string ConstraintCode; - - /// ConstraintType - Information about the constraint code, e.g. Register, - /// RegisterClass, Memory, Other, Unknown. - TargetLowering::ConstraintType ConstraintType; - - /// CallOperandval - If this is the result output operand or a - /// clobber, this is null, otherwise it is the incoming operand to the - /// CallInst. This gets modified as the asm is processed. - Value *CallOperandVal; - - /// ConstraintVT - The ValueType for the operand value. - EVT ConstraintVT; - - /// isMatchingInputConstraint - Return true of this is an input operand that - /// is a matching constraint like "4". - bool isMatchingInputConstraint() const; - - /// getMatchedOperand - If this is an input matching constraint, this method - /// returns the output operand it matches. - unsigned getMatchedOperand() const; - - /// Copy constructor for copying from an AsmOperandInfo. - AsmOperandInfo(const AsmOperandInfo &info) - : InlineAsm::ConstraintInfo(info), - ConstraintCode(info.ConstraintCode), - ConstraintType(info.ConstraintType), - CallOperandVal(info.CallOperandVal), - ConstraintVT(info.ConstraintVT) { - } - - /// Copy constructor for copying from a ConstraintInfo. - AsmOperandInfo(const InlineAsm::ConstraintInfo &info) - : InlineAsm::ConstraintInfo(info), - ConstraintType(TargetLowering::C_Unknown), - CallOperandVal(0), ConstraintVT(MVT::Other) { - } - }; - - typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; - - /// ParseConstraints - Split up the constraint string from the inline - /// assembly value into the specific constraints and their prefixes, - /// and also tie in the associated operand values. - /// If this returns an empty vector, and if the constraint string itself - /// isn't empty, there was an error parsing. - virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const; - - /// Examine constraint type and operand type and determine a weight value. - /// The operand object must already have been set up with the operand type. - virtual ConstraintWeight getMultipleConstraintMatchWeight( - AsmOperandInfo &info, int maIndex) const; - - /// Examine constraint string and operand type and determine a weight value. - /// The operand object must already have been set up with the operand type. - virtual ConstraintWeight getSingleConstraintMatchWeight( - AsmOperandInfo &info, const char *constraint) const; - - /// ComputeConstraintToUse - Determines the constraint code and constraint - /// type to use for the specific AsmOperandInfo, setting - /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand - /// being passed in is available, it can be passed in as Op, otherwise an - /// empty SDValue can be passed. - virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, - SDValue Op, - SelectionDAG *DAG = 0) const; - - /// getConstraintType - Given a constraint, return the type of constraint it - /// is for this target. - virtual ConstraintType getConstraintType(const std::string &Constraint) const; - - /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. - /// {edx}), return the register number and the register class for the - /// register. - /// - /// Given a register class constraint, like 'r', if this corresponds directly - /// to an LLVM register class, return a register of 0 and the register class - /// pointer. - /// - /// This should only be used for C_Register constraints. On error, - /// this returns a register number of 0 and a null register class pointer.. - virtual std::pair<unsigned, const TargetRegisterClass*> - getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; - - /// LowerXConstraint - try to replace an X constraint, which matches anything, - /// with another that has more specific requirements based on the type of the - /// corresponding operand. This returns null if there is no replacement to - /// make. - virtual const char *LowerXConstraint(EVT ConstraintVT) const; - - /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops - /// vector. If it is invalid, don't add anything to Ops. - virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, - std::vector<SDValue> &Ops, - SelectionDAG &DAG) const; - - //===--------------------------------------------------------------------===// - // Instruction Emitting Hooks - // - - // EmitInstrWithCustomInserter - This method should be implemented by targets - // that mark instructions with the 'usesCustomInserter' flag. These - // instructions are special in various ways, which require special support to - // insert. The specified MachineInstr is created but not inserted into any - // basic blocks, and this method is called to expand it into a sequence of - // instructions, potentially also creating new basic blocks and control flow. - virtual MachineBasicBlock * - EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; - - /// AdjustInstrPostInstrSelection - This method should be implemented by - /// targets that mark instructions with the 'hasPostISelHook' flag. These - /// instructions must be adjusted after instruction selection by target hooks. - /// e.g. To fill in optional defs for ARM 's' setting instructions. - virtual void - AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; - - //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). // @@ -1658,6 +1118,22 @@ public: return false; } + /// AddrMode - This represents an addressing mode of: + /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + /// If BaseGV is null, there is no BaseGV. + /// If BaseOffs is zero, there is no base offset. + /// If HasBaseReg is false, there is no base register. + /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with + /// no scale. + /// + struct AddrMode { + GlobalValue *BaseGV; + int64_t BaseOffs; + bool HasBaseReg; + int64_t Scale; + AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} + }; + /// isLegalAddressingMode - Return true if the addressing mode represented by /// AM is legal for this target, for a load/store of the specified type. /// The type may be VoidTy, in which case only return true if the addressing @@ -1708,6 +1184,13 @@ public: return false; } + /// isZExtFree - Return true if zero-extending the specific node Val to type + /// VT2 is free (either because it's implicitly zero-extended such as ARM + /// ldrb / ldrh or because it's folded such as X86 zero-extending loads). + virtual bool isZExtFree(SDValue Val, EVT VT2) const { + return isZExtFree(Val.getValueType(), VT2); + } + /// isFNegFree - Return true if an fneg operation is free to the point where /// it is never worthwhile to replace it with a bitwise operation. virtual bool isFNegFree(EVT) const { @@ -1736,17 +1219,6 @@ public: } //===--------------------------------------------------------------------===// - // Div utility functions - // - SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, - SelectionDAG &DAG) const; - SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector<SDNode*>* Created) const; - SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector<SDNode*>* Created) const; - - - //===--------------------------------------------------------------------===// // Runtime Library hooks // @@ -1909,7 +1381,7 @@ private: /// each ValueType the target supports natively. const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE]; unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE]; - EVT RegisterTypeForVT[MVT::LAST_VALUETYPE]; + MVT RegisterTypeForVT[MVT::LAST_VALUETYPE]; /// RepRegClassForVT - This indicates the "representative" register class to /// use for each ValueType the target supports natively. This information is @@ -1929,7 +1401,7 @@ private: /// contains one step of the expand (e.g. i64 -> i32), even if there are /// multiple steps required (e.g. i64 -> i16). For types natively supported /// by the system, this holds the same type (e.g. i32 -> i32). - EVT TransformToType[MVT::LAST_VALUETYPE]; + MVT TransformToType[MVT::LAST_VALUETYPE]; /// OpActions - For each operation and each value type, keep a LegalizeAction /// that indicates how instruction selection should deal with the operation. @@ -1970,19 +1442,22 @@ public: getTypeConversion(LLVMContext &Context, EVT VT) const { // If this is a simple type, use the ComputeRegisterProp mechanism. if (VT.isSimple()) { - assert((unsigned)VT.getSimpleVT().SimpleTy < - array_lengthof(TransformToType)); - EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; - LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT()); + MVT SVT = VT.getSimpleVT(); + assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType)); + MVT NVT = TransformToType[SVT.SimpleTy]; + LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT); assert( - (!(NVT.isSimple() && LA != TypeLegal) || - ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger) + (LA == TypeLegal || + ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger) && "Promote may not follow Expand or Promote"); if (LA == TypeSplitVector) - NVT = EVT::getVectorVT(Context, VT.getVectorElementType(), - VT.getVectorNumElements() / 2); + return LegalizeKind(LA, EVT::getVectorVT(Context, + SVT.getVectorElementType(), + SVT.getVectorNumElements()/2)); + if (LA == TypeScalarizeVector) + return LegalizeKind(LA, SVT.getVectorElementType()); return LegalizeKind(LA, NVT); } @@ -2086,7 +1561,7 @@ public: } private: - std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses; + std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses; /// TargetDAGCombineArray - Targets can specify ISD nodes that they would /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(), @@ -2125,11 +1600,11 @@ protected: /// with 16-bit alignment would result in four 2-byte stores and one 1-byte /// store. This only applies to setting a constant array of a constant size. /// @brief Specify maximum number of store instructions per memset call. - unsigned maxStoresPerMemset; + unsigned MaxStoresPerMemset; /// Maximum number of stores operations that may be substituted for the call /// to memset, used for functions with OptSize attribute. - unsigned maxStoresPerMemsetOptSize; + unsigned MaxStoresPerMemsetOptSize; /// When lowering \@llvm.memcpy this field specifies the maximum number of /// store operations that may be substituted for a call to memcpy. Targets @@ -2141,11 +1616,11 @@ protected: /// and one 1-byte store. This only applies to copying a constant array of /// constant size. /// @brief Specify maximum bytes of store instructions per memcpy call. - unsigned maxStoresPerMemcpy; + unsigned MaxStoresPerMemcpy; /// Maximum number of store operations that may be substituted for a call /// to memcpy, used for functions with OptSize attribute. - unsigned maxStoresPerMemcpyOptSize; + unsigned MaxStoresPerMemcpyOptSize; /// When lowering \@llvm.memmove this field specifies the maximum number of /// store instructions that may be substituted for a call to memmove. Targets @@ -2156,30 +1631,641 @@ protected: /// with 8-bit alignment would result in nine 1-byte stores. This only /// applies to copying a constant array of constant size. /// @brief Specify maximum bytes of store instructions per memmove call. - unsigned maxStoresPerMemmove; + unsigned MaxStoresPerMemmove; /// Maximum number of store instructions that may be substituted for a call /// to memmove, used for functions with OpSize attribute. - unsigned maxStoresPerMemmoveOptSize; - - /// This field specifies whether the target can benefit from code placement - /// optimization. - bool benefitFromCodePlacementOpt; + unsigned MaxStoresPerMemmoveOptSize; - /// predictableSelectIsExpensive - Tells the code generator that select is + /// PredictableSelectIsExpensive - Tells the code generator that select is /// more expensive than a branch if the branch is usually predicted right. - bool predictableSelectIsExpensive; + bool PredictableSelectIsExpensive; -private: +protected: /// isLegalRC - Return true if the value types that can be represented by the /// specified register class are all legal. bool isLegalRC(const TargetRegisterClass *RC) const; }; +//===----------------------------------------------------------------------===// +/// TargetLowering - This class defines information used to lower LLVM code to +/// legal SelectionDAG operators that the target instruction selector can accept +/// natively. +/// +/// This class also defines callbacks that targets must implement to lower +/// target-specific constructs to SelectionDAG operators. +/// +class TargetLowering : public TargetLoweringBase { + TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION; + void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION; + +public: + /// NOTE: The constructor takes ownership of TLOF. + explicit TargetLowering(const TargetMachine &TM, + const TargetLoweringObjectFile *TLOF); + + /// getPreIndexedAddressParts - returns true by value, base pointer and + /// offset pointer and addressing mode by reference if the node's address + /// can be legally represented as pre-indexed load / store address. + virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/, + SDValue &/*Offset*/, + ISD::MemIndexedMode &/*AM*/, + SelectionDAG &/*DAG*/) const { + return false; + } + + /// getPostIndexedAddressParts - returns true by value, base pointer and + /// offset pointer and addressing mode by reference if this node can be + /// combined with a load / store to form a post-indexed load / store. + virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, + SDValue &/*Base*/, SDValue &/*Offset*/, + ISD::MemIndexedMode &/*AM*/, + SelectionDAG &/*DAG*/) const { + return false; + } + + /// getJumpTableEncoding - Return the entry encoding for a jump table in the + /// current function. The returned value is a member of the + /// MachineJumpTableInfo::JTEntryKind enum. + virtual unsigned getJumpTableEncoding() const; + + virtual const MCExpr * + LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/, + const MachineBasicBlock * /*MBB*/, unsigned /*uid*/, + MCContext &/*Ctx*/) const { + llvm_unreachable("Need to implement this hook if target has custom JTIs"); + } + + /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC + /// jumptable. + virtual SDValue getPICJumpTableRelocBase(SDValue Table, + SelectionDAG &DAG) const; + + /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the + /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an + /// MCExpr. + virtual const MCExpr * + getPICJumpTableRelocBaseExpr(const MachineFunction *MF, + unsigned JTI, MCContext &Ctx) const; + + /// isOffsetFoldingLegal - Return true if folding a constant offset + /// with the given GlobalAddress is legal. It is frequently not legal in + /// PIC relocation models. + virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; + + bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, + SDValue &Chain) const; + + void softenSetCCOperands(SelectionDAG &DAG, EVT VT, + SDValue &NewLHS, SDValue &NewRHS, + ISD::CondCode &CCCode, DebugLoc DL) const; + + SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, + const SDValue *Ops, unsigned NumOps, + bool isSigned, DebugLoc dl) const; + + //===--------------------------------------------------------------------===// + // TargetLowering Optimization Methods + // + + /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two + /// SDValues for returning information from TargetLowering to its clients + /// that want to combine + struct TargetLoweringOpt { + SelectionDAG &DAG; + bool LegalTys; + bool LegalOps; + SDValue Old; + SDValue New; + + explicit TargetLoweringOpt(SelectionDAG &InDAG, + bool LT, bool LO) : + DAG(InDAG), LegalTys(LT), LegalOps(LO) {} + + bool LegalTypes() const { return LegalTys; } + bool LegalOperations() const { return LegalOps; } + + bool CombineTo(SDValue O, SDValue N) { + Old = O; + New = N; + return true; + } + + /// ShrinkDemandedConstant - Check to see if the specified operand of the + /// specified instruction is a constant integer. If so, check to see if + /// there are any bits set in the constant that are not demanded. If so, + /// shrink the constant and return true. + bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded); + + /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the + /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening + /// cast, but it could be generalized for targets with other types of + /// implicit widening casts. + bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, + DebugLoc dl); + }; + + /// SimplifyDemandedBits - Look at Op. At this point, we know that only the + /// DemandedMask bits of the result of Op are ever used downstream. If we can + /// use this information to simplify Op, create a new simplified DAG node and + /// return true, returning the original and new nodes in Old and New. + /// Otherwise, analyze the expression and return a mask of KnownOne and + /// KnownZero bits for the expression (used to simplify the caller). + /// The KnownZero/One bits may only be accurate for those bits in the + /// DemandedMask. + bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, + APInt &KnownZero, APInt &KnownOne, + TargetLoweringOpt &TLO, unsigned Depth = 0) const; + + /// computeMaskedBitsForTargetNode - Determine which of the bits specified in + /// Mask are known to be either zero or one and return them in the + /// KnownZero/KnownOne bitsets. + virtual void computeMaskedBitsForTargetNode(const SDValue Op, + APInt &KnownZero, + APInt &KnownOne, + const SelectionDAG &DAG, + unsigned Depth = 0) const; + + /// ComputeNumSignBitsForTargetNode - This method can be implemented by + /// targets that want to expose additional information about sign bits to the + /// DAG Combiner. + virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, + unsigned Depth = 0) const; + + struct DAGCombinerInfo { + void *DC; // The DAG Combiner object. + CombineLevel Level; + bool CalledByLegalizer; + public: + SelectionDAG &DAG; + + DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc) + : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {} + + bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; } + bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; } + bool isAfterLegalizeVectorOps() const { + return Level == AfterLegalizeDAG; + } + CombineLevel getDAGCombineLevel() { return Level; } + 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); + SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true); + + void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); + }; + + /// SimplifySetCC - Try to simplify a setcc built with the specified operands + /// and cc. If it is unable to simplify it, return a null SDValue. + SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, + ISD::CondCode Cond, bool foldBooleans, + DAGCombinerInfo &DCI, DebugLoc dl) const; + + /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the + /// node is a GlobalAddress + offset. + virtual bool + isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const; + + /// PerformDAGCombine - This method will be invoked for all target nodes and + /// for any target-independent nodes that the target has registered with + /// invoke it for. + /// + /// The semantics are as follows: + /// Return Value: + /// SDValue.Val == 0 - No change was made + /// SDValue.Val == N - N was replaced, is dead, and is already handled. + /// otherwise - N should be replaced by the returned Operand. + /// + /// In addition, methods provided by DAGCombinerInfo may be used to perform + /// more complex transformations. + /// + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + + /// isTypeDesirableForOp - Return true if the target has native support for + /// the specified value type and it is 'desirable' to use the type for the + /// given node type. e.g. On x86 i16 is legal, but undesirable since i16 + /// instruction encodings are longer and some i16 instructions are slow. + virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const { + // By default, assume all legal types are desirable. + return isTypeLegal(VT); + } + + /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner + /// to transform a floating point op of specified opcode to a equivalent op of + /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM. + virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/, + EVT /*VT*/) const { + return false; + } + + /// IsDesirableToPromoteOp - This method query the target whether it is + /// beneficial for dag combiner to promote the specified node. If true, it + /// should return the desired promotion type by reference. + virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const { + return false; + } + + //===--------------------------------------------------------------------===// + // Lowering methods - These methods must be implemented by targets so that + // the SelectionDAGBuilder code knows how to lower these. + // + + /// LowerFormalArguments - This hook must be implemented to lower the + /// incoming (formal) arguments, described by the Ins array, into the + /// specified DAG. The implementation should fill in the InVals array + /// with legal-type argument values, and return the resulting token + /// chain value. + /// + virtual SDValue + LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, + bool /*isVarArg*/, + const SmallVectorImpl<ISD::InputArg> &/*Ins*/, + DebugLoc /*dl*/, SelectionDAG &/*DAG*/, + SmallVectorImpl<SDValue> &/*InVals*/) const { + llvm_unreachable("Not Implemented"); + } + + struct ArgListEntry { + SDValue Node; + Type* Ty; + bool isSExt : 1; + bool isZExt : 1; + bool isInReg : 1; + bool isSRet : 1; + bool isNest : 1; + bool isByVal : 1; + uint16_t Alignment; + + ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), + isSRet(false), isNest(false), isByVal(false), Alignment(0) { } + }; + typedef std::vector<ArgListEntry> ArgListTy; + + /// CallLoweringInfo - This structure contains all information that is + /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the + /// SelectionDAG builder needs to lower a call, and targets will see this + /// struct in their LowerCall implementation. + struct CallLoweringInfo { + SDValue Chain; + Type *RetTy; + bool RetSExt : 1; + bool RetZExt : 1; + bool IsVarArg : 1; + bool IsInReg : 1; + bool DoesNotReturn : 1; + bool IsReturnValueUsed : 1; + + // IsTailCall should be modified by implementations of + // TargetLowering::LowerCall that perform tail call conversions. + bool IsTailCall; + + unsigned NumFixedArgs; + CallingConv::ID CallConv; + SDValue Callee; + ArgListTy &Args; + SelectionDAG &DAG; + DebugLoc DL; + ImmutableCallSite *CS; + SmallVector<ISD::OutputArg, 32> Outs; + SmallVector<SDValue, 32> OutVals; + SmallVector<ISD::InputArg, 32> Ins; + + + /// CallLoweringInfo - Constructs a call lowering context based on the + /// ImmutableCallSite \p cs. + CallLoweringInfo(SDValue chain, Type *retTy, + FunctionType *FTy, bool isTailCall, SDValue callee, + ArgListTy &args, SelectionDAG &dag, DebugLoc dl, + ImmutableCallSite &cs) + : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)), + RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()), + IsInReg(cs.paramHasAttr(0, Attribute::InReg)), + DoesNotReturn(cs.doesNotReturn()), + IsReturnValueUsed(!cs.getInstruction()->use_empty()), + IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()), + CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag), + DL(dl), CS(&cs) {} + + /// CallLoweringInfo - Constructs a call lowering context based on the + /// provided call information. + CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt, + bool isVarArg, bool isInReg, unsigned numFixedArgs, + CallingConv::ID callConv, bool isTailCall, + bool doesNotReturn, bool isReturnValueUsed, SDValue callee, + ArgListTy &args, SelectionDAG &dag, DebugLoc dl) + : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt), + IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn), + IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall), + NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee), + Args(args), DAG(dag), DL(dl), CS(NULL) {} + }; + + /// LowerCallTo - This function lowers an abstract call to a function into an + /// actual call. This returns a pair of operands. The first element is the + /// return value for the function (if RetTy is not VoidTy). The second + /// element is the outgoing token chain. It calls LowerCall to do the actual + /// lowering. + std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const; + + /// LowerCall - This hook must be implemented to lower calls into the + /// the specified DAG. The outgoing arguments to the call are described + /// by the Outs array, and the values to be returned by the call are + /// described by the Ins array. The implementation should fill in the + /// InVals array with legal-type return values from the call, and return + /// the resulting token chain value. + virtual SDValue + LowerCall(CallLoweringInfo &/*CLI*/, + SmallVectorImpl<SDValue> &/*InVals*/) const { + llvm_unreachable("Not Implemented"); + } + + /// HandleByVal - Target-specific cleanup for formal ByVal parameters. + virtual void HandleByVal(CCState *, unsigned &, 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. + /// + virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/, + MachineFunction &/*MF*/, bool /*isVarArg*/, + const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, + LLVMContext &/*Context*/) const + { + // Return true by default to get preexisting behavior. + return true; + } + + /// LowerReturn - This hook must be implemented to lower outgoing + /// return values, described by the Outs array, into the specified + /// DAG. The implementation should return the resulting token chain + /// value. + /// + virtual SDValue + LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, + bool /*isVarArg*/, + const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, + const SmallVectorImpl<SDValue> &/*OutVals*/, + DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { + llvm_unreachable("Not Implemented"); + } + + /// isUsedByReturnOnly - Return true if result of the specified node is used + /// by a return node only. It also compute and return the input chain for the + /// tail call. + /// This is used to determine whether it is possible + /// to codegen a libcall as tail call at legalization time. + virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const { + 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 *) 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 MVT getTypeForExtArgOrReturn(MVT VT, + ISD::NodeType /*ExtendKind*/) const { + MVT MinVT = getRegisterType(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. + /// The reason we can not do away with LowerOperation entirely is that + /// LegalizeDAG isn't yet ready to use this callback. + /// TODO: Consider merging with ReplaceNodeResults. + + /// The target places new result values for the node in Results (their number + /// and types must exactly match those of the original return values of + /// the node), or leaves Results empty, which indicates that the node is not + /// to be custom lowered after all. + /// The default implementation calls LowerOperation. + virtual void LowerOperationWrapper(SDNode *N, + SmallVectorImpl<SDValue> &Results, + SelectionDAG &DAG) const; + + /// LowerOperation - This callback is invoked for operations that are + /// unsupported by the target, which are registered to use 'custom' lowering, + /// and whose defined values are all legal. + /// If the target has no operations that require custom lowering, it need not + /// implement this. The default implementation of this aborts. + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; + + /// ReplaceNodeResults - This callback is invoked when a node result type is + /// illegal for the target, and the operation was registered to use 'custom' + /// lowering for that result type. The target places new result values for + /// the node in Results (their number and types must exactly match those of + /// the original return values of the node), or leaves Results empty, which + /// indicates that the node is not to be custom lowered after all. + /// + /// If the target has no operations that require custom lowering, it need not + /// implement this. The default implementation aborts. + virtual void ReplaceNodeResults(SDNode * /*N*/, + SmallVectorImpl<SDValue> &/*Results*/, + SelectionDAG &/*DAG*/) const { + llvm_unreachable("ReplaceNodeResults not implemented for this target!"); + } + + /// getTargetNodeName() - This method returns the name of a target specific + /// DAG node. + virtual const char *getTargetNodeName(unsigned Opcode) const; + + /// createFastISel - This method returns a target specific FastISel object, + /// or null if the target does not support "fast" ISel. + virtual FastISel *createFastISel(FunctionLoweringInfo &, + const TargetLibraryInfo *) const { + return 0; + } + + //===--------------------------------------------------------------------===// + // Inline Asm Support hooks + // + + /// ExpandInlineAsm - This hook allows the target to expand an inline asm + /// call to be explicit llvm code if it wants to. This is useful for + /// turning simple inline asms into LLVM intrinsics, which gives the + /// compiler more information about the behavior of the code. + virtual bool ExpandInlineAsm(CallInst *) const { + return false; + } + + enum ConstraintType { + C_Register, // Constraint represents specific register(s). + C_RegisterClass, // Constraint represents any of register(s) in class. + C_Memory, // Memory constraint. + C_Other, // Something else. + C_Unknown // Unsupported constraint. + }; + + enum ConstraintWeight { + // Generic weights. + CW_Invalid = -1, // No match. + CW_Okay = 0, // Acceptable. + CW_Good = 1, // Good weight. + CW_Better = 2, // Better weight. + CW_Best = 3, // Best weight. + + // Well-known weights. + CW_SpecificReg = CW_Okay, // Specific register operands. + CW_Register = CW_Good, // Register operands. + CW_Memory = CW_Better, // Memory operands. + CW_Constant = CW_Best, // Constant operand. + CW_Default = CW_Okay // Default or don't know type. + }; + + /// AsmOperandInfo - This contains information for each constraint that we are + /// lowering. + struct AsmOperandInfo : public InlineAsm::ConstraintInfo { + /// ConstraintCode - This contains the actual string for the code, like "m". + /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that + /// most closely matches the operand. + std::string ConstraintCode; + + /// ConstraintType - Information about the constraint code, e.g. Register, + /// RegisterClass, Memory, Other, Unknown. + TargetLowering::ConstraintType ConstraintType; + + /// CallOperandval - If this is the result output operand or a + /// clobber, this is null, otherwise it is the incoming operand to the + /// CallInst. This gets modified as the asm is processed. + Value *CallOperandVal; + + /// ConstraintVT - The ValueType for the operand value. + MVT ConstraintVT; + + /// isMatchingInputConstraint - Return true of this is an input operand that + /// is a matching constraint like "4". + bool isMatchingInputConstraint() const; + + /// getMatchedOperand - If this is an input matching constraint, this method + /// returns the output operand it matches. + unsigned getMatchedOperand() const; + + /// Copy constructor for copying from an AsmOperandInfo. + AsmOperandInfo(const AsmOperandInfo &info) + : InlineAsm::ConstraintInfo(info), + ConstraintCode(info.ConstraintCode), + ConstraintType(info.ConstraintType), + CallOperandVal(info.CallOperandVal), + ConstraintVT(info.ConstraintVT) { + } + + /// Copy constructor for copying from a ConstraintInfo. + AsmOperandInfo(const InlineAsm::ConstraintInfo &info) + : InlineAsm::ConstraintInfo(info), + ConstraintType(TargetLowering::C_Unknown), + CallOperandVal(0), ConstraintVT(MVT::Other) { + } + }; + + typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; + + /// ParseConstraints - Split up the constraint string from the inline + /// assembly value into the specific constraints and their prefixes, + /// and also tie in the associated operand values. + /// If this returns an empty vector, and if the constraint string itself + /// isn't empty, there was an error parsing. + virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const; + + /// Examine constraint type and operand type and determine a weight value. + /// The operand object must already have been set up with the operand type. + virtual ConstraintWeight getMultipleConstraintMatchWeight( + AsmOperandInfo &info, int maIndex) const; + + /// Examine constraint string and operand type and determine a weight value. + /// The operand object must already have been set up with the operand type. + virtual ConstraintWeight getSingleConstraintMatchWeight( + AsmOperandInfo &info, const char *constraint) const; + + /// ComputeConstraintToUse - Determines the constraint code and constraint + /// type to use for the specific AsmOperandInfo, setting + /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand + /// being passed in is available, it can be passed in as Op, otherwise an + /// empty SDValue can be passed. + virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, + SDValue Op, + SelectionDAG *DAG = 0) const; + + /// getConstraintType - Given a constraint, return the type of constraint it + /// is for this target. + virtual ConstraintType getConstraintType(const std::string &Constraint) const; + + /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. + /// {edx}), return the register number and the register class for the + /// register. + /// + /// Given a register class constraint, like 'r', if this corresponds directly + /// to an LLVM register class, return a register of 0 and the register class + /// pointer. + /// + /// This should only be used for C_Register constraints. On error, + /// this returns a register number of 0 and a null register class pointer.. + virtual std::pair<unsigned, const TargetRegisterClass*> + getRegForInlineAsmConstraint(const std::string &Constraint, + EVT VT) const; + + /// LowerXConstraint - try to replace an X constraint, which matches anything, + /// with another that has more specific requirements based on the type of the + /// corresponding operand. This returns null if there is no replacement to + /// make. + virtual const char *LowerXConstraint(EVT ConstraintVT) const; + + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, + std::vector<SDValue> &Ops, + SelectionDAG &DAG) const; + + //===--------------------------------------------------------------------===// + // Div utility functions + // + SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, + SelectionDAG &DAG) const; + SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, + std::vector<SDNode*> *Created) const; + SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, + std::vector<SDNode*> *Created) const; + + //===--------------------------------------------------------------------===// + // Instruction Emitting Hooks + // + + // EmitInstrWithCustomInserter - This method should be implemented by targets + // that mark instructions with the 'usesCustomInserter' flag. These + // instructions are special in various ways, which require special support to + // insert. The specified MachineInstr is created but not inserted into any + // basic blocks, and this method is called to expand it into a sequence of + // instructions, potentially also creating new basic blocks and control flow. + virtual MachineBasicBlock * + EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + + /// AdjustInstrPostInstrSelection - This method should be implemented by + /// targets that mark instructions with the 'hasPostISelHook' flag. These + /// instructions must be adjusted after instruction selection by target hooks. + /// e.g. To fill in optional defs for ARM 's' setting instructions. + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; +}; + /// GetReturnInfo - Given an LLVM IR type and return type attributes, /// compute the return value EVTs and flags, and optionally also /// the offsets, if the return value is being lowered to memory. -void GetReturnInfo(Type* ReturnType, Attributes attr, +void GetReturnInfo(Type* ReturnType, AttributeSet attr, SmallVectorImpl<ISD::OutputArg> &Outs, const TargetLowering &TLI); diff --git a/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h index 13a6fe3..9958755 100644 --- a/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -15,10 +15,10 @@ #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H -#include "llvm/Module.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/SectionKind.h" -#include "llvm/ADT/ArrayRef.h" namespace llvm { class MachineModuleInfo; @@ -27,6 +27,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSymbol; + class MCSymbolRefExpr; class MCStreamer; class GlobalValue; class TargetMachine; @@ -108,13 +109,13 @@ public: return 0; } - /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference + /// getTTypeGlobalReference - Return an MCExpr to use for a reference /// to the specified global variable from exception handling information. /// virtual const MCExpr * - getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const; + getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const; // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. virtual MCSymbol * @@ -123,8 +124,8 @@ public: /// const MCExpr * - getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, - MCStreamer &Streamer) const; + getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, + MCStreamer &Streamer) const; virtual const MCSection * getStaticCtorSection(unsigned Priority = 65535) const { diff --git a/contrib/llvm/include/llvm/Target/TargetMachine.h b/contrib/llvm/include/llvm/Target/TargetMachine.h index 5006647..66f3a3c 100644 --- a/contrib/llvm/include/llvm/Target/TargetMachine.h +++ b/contrib/llvm/include/llvm/Target/TargetMachine.h @@ -14,12 +14,10 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H +#include "llvm/ADT/StringRef.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/TargetTransformInfo.h" -#include "llvm/Target/TargetTransformImpl.h" -#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> @@ -43,6 +41,8 @@ class TargetPassConfig; class TargetRegisterInfo; class TargetSelectionDAGInfo; class TargetSubtargetInfo; +class ScalarTargetTransformInfo; +class VectorTargetTransformInfo; class formatted_raw_ostream; class raw_ostream; @@ -59,10 +59,6 @@ protected: // Can only create subclasses. TargetMachine(const Target &T, StringRef TargetTriple, StringRef CPU, StringRef FS, const TargetOptions &Options); - /// getSubtargetImpl - virtual method implemented by subclasses that returns - /// a reference to that target's TargetSubtargetInfo-derived member variable. - virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; } - /// TheTarget - The Target that this machine was created for. const Target &TheTarget; @@ -95,7 +91,14 @@ public: const StringRef getTargetCPU() const { return TargetCPU; } const StringRef getTargetFeatureString() const { return TargetFS; } - TargetOptions Options; + /// getSubtargetImpl - virtual method implemented by subclasses that returns + /// a reference to that target's TargetSubtargetInfo-derived member variable. + virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; } + + mutable TargetOptions Options; + + /// \brief Reset the target options based on the function's attributes. + void resetTargetOptions(const MachineFunction *MF) const; // Interfaces to the major aspects of target machine information: // -- Instruction opcode and operand information @@ -108,10 +111,6 @@ public: virtual const TargetLowering *getTargetLowering() const { return 0; } virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; } virtual const DataLayout *getDataLayout() const { return 0; } - virtual const ScalarTargetTransformInfo* - getScalarTargetTransformInfo() const { return 0; } - virtual const VectorTargetTransformInfo* - getVectorTargetTransformInfo() const { return 0; } /// getMCAsmInfo - Return target specific asm information. /// @@ -232,6 +231,9 @@ public: /// sections. static void setFunctionSections(bool); + /// \brief Register analysis passes for this target with a pass manager. + virtual void addAnalysisPasses(PassManagerBase &) {} + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit, and returned by /// it to indicate what type of file could actually be made. @@ -290,6 +292,11 @@ protected: // Can only create subclasses. CodeGenOpt::Level OL); public: + /// \brief Register analysis passes for this target with a pass manager. + /// + /// This registers target independent analysis passes. + virtual void addAnalysisPasses(PassManagerBase &PM); + /// createPassConfig - Create a pass configuration object to be used by /// addPassToEmitX methods for generating a pipeline of CodeGen passes. virtual TargetPassConfig *createPassConfig(PassManagerBase &PM); diff --git a/contrib/llvm/include/llvm/Target/TargetOptions.h b/contrib/llvm/include/llvm/Target/TargetOptions.h index 68ca567..c31db24 100644 --- a/contrib/llvm/include/llvm/Target/TargetOptions.h +++ b/contrib/llvm/include/llvm/Target/TargetOptions.h @@ -24,7 +24,7 @@ namespace llvm { // Possible float ABI settings. Used with FloatABIType in TargetOptions.h. namespace FloatABI { enum ABIType { - Default, // Target-specific (either soft or hard depending on triple, etc). + Default, // Target-specific (either soft or hard depending on triple,etc). Soft, // Soft float. Hard // Hard float. }; @@ -48,10 +48,10 @@ namespace llvm { UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false), JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false), DisableTailCalls(false), - StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false), - PositionIndependentExecutable(false), EnableSegmentedStacks(false), - UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default), - AllowFPOpFusion(FPOpFusion::Standard) + StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0), + EnableFastISel(false), PositionIndependentExecutable(false), + EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""), + FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -202,10 +202,10 @@ namespace llvm { /// Strict mode - allow fusion only if/when it can be proven that the excess /// precision won't effect the result. /// - /// Note: This option only controls formation of fused ops by the optimizers. - /// Fused operations that are explicitly specified (e.g. FMA via the - /// llvm.fma.* intrinsic) will always be honored, regardless of the value of - /// this option. + /// Note: This option only controls formation of fused ops by the + /// optimizers. Fused operations that are explicitly specified (e.g. FMA + /// via the llvm.fma.* intrinsic) will always be honored, regardless of + /// the value of this option. FPOpFusion::FPOpFusionMode AllowFPOpFusion; }; diff --git a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h index afa2ee2..6b1e70b 100644 --- a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -16,11 +16,11 @@ #ifndef LLVM_TARGET_TARGETREGISTERINFO_H #define LLVM_TARGET_TARGETREGISTERINFO_H -#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/CallingConv.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/MC/MCRegisterInfo.h" #include <cassert> #include <functional> @@ -30,12 +30,13 @@ class BitVector; class MachineFunction; class RegScavenger; template<class T> class SmallVectorImpl; +class VirtRegMap; class raw_ostream; class TargetRegisterClass { public: - typedef const uint16_t* iterator; - typedef const uint16_t* const_iterator; + typedef const MCPhysReg* iterator; + typedef const MCPhysReg* const_iterator; typedef const MVT::SimpleValueType* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; @@ -45,7 +46,7 @@ public: const uint32_t *SubClassMask; const uint16_t *SuperRegIndices; const sc_iterator SuperClasses; - ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&); + ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&); /// getID() - Return the register class ID number. /// @@ -190,7 +191,7 @@ public: /// /// By default, this method returns all registers in the class. /// - ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const { + ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const { return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs()); } }; @@ -387,27 +388,12 @@ public: return false; } - /// isSubRegister - Returns true if regB is a sub-register of regA. - /// - bool isSubRegister(unsigned regA, unsigned regB) const { - return isSuperRegister(regB, regA); - } - - /// isSuperRegister - Returns true if regB is a super-register of regA. - /// - bool isSuperRegister(unsigned RegA, unsigned RegB) const { - for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) - if (*I == RegB) - return true; - return false; - } - /// getCalleeSavedRegs - Return a null-terminated list of all of the /// callee saved registers on this target. The register should be in the /// order of desired callee-save stack frame offset. The first register is /// closest to the incoming stack pointer if stack grows down, and vice versa. /// - virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0) + virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0) const = 0; /// getCallPreservedMask - Return a mask of call-preserved registers for the @@ -594,10 +580,13 @@ public: return 0; } -// Get the weight in units of pressure for this register class. + /// Get the weight in units of pressure for this register class. virtual const RegClassWeight &getRegClassWeight( const TargetRegisterClass *RC) const = 0; + /// Get the weight in units of pressure for this register unit. + virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0; + /// Get the number of dimensions of register pressure. virtual unsigned getNumRegPressureSets() const = 0; @@ -613,27 +602,29 @@ public: virtual const int *getRegClassPressureSets( const TargetRegisterClass *RC) const = 0; - /// getRawAllocationOrder - Returns the register allocation order for a - /// specified register class with a target-dependent hint. The returned list - /// may contain reserved registers that cannot be allocated. - /// - /// Register allocators need only call this function to resolve - /// target-dependent hints, but it should work without hinting as well. - virtual ArrayRef<uint16_t> - getRawAllocationOrder(const TargetRegisterClass *RC, - unsigned HintType, unsigned HintReg, - const MachineFunction &MF) const { - return RC->getRawAllocationOrder(MF); - } - - /// ResolveRegAllocHint - Resolves the specified register allocation hint - /// to a physical register. Returns the physical register if it is successful. - virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, - const MachineFunction &MF) const { - if (Type == 0 && Reg && isPhysicalRegister(Reg)) - return Reg; - return 0; - } + /// Get the dimensions of register pressure impacted by this register unit. + /// Returns a -1 terminated array of pressure set IDs. + virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0; + + /// Get a list of 'hint' registers that the register allocator should try + /// first when allocating a physical register for the virtual register + /// VirtReg. These registers are effectively moved to the front of the + /// allocation order. + /// + /// The Order argument is the allocation order for VirtReg's register class + /// as returned from RegisterClassInfo::getOrder(). The hint registers must + /// come from Order, and they must not be reserved. + /// + /// The default implementation of this function can resolve + /// target-independent hints provided to MRI::setRegAllocationHint with + /// HintType == 0. Targets that override this function should defer to the + /// default implementation if they have no reason to change the allocation + /// order for VirtReg. There may be target-independent hints. + virtual void getRegAllocationHints(unsigned VirtReg, + ArrayRef<MCPhysReg> Order, + SmallVectorImpl<MCPhysReg> &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM = 0) const; /// avoidWriteAfterWrite - Return true if the register allocator should avoid /// writing a register from RC in two consecutive instructions. @@ -742,21 +733,6 @@ public: llvm_unreachable("isFrameOffsetLegal does not exist on this target"); } - /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog - /// code insertion to eliminate call frame setup and destroy pseudo - /// instructions (but only if the Target is using them). It is responsible - /// for eliminating these instructions, replacing them with concrete - /// instructions. This method need only be implemented if using call frame - /// setup/destroy pseudo instructions. - /// - virtual void - eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI) const { - llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " - "target!"); - } - /// saveScavengerRegister - Spill the register so it can be used by the /// register scavenger. Return true if the register was spilled, false @@ -776,10 +752,11 @@ public: /// referenced by the iterator contains an MO_FrameIndex operand which must be /// eliminated by this method. This method may modify or replace the /// specified instruction, as long as it keeps the iterator pointing at the - /// finished product. SPAdj is the SP adjustment due to call frame setup - /// instruction. + /// finished product. SPAdj is the SP adjustment due to call frame setup + /// instruction. FIOperandNum is the FI operand number. virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, - int SPAdj, RegScavenger *RS=NULL) const = 0; + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS = NULL) const = 0; //===--------------------------------------------------------------------===// /// Debug information queries. @@ -876,7 +853,8 @@ class PrintReg { unsigned Reg; unsigned SubIdx; public: - PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0) + explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, + unsigned subidx = 0) : TRI(tri), Reg(reg), SubIdx(subidx) {} void print(raw_ostream&) const; }; diff --git a/contrib/llvm/include/llvm/Target/TargetSchedule.td b/contrib/llvm/include/llvm/Target/TargetSchedule.td index 0da82fd..660d2c4 100644 --- a/contrib/llvm/include/llvm/Target/TargetSchedule.td +++ b/contrib/llvm/include/llvm/Target/TargetSchedule.td @@ -76,6 +76,7 @@ class SchedMachineModel { int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. int MinLatency = -1; // Determines which instrucions are allowed in a group. // (-1) inorder (0) ooo, (1): inorder +var latencies. + int ILPWindow = -1; // Cycles of latency likely hidden by hardware buffers. int LoadLatency = -1; // Cycles for loads to access the cache. int HighLatency = -1; // Approximation of cycles for "high latency" ops. int MispredictPenalty = -1; // Extra cycles for a mispredicted branch. @@ -132,6 +133,11 @@ def EponymousProcResourceKind : ProcResourceKind; class ProcResource<int num> : ProcResourceKind, ProcResourceUnits<EponymousProcResourceKind, num>; +class ProcResGroup<list<ProcResource> resources> : ProcResourceKind { + list<ProcResource> Resources = resources; + SchedMachineModel SchedModel = ?; +} + // A target architecture may define SchedReadWrite types and associate // them with instruction operands. class SchedReadWrite; diff --git a/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h index 6db96d9..b2d405d 100644 --- a/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h @@ -19,6 +19,7 @@ namespace llvm { +class MachineFunction; class MachineInstr; class SDep; class SUnit; @@ -54,6 +55,13 @@ public: return 0; } + /// \brief True if the subtarget should run MachineScheduler after aggressive + /// coalescing. + /// + /// This currently replaces the SelectionDAG scheduler with the "source" order + /// scheduler. It does not yet disable the postRA scheduler. + virtual bool enableMachineScheduler() const; + // enablePostRAScheduler - If the target can benefit from post-regalloc // scheduling and the specified optimization level meets the requirement // return true to enable post-register-allocation scheduling. In @@ -66,6 +74,9 @@ public: // the latency of a schedule dependency. virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep& dep) const { } + + /// \brief Reset the features for the subtarget. + virtual void resetSubtargetFeatures(const MachineFunction *MF) { } }; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/Target/TargetTransformImpl.h b/contrib/llvm/include/llvm/Target/TargetTransformImpl.h deleted file mode 100644 index 7ea2396..0000000 --- a/contrib/llvm/include/llvm/Target/TargetTransformImpl.h +++ /dev/null @@ -1,98 +0,0 @@ -//=- llvm/Target/TargetTransformImpl.h - Target Loop Trans Info----*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the target-specific implementations of the -// TargetTransform interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H -#define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H - -#include "llvm/TargetTransformInfo.h" -#include "llvm/CodeGen/ValueTypes.h" - -namespace llvm { - -class TargetLowering; - -/// ScalarTargetTransformInfo - This is a default implementation for the -/// ScalarTargetTransformInfo interface. Different targets can implement -/// this interface differently. -class ScalarTargetTransformImpl : public ScalarTargetTransformInfo { -private: - const TargetLowering *TLI; - -public: - /// Ctor - explicit ScalarTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} - - virtual bool isLegalAddImmediate(int64_t imm) const; - - virtual bool isLegalICmpImmediate(int64_t imm) const; - - virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; - - virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; - - virtual bool isTypeLegal(Type *Ty) const; - - virtual unsigned getJumpBufAlignment() const; - - virtual unsigned getJumpBufSize() const; - - virtual bool shouldBuildLookupTables() const; -}; - -class VectorTargetTransformImpl : public VectorTargetTransformInfo { -protected: - const TargetLowering *TLI; - - /// Estimate the cost of type-legalization and the legalized type. - std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; - - /// Estimate the overhead of scalarizing an instruction. Insert and Extract - /// are set if the result needs to be inserted and/or extracted from vectors. - unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; - - // Get the ISD node that corresponds to the Instruction class opcode. - int InstructionOpcodeToISD(unsigned Opcode) const; - -public: - explicit VectorTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} - - virtual ~VectorTargetTransformImpl() {} - - virtual unsigned getInstrCost(unsigned Opcode, Type *Ty1, Type *Ty2) const; - - virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const; - - virtual unsigned getBroadcastCost(Type *Tp) const; - - virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const; - - virtual unsigned getCFInstrCost(unsigned Opcode) const; - - virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy) const; - - virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index) const; - - virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const; - - virtual unsigned getNumberOfParts(Type *Tp) const; -}; - -} // end llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/TargetTransformInfo.h b/contrib/llvm/include/llvm/TargetTransformInfo.h deleted file mode 100644 index 94db490..0000000 --- a/contrib/llvm/include/llvm/TargetTransformInfo.h +++ /dev/null @@ -1,204 +0,0 @@ -//===- llvm/Transforms/TargetTransformInfo.h --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass exposes codegen information to IR-level passes. Every -// transformation that uses codegen information is broken into three parts: -// 1. The IR-level analysis pass. -// 2. The IR-level transformation interface which provides the needed -// information. -// 3. Codegen-level implementation which uses target-specific hooks. -// -// This file defines #2, which is the interface that IR-level transformations -// use for querying the codegen. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE -#define LLVM_TRANSFORMS_TARGET_TRANSFORM_INTERFACE - -#include "llvm/Pass.h" -#include "llvm/AddressingMode.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Type.h" - -namespace llvm { - -class ScalarTargetTransformInfo; -class VectorTargetTransformInfo; - -/// TargetTransformInfo - This pass provides access to the codegen -/// interfaces that are needed for IR-level transformations. -class TargetTransformInfo : public ImmutablePass { -private: - const ScalarTargetTransformInfo *STTI; - const VectorTargetTransformInfo *VTTI; -public: - /// Default ctor. - /// - /// @note This has to exist, because this is a pass, but it should never be - /// used. - TargetTransformInfo(); - - TargetTransformInfo(const ScalarTargetTransformInfo* S, - const VectorTargetTransformInfo *V) - : ImmutablePass(ID), STTI(S), VTTI(V) { - initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry()); - } - - TargetTransformInfo(const TargetTransformInfo &T) : - ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { } - - const ScalarTargetTransformInfo* getScalarTargetTransformInfo() const { - return STTI; - } - const VectorTargetTransformInfo* getVectorTargetTransformInfo() const { - return VTTI; - } - - /// Pass identification, replacement for typeid. - static char ID; -}; - -// ---------------------------------------------------------------------------// -// The classes below are inherited and implemented by target-specific classes -// in the codegen. -// ---------------------------------------------------------------------------// - -/// ScalarTargetTransformInfo - This interface is used by IR-level passes -/// that need target-dependent information for generic scalar transformations. -/// LSR, and LowerInvoke use this interface. -class ScalarTargetTransformInfo { -public: - virtual ~ScalarTargetTransformInfo() {} - - /// isLegalAddImmediate - Return true if the specified immediate is legal - /// add immediate, that is the target has add instructions which can add - /// a register with the immediate without having to materialize the - /// immediate into a register. - virtual bool isLegalAddImmediate(int64_t) const { - return false; - } - /// isLegalICmpImmediate - Return true if the specified immediate is legal - /// icmp immediate, that is the target has icmp instructions which can compare - /// a register against the immediate without having to materialize the - /// immediate into a register. - virtual bool isLegalICmpImmediate(int64_t) const { - return false; - } - /// isLegalAddressingMode - Return true if the addressing mode represented by - /// AM is legal for this target, for a load/store of the specified type. - /// The type may be VoidTy, in which case only return true if the addressing - /// mode is legal for a load/store of any legal type. - /// TODO: Handle pre/postinc as well. - virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const { - return false; - } - /// isTruncateFree - Return true if it's free to truncate a value of - /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in - /// register EAX to i16 by referencing its sub-register AX. - virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const { - return false; - } - /// Is this type legal. - virtual bool isTypeLegal(Type *Ty) const { - return false; - } - /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes - virtual unsigned getJumpBufAlignment() const { - return 0; - } - /// getJumpBufSize - returns the target's jmp_buf size in bytes. - virtual unsigned getJumpBufSize() const { - return 0; - } - /// shouldBuildLookupTables - Return true if switches should be turned into - /// lookup tables for the target. - virtual bool shouldBuildLookupTables() const { - return true; - } -}; - -/// VectorTargetTransformInfo - This interface is used by the vectorizers -/// to estimate the profitability of vectorization for different instructions. -class VectorTargetTransformInfo { -public: - virtual ~VectorTargetTransformInfo() {} - - /// Returns the expected cost of the instruction opcode. The opcode is one of - /// the enums like Instruction::Add. The type arguments are the type of the - /// operation. - /// Most instructions only use the first type and in that case the second - /// operand is ignored. - /// - /// Exceptions: - /// * Br instructions do not use any of the types. - /// * Select instructions pass the return type as Ty1 and the selector as Ty2. - /// * Cast instructions pass the destination as Ty1 and the source as Ty2. - /// * Insert/Extract element pass only the vector type as Ty1. - /// * ShuffleVector, Load, Store do not use this call. - virtual unsigned getInstrCost(unsigned Opcode, - Type *Ty1 = 0, - Type *Ty2 = 0) const { - return 1; - } - - /// Returns the expected cost of arithmetic ops, such as mul, xor, fsub, etc. - virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { - return 1; - } - - /// Returns the cost of a vector broadcast of a scalar at place zero to a - /// vector of type 'Tp'. - virtual unsigned getBroadcastCost(Type *Tp) const { - return 1; - } - - /// Returns the expected cost of cast instructions, such as bitcast, trunc, - /// zext, etc. - virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const { - return 1; - } - - /// Returns the expected cost of control-flow related instrutctions such as - /// Phi, Ret, Br. - virtual unsigned getCFInstrCost(unsigned Opcode) const { - return 1; - } - - /// Returns the expected cost of compare and select instructions. - virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy = 0) const { - return 1; - } - - /// Returns the expected cost of vector Insert and Extract. - /// Use -1 to indicate that there is no information on the index value. - virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index = -1) const { - return 1; - } - - /// Returns the cost of Load and Store instructions. - virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const { - return 1; - } - - /// Returns the number of pieces into which the provided type must be - /// split during legalization. Zero is returned when the answer is unknown. - virtual unsigned getNumberOfParts(Type *Tp) const { - return 0; - } -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/Transforms/IPO.h b/contrib/llvm/include/llvm/Transforms/IPO.h index fc1cd59..e6eb8d3 100644 --- a/contrib/llvm/include/llvm/Transforms/IPO.h +++ b/contrib/llvm/include/llvm/Transforms/IPO.h @@ -15,7 +15,7 @@ #ifndef LLVM_TRANSFORMS_IPO_H #define LLVM_TRANSFORMS_IPO_H -#include <vector> +#include "llvm/ADT/ArrayRef.h" namespace llvm { @@ -109,7 +109,7 @@ Pass *createPruneEHPass(); /// /// Note that commandline options that are used with the above function are not /// used now! -ModulePass *createInternalizePass(const std::vector<const char *> &exportList); +ModulePass *createInternalizePass(ArrayRef<const char *> exportList); /// createInternalizePass - Same as above, but with an empty exportList. ModulePass *createInternalizePass(); diff --git a/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h b/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h index b036040..43a0ac8 100644 --- a/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h +++ b/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h @@ -17,7 +17,7 @@ #ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H #define LLVM_TRANSFORMS_IPO_INLINERPASS_H -#include "llvm/CallGraphSCCPass.h" +#include "llvm/Analysis/CallGraphSCCPass.h" namespace llvm { class CallSite; @@ -42,6 +42,7 @@ struct Inliner : public CallGraphSCCPass { // Pass class. virtual bool runOnSCC(CallGraphSCC &SCC); + using llvm::Pass::doFinalization; // doFinalization - Remove now-dead linkonce functions at the end of // processing to avoid breaking the SCC traversal. virtual bool doFinalization(CallGraph &CG); diff --git a/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h index 3ea0a42..209f68d 100644 --- a/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H -#define LLVM_SUPPORT_PASSMANAGERBUILDER_H +#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H +#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H #include <vector> diff --git a/contrib/llvm/include/llvm/Transforms/Instrumentation.h b/contrib/llvm/include/llvm/Transforms/Instrumentation.h index 8e63aaa..4aae200 100644 --- a/contrib/llvm/include/llvm/Transforms/Instrumentation.h +++ b/contrib/llvm/include/llvm/Transforms/Instrumentation.h @@ -14,6 +14,8 @@ #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H #define LLVM_TRANSFORMS_INSTRUMENTATION_H +#include "llvm/ADT/StringRef.h" + namespace llvm { class ModulePass; @@ -29,21 +31,52 @@ ModulePass *createOptimalEdgeProfilerPass(); ModulePass *createPathProfilerPass(); // Insert GCOV profiling instrumentation -ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, - bool Use402Format = false, - bool UseExtraChecksum = false); +struct GCOVOptions { + static GCOVOptions getDefault(); + + // Specify whether to emit .gcno files. + bool EmitNotes; + + // Specify whether to modify the program to emit .gcda files when run. + bool EmitData; + + // A four-byte version string. The meaning of a version string is described in + // gcc's gcov-io.h + char Version[4]; + + // Emit a "cfg checksum" that follows the "line number checksum" of a + // function. This affects both .gcno and .gcda files. + bool UseCfgChecksum; + + // Add the 'noredzone' attribute to added runtime library calls. + bool NoRedZone; + + // Emit the name of the function in the .gcda files. This is redundant, as + // the function identifier can be used to find the name from the .gcno file. + bool FunctionNamesInData; +}; +ModulePass *createGCOVProfilerPass(const GCOVOptions &Options = + GCOVOptions::getDefault()); // Insert AddressSanitizer (address sanity checking) instrumentation -FunctionPass *createAddressSanitizerPass(); -// Insert ThreadSanitizer (race detection) instrumentation -FunctionPass *createThreadSanitizerPass(); +FunctionPass *createAddressSanitizerFunctionPass( + bool CheckInitOrder = true, bool CheckUseAfterReturn = false, + bool CheckLifetime = false, StringRef BlacklistFile = StringRef(), + bool ZeroBaseShadow = false); +ModulePass *createAddressSanitizerModulePass( + bool CheckInitOrder = true, StringRef BlacklistFile = StringRef(), + bool ZeroBaseShadow = false); +// Insert MemorySanitizer instrumentation (detection of uninitialized reads) +FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false, + StringRef BlacklistFile = StringRef()); + +// Insert ThreadSanitizer (race detection) instrumentation +FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef()); // BoundsChecking - This pass instruments the code to perform run-time bounds // checking on loads, stores, and other memory intrinsics. -// Penalty is the maximum run-time that is acceptable for the user. -// -FunctionPass *createBoundsCheckingPass(unsigned Penalty = 5); +FunctionPass *createBoundsCheckingPass(); } // End llvm namespace diff --git a/contrib/llvm/include/llvm/Transforms/ObjCARC.h b/contrib/llvm/include/llvm/Transforms/ObjCARC.h new file mode 100644 index 0000000..b3c19c0 --- /dev/null +++ b/contrib/llvm/include/llvm/Transforms/ObjCARC.h @@ -0,0 +1,49 @@ +//===-- ObjCARC.h - ObjCARC Scalar Transformations --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header file defines prototypes for accessor functions that expose passes +// in the ObjCARC Scalar Transformations library. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_OBJCARC_H +#define LLVM_TRANSFORMS_OBJCARC_H + +namespace llvm { + +class Pass; + +//===----------------------------------------------------------------------===// +// +// ObjCARCAPElim - ObjC ARC autorelease pool elimination. +// +Pass *createObjCARCAPElimPass(); + +//===----------------------------------------------------------------------===// +// +// ObjCARCExpand - ObjC ARC preliminary simplifications. +// +Pass *createObjCARCExpandPass(); + +//===----------------------------------------------------------------------===// +// +// ObjCARCContract - Late ObjC ARC cleanups. +// +Pass *createObjCARCContractPass(); + +//===----------------------------------------------------------------------===// +// +// ObjCARCOpt - ObjC ARC optimization. +// +Pass *createObjCARCOptPass(); + +} // End llvm namespace + +#endif + diff --git a/contrib/llvm/include/llvm/Transforms/Scalar.h b/contrib/llvm/include/llvm/Transforms/Scalar.h index a5d8eed..e833aaa 100644 --- a/contrib/llvm/include/llvm/Transforms/Scalar.h +++ b/contrib/llvm/include/llvm/Transforms/Scalar.h @@ -115,11 +115,9 @@ Pass *createLICMPass(); //===----------------------------------------------------------------------===// // // LoopStrengthReduce - This pass is strength reduces GEP instructions that use -// a loop's canonical induction variable as one of their indices. It takes an -// optional parameter used to consult the target machine whether certain -// transformations are profitable. +// a loop's canonical induction variable as one of their indices. // -Pass *createLoopStrengthReducePass(const TargetLowering *TLI = 0); +Pass *createLoopStrengthReducePass(); Pass *createGlobalMergePass(const TargetLowering *TLI = 0); @@ -336,30 +334,6 @@ Pass *createCorrelatedValuePropagationPass(); //===----------------------------------------------------------------------===// // -// ObjCARCAPElim - ObjC ARC autorelease pool elimination. -// -Pass *createObjCARCAPElimPass(); - -//===----------------------------------------------------------------------===// -// -// ObjCARCExpand - ObjC ARC preliminary simplifications. -// -Pass *createObjCARCExpandPass(); - -//===----------------------------------------------------------------------===// -// -// ObjCARCContract - Late ObjC ARC cleanups. -// -Pass *createObjCARCContractPass(); - -//===----------------------------------------------------------------------===// -// -// ObjCARCOpt - ObjC ARC optimization. -// -Pass *createObjCARCOptPass(); - -//===----------------------------------------------------------------------===// -// // InstructionSimplifier - Remove redundant instructions. // FunctionPass *createInstructionSimplifierPass(); @@ -368,7 +342,7 @@ extern char &InstructionSimplifierID; //===----------------------------------------------------------------------===// // -// LowerExpectIntriniscs - Removes llvm.expect intrinsics and creates +// LowerExpectIntrinsics - Removes llvm.expect intrinsics and creates // "block_weights" metadata. FunctionPass *createLowerExpectIntrinsicPass(); diff --git a/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h b/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h deleted file mode 100644 index 7d67283..0000000 --- a/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h +++ /dev/null @@ -1,109 +0,0 @@ -//===- AddrModeMatcher.h - Addressing mode matching facility ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// AddressingModeMatcher - This class exposes a single public method, which is -// used to construct a "maximal munch" of the addressing mode for the target -// specified by TLI for an access to "V" with an access type of AccessTy. This -// returns the addressing mode that is actually matched by value, but also -// returns the list of instructions involved in that addressing computation in -// AddrModeInsts. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H -#define LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H - -#include "llvm/AddressingMode.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Target/TargetLowering.h" - -namespace llvm { - -class GlobalValue; -class Instruction; -class Value; -class Type; -class User; -class raw_ostream; - -/// ExtAddrMode - This is an extended version of TargetLowering::AddrMode -/// which holds actual Value*'s for register values. -struct ExtAddrMode : public AddrMode { - Value *BaseReg; - Value *ScaledReg; - ExtAddrMode() : BaseReg(0), ScaledReg(0) {} - void print(raw_ostream &OS) const; - void dump() const; - - bool operator==(const ExtAddrMode& O) const { - return (BaseReg == O.BaseReg) && (ScaledReg == O.ScaledReg) && - (BaseGV == O.BaseGV) && (BaseOffs == O.BaseOffs) && - (HasBaseReg == O.HasBaseReg) && (Scale == O.Scale); - } -}; - -static inline raw_ostream &operator<<(raw_ostream &OS, const ExtAddrMode &AM) { - AM.print(OS); - return OS; -} - -class AddressingModeMatcher { - SmallVectorImpl<Instruction*> &AddrModeInsts; - const TargetLowering &TLI; - - /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and - /// the memory instruction that we're computing this address for. - Type *AccessTy; - Instruction *MemoryInst; - - /// AddrMode - This is the addressing mode that we're building up. This is - /// part of the return value of this addressing mode matching stuff. - ExtAddrMode &AddrMode; - - /// IgnoreProfitability - This is set to true when we should not do - /// profitability checks. When true, IsProfitableToFoldIntoAddressingMode - /// always returns true. - bool IgnoreProfitability; - - AddressingModeMatcher(SmallVectorImpl<Instruction*> &AMI, - const TargetLowering &T, Type *AT, - Instruction *MI, ExtAddrMode &AM) - : AddrModeInsts(AMI), TLI(T), AccessTy(AT), MemoryInst(MI), AddrMode(AM) { - IgnoreProfitability = false; - } -public: - - /// Match - Find the maximal addressing mode that a load/store of V can fold, - /// give an access type of AccessTy. This returns a list of involved - /// instructions in AddrModeInsts. - static ExtAddrMode Match(Value *V, Type *AccessTy, - Instruction *MemoryInst, - SmallVectorImpl<Instruction*> &AddrModeInsts, - const TargetLowering &TLI) { - ExtAddrMode Result; - - bool Success = - AddressingModeMatcher(AddrModeInsts, TLI, AccessTy, - MemoryInst, Result).MatchAddr(V, 0); - (void)Success; assert(Success && "Couldn't select *anything*?"); - return Result; - } -private: - bool MatchScaledValue(Value *ScaleReg, int64_t Scale, unsigned Depth); - bool MatchAddr(Value *V, unsigned Depth); - bool MatchOperationAddr(User *Operation, unsigned Opcode, unsigned Depth); - bool IsProfitableToFoldIntoAddressingMode(Instruction *I, - ExtAddrMode &AMBefore, - ExtAddrMode &AMAfter); - bool ValueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2); -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index b810f1a..8f1a6e2 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -12,14 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCK_H -#define LLVM_TRANSFORMS_UTILS_BASICBLOCK_H +#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H +#define LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H // FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock -#include "llvm/BasicBlock.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/DebugLoc.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BlackList.h b/contrib/llvm/include/llvm/Transforms/Utils/BlackList.h new file mode 100644 index 0000000..f19470e --- /dev/null +++ b/contrib/llvm/include/llvm/Transforms/Utils/BlackList.h @@ -0,0 +1,58 @@ +//===-- BlackList.h - blacklist for sanitizers ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +//===----------------------------------------------------------------------===// +// +// This is a utility class for instrumentation passes (like AddressSanitizer +// or ThreadSanitizer) to avoid instrumenting some functions or global +// variables based on a user-supplied blacklist. +// +// The blacklist disables instrumentation of various functions and global +// variables. Each line contains a prefix, followed by a wild card expression. +// Empty lines and lines starting with "#" are ignored. +// --- +// # Blacklisted items: +// fun:*_ZN4base6subtle* +// global:*global_with_bad_access_or_initialization* +// global-init:*global_with_initialization_issues* +// global-init-type:*Namespace::ClassName* +// src:file_with_tricky_code.cc +// --- +// Note that the wild card is in fact an llvm::Regex, but * is automatically +// replaced with .* +// This is similar to the "ignore" feature of ThreadSanitizer. +// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores +// +//===----------------------------------------------------------------------===// +// + +#include "llvm/ADT/StringMap.h" + +namespace llvm { +class Function; +class GlobalVariable; +class Module; +class Regex; +class StringRef; + +class BlackList { + public: + BlackList(const StringRef Path); + // Returns whether either this function or it's source file are blacklisted. + bool isIn(const Function &F) const; + // Returns whether either this global or it's source file are blacklisted. + bool isIn(const GlobalVariable &G) const; + // Returns whether this module is blacklisted by filename. + bool isIn(const Module &M) const; + // Returns whether a global should be excluded from initialization checking. + bool isInInit(const GlobalVariable &G) const; + private: + StringMap<Regex*> Entries; + + bool inSection(const StringRef Section, const StringRef Query) const; +}; + +} // namespace llvm diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h index ab9fc47..181ed07 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -12,10 +12,10 @@ // //===----------------------------------------------------------------------===// -#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H -#define TRANSFORMS_UTILS_BUILDLIBCALLS_H +#ifndef LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H +#define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H -#include "llvm/IRBuilder.h" +#include "llvm/IR/IRBuilder.h" namespace llvm { class Value; @@ -81,7 +81,7 @@ namespace llvm { /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' /// suffix. Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, - const AttrListPtr &Attrs); + const AttributeSet &Attrs); /// EmitPutChar - Emit a call to the putchar function. This assumes that Char /// is an integer. diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BypassSlowDivision.h b/contrib/llvm/include/llvm/Transforms/Utils/BypassSlowDivision.h index ac8af12..0d081c0 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/BypassSlowDivision.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/BypassSlowDivision.h @@ -15,10 +15,11 @@ // //===----------------------------------------------------------------------===// -#ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H -#define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H +#ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H +#define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H -#include "llvm/Function.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/Function.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h index 1780025..14212f6 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -18,9 +18,9 @@ #ifndef LLVM_TRANSFORMS_UTILS_CLONING_H #define LLVM_TRANSFORMS_UTILS_CLONING_H -#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/ValueMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Transforms/Utils/ValueMapper.h" diff --git a/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h index 7ad7bdd..488d7a5 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h @@ -15,7 +15,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H #define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H -#include "llvm/InstrTypes.h" +#include "llvm/IR/InstrTypes.h" namespace llvm { class ICmpInst; diff --git a/contrib/llvm/include/llvm/Transforms/Utils/IntegerDivision.h b/contrib/llvm/include/llvm/Transforms/Utils/IntegerDivision.h index cecc807..27d3c58 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/IntegerDivision.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/IntegerDivision.h @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef TRANSFORMS_UTILS_INTEGERDIVISION_H -#define TRANSFORMS_UTILS_INTEGERDIVISION_H +#ifndef LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H +#define LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H namespace llvm { class BinaryOperator; @@ -43,6 +43,20 @@ namespace llvm { /// @brief Replace Div with generated code. bool expandDivision(BinaryOperator* Div); + /// Generate code to calculate the remainder of two integers, replacing Rem + /// with the generated code. Uses the above 32bit routine, therefore adequate + /// for targets with little or no support for less than 32 bit arithmetic. + /// + /// @brief Replace Rem with generated code. + bool expandRemainderUpTo32Bits(BinaryOperator *Rem); + + /// Generate code to divide two integers, replacing Div with the generated + /// code. Uses the above 32bit routine, therefore adequate for targets with + /// little or no support for less than 32 bit arithmetic. + /// + /// @brief Replace Rem with generated code. + bool expandDivisionUpTo32Bits(BinaryOperator *Div); + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Local.h b/contrib/llvm/include/llvm/Transforms/Utils/Local.h index be3029e..687c9d5 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/Local.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/Local.h @@ -15,10 +15,10 @@ #ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H #define LLVM_TRANSFORMS_UTILS_LOCAL_H -#include "llvm/IRBuilder.h" -#include "llvm/Operator.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/DataLayout.h" namespace llvm { @@ -135,8 +135,8 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB); /// of the CFG. It returns true if a modification was made, possibly deleting /// the basic block that was pointed to. /// -bool SimplifyCFG(BasicBlock *BB, const DataLayout *TD = 0, - const TargetTransformInfo *TTI = 0); +bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, + const DataLayout *TD = 0); /// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch, /// and if a predecessor branches to us and one of our successors, fold the @@ -252,6 +252,16 @@ bool LowerDbgDeclare(Function &F); /// an alloca, if any. DbgDeclareInst *FindAllocaDbgDeclare(Value *V); +/// replaceDbgDeclareForAlloca - Replaces llvm.dbg.declare instruction when +/// alloca is replaced with a new value. +bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, + DIBuilder &Builder); + +/// \brief Remove all blocks that can not be reached from the function's entry. +/// +/// Returns true if any basic block was removed. +bool removeUnreachableBlocks(Function &F); + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h index 2c0ec9b..bb7fc06 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H -#define LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H +#ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H +#define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H namespace llvm { @@ -30,4 +30,4 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority); } // End llvm namespace -#endif // LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H +#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H diff --git a/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h index 0bb6ec6..52a6157 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef TRANSFORMS_UTILS_PROMOTEMEMTOREG_H -#define TRANSFORMS_UTILS_PROMOTEMEMTOREG_H +#ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H +#define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H #include <vector> diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h index db65a47..cd04893 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h @@ -15,6 +15,7 @@ #define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" namespace llvm { class BasicBlock; diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h index fde452b..6bb81be 100644 --- a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -31,7 +31,8 @@ namespace llvm { /// simplifier. LibCallSimplifierImpl *Impl; public: - LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); + LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI, + bool UnsafeFPShrink); virtual ~LibCallSimplifier(); /// optimizeCall - Take the given call instruction and return a more diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize.h b/contrib/llvm/include/llvm/Transforms/Vectorize.h index 41e53a8..d205dbd 100644 --- a/contrib/llvm/include/llvm/Transforms/Vectorize.h +++ b/contrib/llvm/include/llvm/Transforms/Vectorize.h @@ -18,6 +18,7 @@ namespace llvm { class BasicBlock; class BasicBlockPass; +class Pass; //===----------------------------------------------------------------------===// /// @brief Vectorize configuration. @@ -83,6 +84,9 @@ struct VectorizeConfig { /// @brief The maximum number of pairable instructions per group. unsigned MaxInsts; + /// @brief The maximum number of candidate instruction pairs per group. + unsigned MaxPairs; + /// @brief The maximum number of pairing iterations. unsigned MaxIter; @@ -110,7 +114,7 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); // // LoopVectorize - Create a loop vectorization pass. // -Pass * createLoopVectorizePass(); +Pass *createLoopVectorizePass(); //===----------------------------------------------------------------------===// /// @brief Vectorize the BasicBlock. |