diff options
Diffstat (limited to 'include')
120 files changed, 3172 insertions, 1624 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index d57c250..063ab91 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -78,8 +78,9 @@ typedef struct LLVMOpaqueValue *LLVMValueRef; typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; typedef struct LLVMOpaqueBuilder *LLVMBuilderRef; -/* Used to provide a module to JIT or interpreter. - * See the llvm::ModuleProvider class. +/* Interface used to provide a module to JIT or interpreter. This is now just a + * synonym for llvm::Module, but we have to keep using the different type to + * keep binary compatibility. */ typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef; @@ -117,63 +118,76 @@ typedef enum { LLVMNoCaptureAttribute = 1<<21, LLVMNoRedZoneAttribute = 1<<22, LLVMNoImplicitFloatAttribute = 1<<23, - LLVMNakedAttribute = 1<<24 + LLVMNakedAttribute = 1<<24, + LLVMInlineHintAttribute = 1<<25 } LLVMAttribute; typedef enum { + /* Terminator Instructions */ LLVMRet = 1, LLVMBr = 2, LLVMSwitch = 3, - LLVMInvoke = 4, - LLVMUnwind = 5, - LLVMUnreachable = 6, - LLVMAdd = 7, - LLVMFAdd = 8, - LLVMSub = 9, - LLVMFSub = 10, - LLVMMul = 11, - LLVMFMul = 12, - LLVMUDiv = 13, - LLVMSDiv = 14, - LLVMFDiv = 15, - LLVMURem = 16, - LLVMSRem = 17, - LLVMFRem = 18, - LLVMShl = 19, - LLVMLShr = 20, - LLVMAShr = 21, - LLVMAnd = 22, - LLVMOr = 23, - LLVMXor = 24, - LLVMMalloc = 25, - LLVMFree = 26, - LLVMAlloca = 27, - LLVMLoad = 28, - LLVMStore = 29, - LLVMGetElementPtr = 30, - LLVMTrunk = 31, - LLVMZExt = 32, - LLVMSExt = 33, - LLVMFPToUI = 34, - LLVMFPToSI = 35, - LLVMUIToFP = 36, - LLVMSIToFP = 37, - LLVMFPTrunc = 38, - LLVMFPExt = 39, - LLVMPtrToInt = 40, - LLVMIntToPtr = 41, - LLVMBitCast = 42, - LLVMICmp = 43, - LLVMFCmp = 44, - LLVMPHI = 45, - LLVMCall = 46, - LLVMSelect = 47, - LLVMVAArg = 50, - LLVMExtractElement = 51, - LLVMInsertElement = 52, - LLVMShuffleVector = 53, - LLVMExtractValue = 54, - LLVMInsertValue = 55 + LLVMIndirectBr = 4, + LLVMInvoke = 5, + LLVMUnwind = 6, + LLVMUnreachable = 7, + + /* Standard Binary Operators */ + LLVMAdd = 8, + LLVMFAdd = 9, + LLVMSub = 10, + LLVMFSub = 11, + LLVMMul = 12, + LLVMFMul = 13, + LLVMUDiv = 14, + LLVMSDiv = 15, + LLVMFDiv = 16, + LLVMURem = 17, + LLVMSRem = 18, + LLVMFRem = 19, + + /* Logical Operators */ + LLVMShl = 20, + LLVMLShr = 21, + LLVMAShr = 22, + LLVMAnd = 23, + LLVMOr = 24, + LLVMXor = 25, + + /* Memory Operators */ + LLVMAlloca = 26, + LLVMLoad = 27, + LLVMStore = 28, + LLVMGetElementPtr = 29, + + /* Cast Operators */ + LLVMTrunc = 30, + LLVMZExt = 31, + LLVMSExt = 32, + LLVMFPToUI = 33, + LLVMFPToSI = 34, + LLVMUIToFP = 35, + LLVMSIToFP = 36, + LLVMFPTrunc = 37, + LLVMFPExt = 38, + LLVMPtrToInt = 39, + LLVMIntToPtr = 40, + LLVMBitCast = 41, + + /* Other Operators */ + LLVMICmp = 42, + LLVMFCmp = 43, + LLVMPHI = 44, + LLVMCall = 45, + LLVMSelect = 46, + /* UserOp1 */ + /* UserOp2 */ + LLVMVAArg = 49, + LLVMExtractElement = 50, + LLVMInsertElement = 51, + LLVMShuffleVector = 52, + LLVMExtractValue = 53, + LLVMInsertValue = 54 } LLVMOpcode; typedef enum { @@ -191,7 +205,8 @@ typedef enum { LLVMPointerTypeKind, /**< Pointers */ LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ - LLVMMetadataTypeKind /**< Metadata */ + LLVMMetadataTypeKind, /**< Metadata */ + LLVMUnionTypeKind /**< Unions */ } LLVMTypeKind; typedef enum { @@ -210,8 +225,7 @@ typedef enum { LLVMDLLImportLinkage, /**< Function to be imported from DLL */ LLVMDLLExportLinkage, /**< Function to be accessible from DLL */ LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */ - LLVMGhostLinkage, /**< Stand-in functions for streaming fns from - bitcode */ + LLVMGhostLinkage, /**< Obsolete */ LLVMCommonLinkage, /**< Tentative definitions */ LLVMLinkerPrivateLinkage /**< Like Private, but linker removes. */ } LLVMLinkage; @@ -371,6 +385,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); +/* Operations on union types */ +LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, + unsigned ElementCount); +LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount); +unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy); +void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest); + /* Operations on array, pointer, and vector types (sequence types) */ LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); @@ -914,17 +935,15 @@ LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS, /*===-- Module providers --------------------------------------------------===*/ -/* Encapsulates the module M in a module provider, taking ownership of the - * module. - * See the constructor llvm::ExistingModuleProvider::ExistingModuleProvider. +/* Changes the type of M so it can be passed to FunctionPassManagers and the + * JIT. They take ModuleProviders for historical reasons. */ LLVMModuleProviderRef LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M); -/* Destroys the module provider MP as well as the contained module. - * See the destructor llvm::ModuleProvider::~ModuleProvider. +/* Destroys the module M. */ -void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP); +void LLVMDisposeModuleProvider(LLVMModuleProviderRef M); /*===-- Memory buffers ----------------------------------------------------===*/ @@ -981,7 +1000,6 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM); } namespace llvm { - class ModuleProvider; class MemoryBuffer; class PassManagerBase; @@ -1018,11 +1036,16 @@ namespace llvm { DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef ) - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ModuleProvider, LLVMModuleProviderRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef ) DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef ) + /* LLVMModuleProviderRef exists for historical reasons, but now just holds a + * Module. + */ + inline Module *unwrap(LLVMModuleProviderRef MP) { + return reinterpret_cast<Module*>(MP); + } #undef DEFINE_STDCXX_CONVERSION_FUNCTIONS #undef DEFINE_ISA_CONVERSION_FUNCTIONS diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h new file mode 100644 index 0000000..9cd1e1f --- /dev/null +++ b/include/llvm-c/EnhancedDisassembly.h @@ -0,0 +1,515 @@ +/*===-- 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/System/DataTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + @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. + */ +typedef enum { +/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */ + kEDAssemblySyntaxX86Intel = 0, +/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */ + kEDAssemblySyntaxX86ATT = 1 +} EDAssemblySyntax_t; + +/*! + @typedef EDDisassemblerRef + Encapsulates a disassembler for a single CPU architecture. + */ +struct EDDisassembler; +typedef struct EDDisassembler *EDDisassemblerRef; + +/*! + @typedef EDInstRef + Encapsulates a single disassembled instruction in one assembly syntax. + */ +struct EDInst; +typedef struct EDInst *EDInstRef; + +/*! + @typedef EDTokenRef + Encapsulates a token from the disassembly of an instruction. + */ +struct EDToken; +typedef struct EDToken *EDTokenRef; + +/*! + @typedef EDOperandRef + Encapsulates an operand of an instruction. + */ +struct EDOperand; +typedef struct EDOperand *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/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 45108c8..b9f2d83 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -307,15 +307,17 @@ public: } BitVector &operator|=(const BitVector &RHS) { - assert(Size == RHS.Size && "Illegal operation!"); - for (unsigned i = 0; i < NumBitWords(size()); ++i) + if (size() < RHS.size()) + resize(RHS.size()); + for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) Bits[i] |= RHS.Bits[i]; return *this; } BitVector &operator^=(const BitVector &RHS) { - assert(Size == RHS.Size && "Illegal operation!"); - for (unsigned i = 0; i < NumBitWords(size()); ++i) + if (size() < RHS.size()) + resize(RHS.size()); + for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i) Bits[i] ^= RHS.Bits[i]; return *this; } diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 8b161ea..7350906 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -359,7 +359,7 @@ private: BucketT *OldBuckets = Buckets; // Double the number of buckets. - while (NumBuckets <= AtLeast) + while (NumBuckets < AtLeast) NumBuckets <<= 1; NumTombstones = 0; Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets)); diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index 89f55ca..0898b96 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -41,8 +41,8 @@ public: return TheMap.count(V); } - void erase(const ValueT &V) { - TheMap.erase(V); + bool erase(const ValueT &V) { + return TheMap.erase(V); } DenseSet &operator=(const DenseSet &RHS) { diff --git a/include/llvm/ADT/ImmutableIntervalMap.h b/include/llvm/ADT/ImmutableIntervalMap.h new file mode 100644 index 0000000..f33fb1e --- /dev/null +++ b/include/llvm/ADT/ImmutableIntervalMap.h @@ -0,0 +1,238 @@ +//===--- ImmutableIntervalMap.h - Immutable (functional) 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 defines the ImmutableIntervalMap class. +// +//===----------------------------------------------------------------------===// +#include "llvm/ADT/ImmutableMap.h" + +namespace llvm { + +class Interval { +private: + uint64_t Start; + uint64_t End; + +public: + Interval(uint64_t S, uint64_t E) : Start(S), End(E) {} + + uint64_t getStart() const { return Start; } + uint64_t getEnd() const { return End; } +}; + +template <typename T> +struct ImutIntervalInfo { + typedef const std::pair<Interval, T> value_type; + typedef const value_type &value_type_ref; + typedef const Interval key_type; + typedef const Interval &key_type_ref; + typedef const T data_type; + typedef const T &data_type_ref; + + static key_type_ref KeyOfValue(value_type_ref V) { + return V.first; + } + + static data_type_ref DataOfValue(value_type_ref V) { + return V.second; + } + + static bool isEqual(key_type_ref L, key_type_ref R) { + return L.getStart() == R.getStart() && L.getEnd() == R.getEnd(); + } + + static bool isDataEqual(data_type_ref L, data_type_ref R) { + return ImutContainerInfo<T>::isEqual(L,R); + } + + static bool isLess(key_type_ref L, key_type_ref R) { + // Assume L and R does not overlap. + if (L.getStart() < R.getStart()) { + assert(L.getEnd() < R.getStart()); + return true; + } else if (L.getStart() == R.getStart()) { + assert(L.getEnd() == R.getEnd()); + return false; + } else { + assert(L.getStart() > R.getEnd()); + return false; + } + } + + static bool isContainedIn(key_type_ref K, key_type_ref L) { + if (K.getStart() >= L.getStart() && K.getEnd() <= L.getEnd()) + return true; + else + return false; + } + + static void Profile(FoldingSetNodeID &ID, value_type_ref V) { + ID.AddInteger(V.first.getStart()); + ID.AddInteger(V.first.getEnd()); + ImutProfileInfo<T>::Profile(ID, V.second); + } +}; + +template <typename ImutInfo> +class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> { + typedef ImutAVLTree<ImutInfo> TreeTy; + typedef typename ImutInfo::value_type value_type; + typedef typename ImutInfo::value_type_ref value_type_ref; + typedef typename ImutInfo::key_type key_type; + typedef typename ImutInfo::key_type_ref key_type_ref; + typedef typename ImutInfo::data_type data_type; + typedef typename ImutInfo::data_type_ref data_type_ref; + +public: + ImutIntervalAVLFactory(BumpPtrAllocator &Alloc) + : ImutAVLFactory<ImutInfo>(Alloc) {} + + TreeTy *Add(TreeTy *T, value_type_ref V) { + T = Add_internal(V,T); + this->MarkImmutable(T); + return T; + } + + TreeTy *Find(TreeTy *T, key_type_ref K) { + if (!T) + return NULL; + + key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->Value(T)); + + if (ImutInfo::isContainedIn(K, CurrentKey)) + return T; + else if (ImutInfo::isLess(K, CurrentKey)) + return Find(this->Left(T), K); + else + return Find(this->Right(T), K); + } + +private: + TreeTy *Add_internal(value_type_ref V, TreeTy *T) { + key_type_ref K = ImutInfo::KeyOfValue(V); + T = RemoveAllOverlaps(T, K); + if (this->isEmpty(T)) + return this->CreateNode(NULL, V, NULL); + + assert(!T->isMutable()); + + key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T)); + + if (ImutInfo::isLess(K, KCurrent)) + return this->Balance(Add_internal(V, this->Left(T)), this->Value(T), this->Right(T)); + else + return this->Balance(this->Left(T), this->Value(T), Add_internal(V, this->Right(T))); + } + + // Remove all overlaps from T. + TreeTy *RemoveAllOverlaps(TreeTy *T, key_type_ref K) { + bool Changed; + do { + Changed = false; + T = RemoveOverlap(T, K, Changed); + this->MarkImmutable(T); + } while (Changed); + + return T; + } + + // Remove one overlap from T. + TreeTy *RemoveOverlap(TreeTy *T, key_type_ref K, bool &Changed) { + if (!T) + return NULL; + Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T)); + + // If current key does not overlap the inserted key. + if (CurrentK.getStart() > K.getEnd()) + return this->Balance(RemoveOverlap(this->Left(T), K, Changed), this->Value(T), this->Right(T)); + else if (CurrentK.getEnd() < K.getStart()) + return this->Balance(this->Left(T), this->Value(T), RemoveOverlap(this->Right(T), K, Changed)); + + // Current key overlaps with the inserted key. + // Remove the current key. + Changed = true; + data_type_ref OldData = ImutInfo::DataOfValue(this->Value(T)); + T = this->Remove_internal(CurrentK, T); + // Add back the unoverlapped part of the current key. + if (CurrentK.getStart() < K.getStart()) { + if (CurrentK.getEnd() <= K.getEnd()) { + Interval NewK(CurrentK.getStart(), K.getStart()-1); + return Add_internal(std::make_pair(NewK, OldData), T); + } else { + Interval NewK1(CurrentK.getStart(), K.getStart()-1); + T = Add_internal(std::make_pair(NewK1, OldData), T); + + Interval NewK2(K.getEnd()+1, CurrentK.getEnd()); + return Add_internal(std::make_pair(NewK2, OldData), T); + } + } else { + if (CurrentK.getEnd() > K.getEnd()) { + Interval NewK(K.getEnd()+1, CurrentK.getEnd()); + return Add_internal(std::make_pair(NewK, OldData), T); + } else + return T; + } + } +}; + +/// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals +/// in the map are guaranteed to be disjoint. +template <typename ValT> +class ImmutableIntervalMap + : public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > { + + typedef typename ImutIntervalInfo<ValT>::value_type value_type; + typedef typename ImutIntervalInfo<ValT>::value_type_ref value_type_ref; + typedef typename ImutIntervalInfo<ValT>::key_type key_type; + typedef typename ImutIntervalInfo<ValT>::key_type_ref key_type_ref; + typedef typename ImutIntervalInfo<ValT>::data_type data_type; + typedef typename ImutIntervalInfo<ValT>::data_type_ref data_type_ref; + typedef ImutAVLTree<ImutIntervalInfo<ValT> > TreeTy; + +public: + explicit ImmutableIntervalMap(TreeTy *R) + : ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> >(R) {} + + class Factory { + ImutIntervalAVLFactory<ImutIntervalInfo<ValT> > F; + + public: + Factory(BumpPtrAllocator& Alloc) : F(Alloc) {} + + ImmutableIntervalMap GetEmptyMap() { + return ImmutableIntervalMap(F.GetEmptyTree()); + } + + ImmutableIntervalMap Add(ImmutableIntervalMap Old, + key_type_ref K, data_type_ref D) { + TreeTy *T = F.Add(Old.Root, std::make_pair<key_type, data_type>(K, D)); + return ImmutableIntervalMap(F.GetCanonicalTree(T)); + } + + ImmutableIntervalMap Remove(ImmutableIntervalMap Old, key_type_ref K) { + TreeTy *T = F.Remove(Old.Root, K); + return ImmutableIntervalMap(F.GetCanonicalTree(T)); + } + + data_type *Lookup(ImmutableIntervalMap M, key_type_ref K) { + TreeTy *T = F.Find(M.getRoot(), K); + if (T) + return &T->getValue().second; + else + return 0; + } + }; + +private: + // For ImmutableIntervalMap, the lookup operation has to be done by the + // factory. + data_type* lookup(key_type_ref K) const; +}; + +} // end namespace llvm diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index 1b3f1a9..8af128e 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -68,7 +68,7 @@ public: typedef typename ValInfo::data_type_ref data_type_ref; typedef ImutAVLTree<ValInfo> TreeTy; -private: +protected: TreeTy* Root; public: @@ -106,13 +106,10 @@ public: void operator=(const Factory& RHS); // DO NOT IMPLEMENT }; - friend class Factory; - bool contains(key_type_ref K) const { return Root ? Root->contains(K) : false; } - bool operator==(ImmutableMap RHS) const { return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index ac06a40..65e70e2 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -27,6 +27,7 @@ namespace llvm { //===----------------------------------------------------------------------===// template <typename ImutInfo> class ImutAVLFactory; +template <typename ImutInfo> class ImutIntervalAVLFactory; template <typename ImutInfo> class ImutAVLTreeInOrderIterator; template <typename ImutInfo> class ImutAVLTreeGenericIterator; @@ -39,6 +40,7 @@ public: typedef ImutAVLFactory<ImutInfo> Factory; friend class ImutAVLFactory<ImutInfo>; + friend class ImutIntervalAVLFactory<ImutInfo>; friend class ImutAVLTreeGenericIterator<ImutInfo>; friend class FoldingSet<ImutAVLTree>; @@ -389,7 +391,7 @@ public: // These have succinct names so that the balancing code // is as terse (and readable) as possible. //===--------------------------------------------------===// -private: +protected: bool isEmpty(TreeTy* T) const { return !T; } unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; } @@ -581,25 +583,14 @@ public: continue; // We found a collision. Perform a comparison of Contents('T') - // with Contents('L')+'V'+Contents('R'). + // with Contents('TNew') typename TreeTy::iterator TI = T->begin(), TE = T->end(); - // First compare Contents('L') with the (initial) contents of T. - if (!CompareTreeWithSection(TNew->getLeft(), TI, TE)) - continue; - - // Now compare the new data element. - if (TI == TE || !TI->ElementEqual(TNew->getValue())) - continue; - - ++TI; - - // Now compare the remainder of 'T' with 'R'. - if (!CompareTreeWithSection(TNew->getRight(), TI, TE)) + if (!CompareTreeWithSection(TNew, TI, TE)) continue; if (TI != TE) - continue; // Contents('R') did not match suffix of 'T'. + continue; // T has more contents than TNew. // Trees did match! Return 'T'. return T; diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 346fb1c..5c774b9 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -310,11 +310,47 @@ public: } // Intersection, union, disjoint union. - BitVector &operator&=(const SmallBitVector &RHS); // TODO: implement + SmallBitVector &operator&=(const SmallBitVector &RHS) { + resize(std::max(size(), RHS.size())); + if (isSmall()) + setSmallBits(getSmallBits() & RHS.getSmallBits()); + else if (!RHS.isSmall()) + X.getPointer()->operator&=(*RHS.X.getPointer()); + else { + SmallBitVector Copy = RHS; + Copy.resize(size()); + X.getPointer()->operator&=(*Copy.X.getPointer()); + } + return *this; + } - BitVector &operator|=(const SmallBitVector &RHS); // TODO: implement + SmallBitVector &operator|=(const SmallBitVector &RHS) { + resize(std::max(size(), RHS.size())); + if (isSmall()) + setSmallBits(getSmallBits() | RHS.getSmallBits()); + else if (!RHS.isSmall()) + X.getPointer()->operator|=(*RHS.X.getPointer()); + else { + SmallBitVector Copy = RHS; + Copy.resize(size()); + X.getPointer()->operator|=(*Copy.X.getPointer()); + } + return *this; + } - BitVector &operator^=(const SmallBitVector &RHS); // TODO: implement + SmallBitVector &operator^=(const SmallBitVector &RHS) { + resize(std::max(size(), RHS.size())); + if (isSmall()) + setSmallBits(getSmallBits() ^ RHS.getSmallBits()); + else if (!RHS.isSmall()) + X.getPointer()->operator^=(*RHS.X.getPointer()); + else { + SmallBitVector Copy = RHS; + Copy.resize(size()); + X.getPointer()->operator^=(*Copy.X.getPointer()); + } + return *this; + } // Assignment operator. const SmallBitVector &operator=(const SmallBitVector &RHS) { diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index c29fc9f..ef08125 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -225,7 +225,7 @@ struct NextPowerOfTwo { }; -/// SmallPtrSet - This class implements a set which is optimizer for holding +/// SmallPtrSet - This class implements a set which is optimized for holding /// SmallSize or less elements. This internally rounds up SmallSize to the next /// power of two if it is not already a power of two. See the comments above /// SmallPtrSetImpl for details of the algorithm. diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index fe39324..8798b0e 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -66,6 +66,7 @@ public: ppc, // PPC: powerpc ppc64, // PPC64: powerpc64, ppu sparc, // Sparc: sparc + sparcv9, // Sparcv9: Sparcv9 systemz, // SystemZ: s390x tce, // TCE (http://tce.cs.tut.fi/): tce thumb, // Thumb: thumb, thumbv.* diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index 06951c7..e2675eb 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -37,7 +37,7 @@ Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0); /// ConstantFoldConstantExpression - Attempt to fold the constant expression /// using the specified TargetData. If successful, the constant result is /// result is returned, if not, null is returned. -Constant *ConstantFoldConstantExpression(ConstantExpr *CE, +Constant *ConstantFoldConstantExpression(const ConstantExpr *CE, const TargetData *TD = 0); /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 150d3ee..ccf0105 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -193,7 +193,9 @@ namespace llvm { FlagFwdDecl = 1 << 2, FlagAppleBlock = 1 << 3, FlagBlockByrefStruct = 1 << 4, - FlagVirtual = 1 << 5 + FlagVirtual = 1 << 5, + FlagArtificial = 1 << 6 // To identify artificial arguments in + // a subroutine type. e.g. "this" in c++. }; protected: @@ -241,6 +243,9 @@ namespace llvm { bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; } + bool isArtificial() const { + return (getFlags() & FlagArtificial) != 0; + } /// dump - print type. void dump() const; @@ -298,6 +303,9 @@ namespace llvm { DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } unsigned getRunTimeLang() const { return getUnsignedField(11); } + DICompositeType getContainingType() const { + return getFieldAs<DICompositeType>(12); + } /// Verify - Verify that a composite type descriptor is well formed. bool Verify() const; @@ -372,6 +380,7 @@ namespace llvm { DICompositeType getContainingType() const { return getFieldAs<DICompositeType>(13); } + unsigned isArtificial() const { return getUnsignedField(14); } StringRef getFilename() const { return getCompileUnit().getFilename();} StringRef getDirectory() const { return getCompileUnit().getDirectory();} @@ -567,7 +576,11 @@ namespace llvm { uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, - unsigned RunTimeLang = 0); + unsigned RunTimeLang = 0, + MDNode *ContainingType = 0); + + /// CreateArtificialType - Create a new DIType with "artificial" flag set. + DIType CreateArtificialType(DIType Ty); /// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context, @@ -591,7 +604,8 @@ namespace llvm { bool isDefinition, unsigned VK = 0, unsigned VIndex = 0, - DIType = DIType()); + DIType = DIType(), + bool isArtificial = 0); /// CreateSubprogramDefinition - Create new subprogram descriptor for the /// given declaration. diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 50f7d45..e6e9c71 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -16,29 +16,27 @@ #define LLVM_ANALYSIS_IVUSERS_H #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/ADT/SmallVector.h" -#include <map> +#include "llvm/Support/ValueHandle.h" namespace llvm { class DominatorTree; class Instruction; class Value; -struct IVUsersOfOneStride; - -/// IVStrideUse - Keep track of one use of a strided induction variable, where -/// the stride is stored externally. The Offset member keeps track of the -/// offset from the IV, User is the actual user of the operand, and -/// 'OperandValToReplace' is the operand of the User that is the use. +class IVUsers; +class ScalarEvolution; +class SCEV; + +/// IVStrideUse - Keep track of one use of a strided induction variable. +/// The Expr member keeps track of the expression, User is the actual user +/// instruction of the operand, and 'OperandValToReplace' is the operand of +/// the User that is the use. class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { public: - IVStrideUse(IVUsersOfOneStride *parent, - const SCEV *offset, + IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off, Instruction* U, Value *O) - : CallbackVH(U), Parent(parent), Offset(offset), - OperandValToReplace(O), - IsUseOfPostIncrementedValue(false) { + : CallbackVH(U), Parent(P), Stride(S), Offset(Off), + OperandValToReplace(O), IsUseOfPostIncrementedValue(false) { } /// getUser - Return the user instruction for this use. @@ -51,9 +49,17 @@ public: setValPtr(NewUser); } - /// getParent - Return a pointer to the IVUsersOfOneStride that owns + /// getParent - Return a pointer to the IVUsers that owns /// this IVStrideUse. - IVUsersOfOneStride *getParent() const { return Parent; } + IVUsers *getParent() const { return Parent; } + + /// getStride - Return the expression for the stride for the use. + const SCEV *getStride() const { return Stride; } + + /// setStride - Assign a new stride to this use. + void setStride(const SCEV *Val) { + Stride = Val; + } /// getOffset - Return the offset to add to a theoeretical induction /// variable that starts at zero and counts up by the stride to compute @@ -92,8 +98,11 @@ public: } private: - /// Parent - a pointer to the IVUsersOfOneStride that owns this IVStrideUse. - IVUsersOfOneStride *Parent; + /// Parent - a pointer to the IVUsers that owns this IVStrideUse. + IVUsers *Parent; + + /// Stride - The stride for this use. + const SCEV *Stride; /// Offset - The offset to add to the base induction expression. const SCEV *Offset; @@ -138,37 +147,8 @@ private: mutable ilist_node<IVStrideUse> Sentinel; }; -/// IVUsersOfOneStride - This structure keeps track of all instructions that -/// have an operand that is based on the trip count multiplied by some stride. -struct IVUsersOfOneStride : public ilist_node<IVUsersOfOneStride> { -private: - IVUsersOfOneStride(const IVUsersOfOneStride &I); // do not implement - void operator=(const IVUsersOfOneStride &I); // do not implement - -public: - IVUsersOfOneStride() : Stride(0) {} - - explicit IVUsersOfOneStride(const SCEV *stride) : Stride(stride) {} - - /// Stride - The stride for all the contained IVStrideUses. This is - /// a constant for affine strides. - const SCEV *Stride; - - /// Users - Keep track of all of the users of this stride as well as the - /// initial value and the operand that uses the IV. - ilist<IVStrideUse> Users; - - void addUser(const SCEV *Offset, Instruction *User, Value *Operand) { - Users.push_back(new IVStrideUse(this, Offset, User, Operand)); - } - - void removeUser(IVStrideUse *User) { - Users.erase(User); - } -}; - class IVUsers : public LoopPass { - friend class IVStrideUserVH; + friend class IVStrideUse; Loop *L; LoopInfo *LI; DominatorTree *DT; @@ -177,19 +157,8 @@ class IVUsers : public LoopPass { /// IVUses - A list of all tracked IV uses of induction variable expressions /// we are interested in. - ilist<IVUsersOfOneStride> IVUses; - -public: - /// IVUsesByStride - A mapping from the strides in StrideOrder to the - /// uses in IVUses. - std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride; + ilist<IVStrideUse> IVUses; - /// StrideOrder - An ordering of the keys in IVUsesByStride that is stable: - /// We use this to iterate over the IVUsesByStride collection without being - /// dependent on random ordering of pointers in the process. - SmallVector<const SCEV *, 16> StrideOrder; - -private: virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnLoop(Loop *L, LPPassManager &LPM); @@ -205,8 +174,8 @@ public: /// return true. Otherwise, return false. bool AddUsersIfInteresting(Instruction *I); - void AddUser(const SCEV *Stride, const SCEV *Offset, - Instruction *User, Value *Operand); + IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset, + Instruction *User, Value *Operand); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. @@ -217,6 +186,14 @@ public: /// isUseOfPostIncrementedValue flag. const SCEV *getCanonicalExpr(const IVStrideUse &U) const; + typedef ilist<IVStrideUse>::iterator iterator; + typedef ilist<IVStrideUse>::const_iterator const_iterator; + iterator begin() { return IVUses.begin(); } + iterator end() { return IVUses.end(); } + const_iterator begin() const { return IVUses.begin(); } + const_iterator end() const { return IVUses.end(); } + bool empty() const { return IVUses.empty(); } + void print(raw_ostream &OS, const Module* = 0) const; /// dump - This method is used for debugging. diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 7ce49d7..84acd7d 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -34,7 +34,7 @@ namespace llvm { /// NeverInline - True if this callee should never be inlined into a /// caller. bool NeverInline; - + /// usesDynamicAlloca - True if this function calls alloca (in the C sense). bool usesDynamicAlloca; @@ -42,17 +42,20 @@ namespace llvm { /// is used to estimate the code size cost of inlining it. unsigned NumInsts, NumBlocks; + /// NumCalls - Keep track of the number of calls to 'big' functions. + unsigned NumCalls; + /// NumVectorInsts - Keep track of how many instructions produce vector /// values. The inliner is being more aggressive with inlining vector /// kernels. unsigned NumVectorInsts; - + /// NumRets - Keep track of how many Ret instructions the block contains. unsigned NumRets; CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0), - NumBlocks(0), NumVectorInsts(0), NumRets(0) {} - + NumBlocks(0), NumCalls(0), NumVectorInsts(0), NumRets(0) {} + /// analyzeBasicBlock - Add information about the specified basic block /// to the current structure. void analyzeBasicBlock(const BasicBlock *BB); @@ -64,7 +67,9 @@ namespace llvm { namespace InlineConstants { // Various magic constants used to adjust heuristics. - const int CallPenalty = 5; + const int InstrCost = 5; + const int IndirectCallBonus = 500; + const int CallPenalty = 25; const int LastCallToStaticBonus = -15000; const int ColdccPenalty = 2000; const int NoreturnPenalty = 10000; @@ -119,18 +124,18 @@ namespace llvm { return getCost(); } }; - + /// InlineCostAnalyzer - Cost analyzer used by inliner. class InlineCostAnalyzer { struct ArgInfo { public: unsigned ConstantWeight; unsigned AllocaWeight; - + ArgInfo(unsigned CWeight, unsigned AWeight) : ConstantWeight(CWeight), AllocaWeight(AWeight) {} }; - + struct FunctionInfo { CodeMetrics Metrics; @@ -139,12 +144,12 @@ namespace llvm { /// would reduce the code size. If so, we add some value to the argument /// entry here. std::vector<ArgInfo> ArgumentWeights; - + /// CountCodeReductionForConstant - Figure out an approximation for how /// many instructions will be constant folded if the specified value is /// constant. unsigned CountCodeReductionForConstant(Value *V); - + /// CountCodeReductionForAlloca - Figure out an approximation of how much /// smaller the function will be if it is inlined into a context where an /// argument becomes an alloca. diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 33bf0b0..d5e4d51 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -553,6 +553,10 @@ public: /// normal unsigned value, if possible. Returns 0 if the trip count is unknown /// of not constant. Will also return 0 if the trip count is very large /// (>= 2^32) + /// + /// The IndVarSimplify pass transforms loops to have a form that this + /// function easily understands. + /// unsigned getSmallConstantTripCount() const; /// getSmallConstantTripMultiple - Returns the largest constant divisor of the diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index f6fa0c8..a7f42c9 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -72,7 +72,7 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD, // free Call Utility Functions. // -/// isFreeCall - Returns true if the the value is a call to the builtin free() +/// isFreeCall - Returns true if the value is a call to the builtin free() bool isFreeCall(const Value *I); } // End llvm namespace diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index e281971..383ee88 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -452,11 +452,25 @@ namespace llvm { const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands); const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS); - const SCEV *getFieldOffsetExpr(const StructType *STy, unsigned FieldNo); - const SCEV *getAllocSizeExpr(const Type *AllocTy); const SCEV *getUnknown(Value *V); const SCEV *getCouldNotCompute(); + /// getSizeOfExpr - Return an expression for sizeof on the given type. + /// + const SCEV *getSizeOfExpr(const Type *AllocTy); + + /// getAlignOfExpr - Return an expression for alignof on the given type. + /// + const SCEV *getAlignOfExpr(const Type *AllocTy); + + /// getOffsetOfExpr - Return an expression for offsetof on the given field. + /// + const SCEV *getOffsetOfExpr(const StructType *STy, unsigned FieldNo); + + /// getOffsetOfExpr - Return an expression for offsetof on the given field. + /// + const SCEV *getOffsetOfExpr(const Type *CTy, Constant *FieldNo); + /// getNegativeSCEV - Return the SCEV object corresponding to -V. /// const SCEV *getNegativeSCEV(const SCEV *V); @@ -503,7 +517,7 @@ namespace llvm { /// getIntegerSCEV - Given a SCEVable type, create a constant for the /// specified signed integer value and return a SCEV for the constant. - const SCEV *getIntegerSCEV(int Val, const Type *Ty); + const SCEV *getIntegerSCEV(int64_t Val, const Type *Ty); /// getUMaxFromMismatchedTypes - Promote the operands to the wider of /// the types using zero-extension, and then perform a umax operation diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 01df503..26dc0c4 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -27,10 +27,7 @@ namespace llvm { /// and destroy it when finished to allow the release of the associated /// memory. class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { - public: ScalarEvolution &SE; - - private: std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > InsertedExpressions; std::set<Value*> InsertedValues; @@ -57,11 +54,11 @@ namespace llvm { /// in a more literal form. bool CanonicalMode; - protected: typedef IRBuilder<true, TargetFolder> BuilderType; BuilderType Builder; friend struct SCEVVisitor<SCEVExpander, Value*>; + public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. explicit SCEVExpander(ScalarEvolution &se) @@ -167,17 +164,13 @@ namespace llvm { Value *visitUMaxExpr(const SCEVUMaxExpr *S); - Value *visitFieldOffsetExpr(const SCEVFieldOffsetExpr *S); - - Value *visitAllocSizeExpr(const SCEVAllocSizeExpr *S); - Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); } - void rememberInstruction(Value *I) { - if (!PostIncLoop) InsertedValues.insert(I); - } + void rememberInstruction(Value *I); + + void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I); Value *expandAddRecExprLiterally(const SCEVAddRecExpr *); PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 64b8b0b..0ab3b3f 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -27,7 +27,7 @@ namespace llvm { // folders simpler. scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, - scFieldOffset, scAllocSize, scUnknown, scCouldNotCompute + scUnknown, scCouldNotCompute }; //===--------------------------------------------------------------------===// @@ -412,12 +412,15 @@ namespace llvm { } virtual bool hasComputableLoopEvolution(const Loop *QL) const { - if (L == QL) return true; - return false; + return L == QL; } virtual bool isLoopInvariant(const Loop *QueryLoop) const; + bool dominates(BasicBlock *BB, DominatorTree *DT) const; + + bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const; + /// isAffine - Return true if this is an affine AddRec (i.e., it represents /// an expressions A+B*x where A and B are loop invariant values. bool isAffine() const { @@ -512,95 +515,6 @@ namespace llvm { }; //===--------------------------------------------------------------------===// - /// SCEVTargetDataConstant - This node is the base class for representing - /// target-dependent values in a target-independent way. - /// - class SCEVTargetDataConstant : public SCEV { - protected: - const Type *Ty; - SCEVTargetDataConstant(const FoldingSetNodeID &ID, enum SCEVTypes T, - const Type *ty) : - SCEV(ID, T), Ty(ty) {} - - public: - virtual bool isLoopInvariant(const Loop *) const { return true; } - virtual bool hasComputableLoopEvolution(const Loop *) const { - return false; // not computable - } - - virtual bool hasOperand(const SCEV *) const { - return false; - } - - bool dominates(BasicBlock *, DominatorTree *) const { - return true; - } - - bool properlyDominates(BasicBlock *, DominatorTree *) const { - return true; - } - - virtual const Type *getType() const { return Ty; } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVTargetDataConstant *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scFieldOffset || - S->getSCEVType() == scAllocSize; - } - }; - - //===--------------------------------------------------------------------===// - /// SCEVFieldOffsetExpr - This node represents an offsetof expression. - /// - class SCEVFieldOffsetExpr : public SCEVTargetDataConstant { - friend class ScalarEvolution; - - const StructType *STy; - unsigned FieldNo; - SCEVFieldOffsetExpr(const FoldingSetNodeID &ID, const Type *ty, - const StructType *sty, unsigned fieldno) : - SCEVTargetDataConstant(ID, scFieldOffset, ty), - STy(sty), FieldNo(fieldno) {} - - public: - const StructType *getStructType() const { return STy; } - unsigned getFieldNo() const { return FieldNo; } - - virtual void print(raw_ostream &OS) const; - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVFieldOffsetExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scFieldOffset; - } - }; - - //===--------------------------------------------------------------------===// - /// SCEVAllocSize - This node represents a sizeof expression. - /// - class SCEVAllocSizeExpr : public SCEVTargetDataConstant { - friend class ScalarEvolution; - - const Type *AllocTy; - SCEVAllocSizeExpr(const FoldingSetNodeID &ID, - const Type *ty, const Type *allocty) : - SCEVTargetDataConstant(ID, scAllocSize, ty), - AllocTy(allocty) {} - - public: - const Type *getAllocType() const { return AllocTy; } - - virtual void print(raw_ostream &OS) const; - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAllocSizeExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAllocSize; - } - }; - - //===--------------------------------------------------------------------===// /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV /// value, and only represent it as its LLVM Value. This is the "bottom" /// value for the analysis. @@ -615,6 +529,16 @@ namespace llvm { public: Value *getValue() const { return V; } + /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special + /// constant representing a type size, alignment, or field offset in + /// a target-independent manner, and hasn't happened to have been + /// folded with other operations into something unrecognizable. This + /// is mainly only useful for pretty-printing and other situations + /// where it isn't absolutely required for these to succeed. + bool isSizeOf(const Type *&AllocTy) const; + bool isAlignOf(const Type *&AllocTy) const; + bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const; + virtual bool isLoopInvariant(const Loop *L) const; virtual bool hasComputableLoopEvolution(const Loop *QL) const { return false; // not computable @@ -665,10 +589,6 @@ namespace llvm { return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S); case scUMaxExpr: return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S); - case scFieldOffset: - return ((SC*)this)->visitFieldOffsetExpr((const SCEVFieldOffsetExpr*)S); - case scAllocSize: - return ((SC*)this)->visitAllocSizeExpr((const SCEVAllocSizeExpr*)S); case scUnknown: return ((SC*)this)->visitUnknown((const SCEVUnknown*)S); case scCouldNotCompute: diff --git a/include/llvm/Assembly/AsmAnnotationWriter.h b/include/llvm/Assembly/AsmAnnotationWriter.h index 6c3ddaf..6d75720 100644 --- a/include/llvm/Assembly/AsmAnnotationWriter.h +++ b/include/llvm/Assembly/AsmAnnotationWriter.h @@ -23,29 +23,34 @@ class Function; class BasicBlock; class Instruction; class raw_ostream; +class formatted_raw_ostream; class AssemblyAnnotationWriter { public: virtual ~AssemblyAnnotationWriter(); - // emitFunctionAnnot - This may be implemented to emit a string right before - // the start of a function. + /// emitFunctionAnnot - This may be implemented to emit a string right before + /// the start of a function. virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {} - // emitBasicBlockStartAnnot - This may be implemented to emit a string right - // after the basic block label, but before the first instruction in the block. + /// emitBasicBlockStartAnnot - This may be implemented to emit a string right + /// after the basic block label, but before the first instruction in the block. virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){ } - // emitBasicBlockEndAnnot - This may be implemented to emit a string right - // after the basic block. + /// emitBasicBlockEndAnnot - This may be implemented to emit a string right + /// after the basic block. virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){ } - // emitInstructionAnnot - This may be implemented to emit a string right - // before an instruction is emitted. + /// emitInstructionAnnot - This may be implemented to emit a string right + /// before an instruction is emitted. virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {} + + /// printInfoComment - This may be implemented to emit a comment to the + /// right of an instruction or global value. + virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {} }; } // End llvm namespace diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 7fa5d4a..126c290 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -58,6 +58,13 @@ const Attributes NoRedZone = 1<<22; /// disable redzone const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point /// instructions. const Attributes Naked = 1<<24; ///< Naked function +const Attributes InlineHint = 1<<25; ///< source said inlining was + ///desirable +const Attributes StackAlignment = 31<<26; ///< Alignment of stack for + ///function (5 bits) stored as log2 + ///of alignment with +1 bias + ///0 means unaligned (different from + ///alignstack(1)) /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -66,7 +73,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// be used on return values or function parameters. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone | NoImplicitFloat | Naked; + NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; @@ -103,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) { return 1U << ((Align >> 16) - 1); } +/// This turns an int stack alignment (which must be a power of 2) into +/// the form used internally in Attributes. +inline Attributes constructStackAlignmentFromInt(unsigned i) { + // Default alignment, allow the target to define how to align it. + if (i == 0) + return 0; + + assert(isPowerOf2_32(i) && "Alignment must be a power of two."); + assert(i <= 0x40000000 && "Alignment too large."); + return (Log2_32(i)+1) << 26; +} + +/// This returns the stack alignment field of an attribute as a byte alignment +/// value. +inline unsigned getStackAlignmentFromAttrs(Attributes A) { + Attributes StackAlign = A & Attribute::StackAlignment; + if (StackAlign == 0) + return 0; + + return 1U << ((StackAlign >> 26) - 1); +} + /// The set of Attributes set in Attributes is converted to a /// string of equivalent mnemonics. This is, presumably, for writing out diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h index e19e4c0..67f2a4a 100644 --- a/include/llvm/Bitcode/Archive.h +++ b/include/llvm/Bitcode/Archive.h @@ -27,7 +27,6 @@ namespace llvm { class MemoryBuffer; // Forward declare classes -class ModuleProvider; // From VMCore class Module; // From VMCore class Archive; // Declared below class ArchiveMemberHeader; // Internal implementation class @@ -374,14 +373,14 @@ class Archive { /// returns the associated module that defines that symbol. This method can /// be called as many times as necessary. This is handy for linking the /// archive into another module based on unresolved symbols. Note that the - /// ModuleProvider returned by this accessor should not be deleted by the - /// caller. It is managed internally by the Archive class. It is possible - /// that multiple calls to this accessor will return the same ModuleProvider - /// instance because the associated module defines multiple symbols. - /// @returns The ModuleProvider* found or null if the archive does not - /// contain a module that defines the \p symbol. + /// Module returned by this accessor should not be deleted by the caller. It + /// is managed internally by the Archive class. It is possible that multiple + /// calls to this accessor will return the same Module instance because the + /// associated module defines multiple symbols. + /// @returns The Module* found or null if the archive does not contain a + /// module that defines the \p symbol. /// @brief Look up a module by symbol name. - ModuleProvider* findModuleDefiningSymbol( + Module* findModuleDefiningSymbol( const std::string& symbol, ///< Symbol to be sought std::string* ErrMessage ///< Error message storage, if non-zero ); @@ -397,7 +396,7 @@ class Archive { /// @brief Look up multiple symbols in the archive. bool findModulesDefiningSymbols( std::set<std::string>& symbols, ///< Symbols to be sought - std::set<ModuleProvider*>& modules, ///< The modules matching \p symbols + std::set<Module*>& modules, ///< The modules matching \p symbols std::string* ErrMessage ///< Error msg storage, if non-zero ); @@ -513,9 +512,9 @@ class Archive { /// This type is used to keep track of bitcode modules loaded from the /// symbol table. It maps the file offset to a pair that consists of the - /// associated ArchiveMember and the ModuleProvider. + /// associated ArchiveMember and the Module. /// @brief Module mapping type - typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> > + typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> > ModuleMap; diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 2b1b85e..31d513c 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -291,7 +291,7 @@ private: /// 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 - /// known to exist at the end of the the record. + /// known to exist at the end of the record. template<typename uintty> void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, StringRef Blob) { diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 9bb50d4..a980df8 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -94,7 +94,8 @@ namespace bitc { TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) - TYPE_CODE_METADATA = 16 // METADATA + TYPE_CODE_METADATA = 16, // METADATA + TYPE_CODE_UNION = 17 // UNION: [eltty x N] }; // The type symbol table only has one code (TST_ENTRY_CODE). diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 7b74bdf..45eb801 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -18,21 +18,20 @@ namespace llvm { class Module; - class ModuleProvider; class MemoryBuffer; class ModulePass; class BitstreamWriter; class LLVMContext; class raw_ostream; - /// getBitcodeModuleProvider - Read the header of the specified bitcode buffer + /// getLazyBitcodeModule - Read the header of the specified bitcode buffer /// and prepare for lazy deserialization of function bodies. If successful, /// this takes ownership of 'buffer' and returns a non-null pointer. On /// error, this returns null, *does not* take ownership of Buffer, and fills /// in *ErrMsg with an error description if ErrMsg is non-null. - ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer, - LLVMContext& Context, - std::string *ErrMsg = 0); + Module *getLazyBitcodeModule(MemoryBuffer *Buffer, + LLVMContext& Context, + std::string *ErrMsg = 0); /// ParseBitcodeFile - Read the specified bitcode file, returning the module. /// If an error occurs, this returns null and fills in *ErrMsg if it is diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 377096c..28a1a3e 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -19,7 +19,6 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/DebugLoc.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/ADT/DenseMap.h" namespace llvm { class BlockAddress; @@ -62,13 +61,6 @@ namespace llvm { class AsmPrinter : public MachineFunctionPass { static char ID; - /// FunctionNumber - This provides a unique ID for each function emitted in - /// this translation unit. It is autoincremented by SetupMachineFunction, - /// and can be accessed with getFunctionNumber() and - /// IncrementFunctionNumber(). - /// - unsigned FunctionNumber; - // GCMetadataPrinters - The garbage collection metadata printer table. typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type; typedef gcp_map_type::iterator gcp_iterator; @@ -88,13 +80,6 @@ namespace llvm { DwarfWriter *DW; public: - /// Flags to specify different kinds of comments to output in - /// assembly code. These flags carry semantic information not - /// otherwise easily derivable from the IR text. - /// - enum CommentFlag { - ReloadReuse = 0x1 - }; /// Output stream on which we're printing assembly code. /// @@ -157,7 +142,8 @@ namespace llvm { protected: explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM, - const MCAsmInfo *T, bool V); + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *T); public: virtual ~AsmPrinter(); @@ -168,7 +154,7 @@ namespace llvm { /// getFunctionNumber - Return a unique ID for the current function. /// - unsigned getFunctionNumber() const { return FunctionNumber; } + unsigned getFunctionNumber() const; protected: /// getAnalysisUsage - Record analysis usage. @@ -215,26 +201,51 @@ namespace llvm { unsigned AsmVariant, const char *ExtraCode); + /// runOnMachineFunction - Emit the specified function out to the + /// OutStreamer. + virtual bool runOnMachineFunction(MachineFunction &MF) { + SetupMachineFunction(MF); + EmitFunctionHeader(); + EmitFunctionBody(); + return false; + } + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should - /// not normally call this, as the counter is automatically bumped by - /// SetupMachineFunction. - void IncrementFunctionNumber() { FunctionNumber++; } + /// EmitFunctionHeader - This method emits the header for the current + /// function. + void EmitFunctionHeader(); + + /// EmitFunctionBody - This method emits the body and trailer for a + /// function. + void EmitFunctionBody(); + + /// EmitInstruction - Targets should implement this to emit instructions. + virtual void EmitInstruction(const MachineInstr *MI) { + assert(0 && "EmitInstruction not implemented"); + } + + /// EmitFunctionBodyStart - Targets can override this to emit stuff before + /// the first basic block in the function. + virtual void EmitFunctionBodyStart() {} + + /// EmitFunctionBodyEnd - Targets can override this to emit stuff after + /// the last basic block in the function. + virtual void EmitFunctionBodyEnd() {} /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by /// the code generator. /// - void EmitConstantPool(MachineConstantPool *MCP); - + virtual void EmitConstantPool(); + /// EmitJumpTableInfo - Print assembly representations of the jump tables /// used by the current function to the current output stream. /// - void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF); + void EmitJumpTableInfo(); /// EmitGlobalVariable - Emit the specified global variable to the .s file. virtual void EmitGlobalVariable(const GlobalVariable *GV); @@ -265,9 +276,6 @@ namespace llvm { /// void EmitInt64(uint64_t Value) const; - /// EmitFile - Emit a .file directive. - void EmitFile(unsigned Number, StringRef Name) const; - //===------------------------------------------------------------------===// /// EmitAlignment - Emit an alignment directive to the specified power of @@ -292,19 +300,15 @@ namespace llvm { /// printLabel - This method prints a local label used by debug and /// exception handling tables. - void printLabel(const MachineInstr *MI) const; void printLabel(unsigned Id) const; /// printDeclare - This method prints a local variable declaration used by /// debug tables. void printDeclare(const MachineInstr *MI) const; - /// EmitComments - Pretty-print comments for instructions - void EmitComments(const MachineInstr &MI) const; - /// GetGlobalValueSymbol - Return the MCSymbol for the specified global /// value. - MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; + virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with /// global value name as its base, with the specified suffix, and where the @@ -317,23 +321,21 @@ namespace llvm { /// ExternalSymbol. MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; - /// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic - /// block label. - MCSymbol *GetMBBSymbol(unsigned MBBID) const; - /// GetCPISymbol - Return the symbol for the specified constant pool entry. MCSymbol *GetCPISymbol(unsigned CPID) const; /// GetJTISymbol - Return the symbol for the specified jump table entry. MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; + /// GetJTSetSymbol - Return the symbol for the specified jump table .set + /// FIXME: privatize to AsmPrinter. + MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const; + /// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress /// uses of the specified basic block. - MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA, - const char *Suffix = "") const; + MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; MCSymbol *GetBlockAddressSymbol(const Function *F, - const BasicBlock *BB, - const char *Suffix = "") const; + const BasicBlock *BB) const; /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing @@ -347,12 +349,21 @@ namespace llvm { void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0); protected: + virtual void EmitFunctionEntryLabel(); + virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); + /// printOffset - This is just convenient handler for printing offsets. + void printOffset(int64_t Offset) const; + + private: + /// processDebugLoc - Processes the debug information of each machine /// instruction's DebugLoc. void processDebugLoc(const MachineInstr *MI, bool BeforePrintingInsn); + void printLabelInst(const MachineInstr *MI) const; + /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. void printInlineAsm(const MachineInstr *MI) const; @@ -364,24 +375,15 @@ namespace llvm { /// printKill - This method prints the specified kill machine instruction. void printKill(const MachineInstr *MI) const; - /// printPICJumpTableSetLabel - This method prints a set label for the - /// specified MachineBasicBlock for a jumptable entry. - virtual void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const; - virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const; - - /// printVisibility - This prints visibility information about symbol, if + /// EmitVisibility - This emits visibility information about symbol, if /// this is suported by the target. - void printVisibility(MCSymbol *Sym, unsigned Visibility) const; + void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const; - /// printOffset - This is just convenient handler for printing offsets. - void printOffset(int64_t Offset) const; - - private: + void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const; + + void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const; void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 4d50879..7fda6f7 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -132,4 +132,283 @@ void SelectRoot(SelectionDAG &DAG) { CurDAG->setRoot(Dummy.getValue()); } + +/// CheckInteger - Return true if the specified node is not a ConstantSDNode or +/// if it doesn't have the specified value. +static bool CheckInteger(SDValue V, int64_t Val) { + ConstantSDNode *C = dyn_cast<ConstantSDNode>(V); + return C == 0 || C->getSExtValue() != Val; +} + +/// CheckAndImmediate - Check to see if the specified node is an and with an +/// immediate returning true on failure. +/// +/// FIXME: Inline this gunk into CheckAndMask. +bool CheckAndImmediate(SDValue V, int64_t Val) { + if (V->getOpcode() == ISD::AND) + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1))) + if (CheckAndMask(V.getOperand(0), C, Val)) + return false; + return true; +} + +/// CheckOrImmediate - Check to see if the specified node is an or with an +/// immediate returning true on failure. +/// +/// FIXME: Inline this gunk into CheckOrMask. +bool CheckOrImmediate(SDValue V, int64_t Val) { + if (V->getOpcode() == ISD::OR) + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1))) + if (CheckOrMask(V.getOperand(0), C, Val)) + return false; + return true; +} + +// These functions are marked always inline so that Idx doesn't get pinned to +// the stack. +ALWAYS_INLINE static int8_t +GetInt1(const unsigned char *MatcherTable, unsigned &Idx) { + return MatcherTable[Idx++]; +} + +ALWAYS_INLINE static int16_t +GetInt2(const unsigned char *MatcherTable, unsigned &Idx) { + int16_t Val = GetInt1(MatcherTable, Idx); + Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8; + return Val; +} + +ALWAYS_INLINE static int32_t +GetInt4(const unsigned char *MatcherTable, unsigned &Idx) { + int32_t Val = GetInt2(MatcherTable, Idx); + Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16; + return Val; +} + +ALWAYS_INLINE static int64_t +GetInt8(const unsigned char *MatcherTable, unsigned &Idx) { + int64_t Val = GetInt4(MatcherTable, Idx); + Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32; + return Val; +} + +enum BuiltinOpcodes { + OPC_Emit, + OPC_Push, + OPC_Record, + OPC_MoveChild, + OPC_MoveParent, + OPC_CheckSame, + OPC_CheckPatternPredicate, + OPC_CheckPredicate, + OPC_CheckOpcode, + OPC_CheckType, + OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8, + OPC_CheckCondCode, + OPC_CheckValueType, + OPC_CheckComplexPat, + OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8, + OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8, + OPC_IsProfitableToFold, + OPC_IsLegalToFold +}; + +struct MatchScope { + /// FailIndex - If this match fails, this is the index to continue with. + unsigned FailIndex; + + /// NodeStackSize - The size of the node stack when the scope was formed. + unsigned NodeStackSize; + + /// NumRecordedNodes - The number of recorded nodes when the scope was formed. + unsigned NumRecordedNodes; +}; + +SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, + unsigned TableSize) { + switch (NodeToMatch->getOpcode()) { + default: + break; + case ISD::EntryToken: // These nodes remain the same. + case ISD::BasicBlock: + case ISD::Register: + case ISD::HANDLENODE: + case ISD::TargetConstant: + case ISD::TargetConstantFP: + case ISD::TargetConstantPool: + case ISD::TargetFrameIndex: + case ISD::TargetExternalSymbol: + case ISD::TargetBlockAddress: + case ISD::TargetJumpTable: + case ISD::TargetGlobalTLSAddress: + case ISD::TargetGlobalAddress: + case ISD::TokenFactor: + case ISD::CopyFromReg: + case ISD::CopyToReg: + return 0; + case ISD::AssertSext: + case ISD::AssertZext: + ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0)); + return 0; + case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch); + case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch); + case ISD::UNDEF: return Select_UNDEF(NodeToMatch); + } + + assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); + + SmallVector<MatchScope, 8> MatchScopes; + + // RecordedNodes - This is the set of nodes that have been recorded by the + // state machine. + SmallVector<SDValue, 8> RecordedNodes; + + // Set up the node stack with NodeToMatch as the only node on the stack. + SmallVector<SDValue, 8> NodeStack; + SDValue N = SDValue(NodeToMatch, 0); + NodeStack.push_back(N); + + // Interpreter starts at opcode #0. + unsigned MatcherIndex = 0; + while (1) { + assert(MatcherIndex < TableSize && "Invalid index"); + switch ((BuiltinOpcodes)MatcherTable[MatcherIndex++]) { + case OPC_Emit: { + errs() << "EMIT NODE\n"; + return 0; + } + case OPC_Push: { + unsigned NumToSkip = MatcherTable[MatcherIndex++]; + MatchScope NewEntry; + NewEntry.FailIndex = MatcherIndex+NumToSkip; + NewEntry.NodeStackSize = NodeStack.size(); + NewEntry.NumRecordedNodes = RecordedNodes.size(); + MatchScopes.push_back(NewEntry); + continue; + } + case OPC_Record: + // Remember this node, it may end up being an operand in the pattern. + RecordedNodes.push_back(N); + continue; + + case OPC_MoveChild: { + unsigned Child = MatcherTable[MatcherIndex++]; + if (Child >= N.getNumOperands()) + break; // Match fails if out of range child #. + N = N.getOperand(Child); + NodeStack.push_back(N); + continue; + } + + case OPC_MoveParent: + // Pop the current node off the NodeStack. + NodeStack.pop_back(); + assert(!NodeStack.empty() && "Node stack imbalance!"); + N = NodeStack.back(); + continue; + + case OPC_CheckSame: { + // Accept if it is exactly the same as a previously recorded node. + unsigned RecNo = MatcherTable[MatcherIndex++]; + assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); + if (N != RecordedNodes[RecNo]) break; + continue; + } + case OPC_CheckPatternPredicate: + if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break; + continue; + case OPC_CheckPredicate: + if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break; + continue; + case OPC_CheckComplexPat: { + unsigned PatNo = MatcherTable[MatcherIndex++]; + (void)PatNo; + // FIXME: CHECK IT. + continue; + } + + case OPC_CheckOpcode: + if (N->getOpcode() != MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckType: + if (N.getValueType() != + (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckCondCode: + if (cast<CondCodeSDNode>(N)->get() != + (ISD::CondCode)MatcherTable[MatcherIndex++]) break; + continue; + case OPC_CheckValueType: + if (cast<VTSDNode>(N)->getVT() != + (MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break; + continue; + + case OPC_CheckInteger1: + if (CheckInteger(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger2: + if (CheckInteger(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger4: + if (CheckInteger(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckInteger8: + if (CheckInteger(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_CheckAndImm1: + if (CheckAndImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm2: + if (CheckAndImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm4: + if (CheckAndImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckAndImm8: + if (CheckAndImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_CheckOrImm1: + if (CheckOrImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm2: + if (CheckOrImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm4: + if (CheckOrImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break; + continue; + case OPC_CheckOrImm8: + if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break; + continue; + + case OPC_IsProfitableToFold: + assert(!NodeStack.size() == 1 && "No parent node"); + if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(), + NodeToMatch)) + break; + continue; + case OPC_IsLegalToFold: + assert(!NodeStack.size() == 1 && "No parent node"); + if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(), + NodeToMatch)) + break; + continue; + } + + // If the code reached this point, then the match failed pop out to the next + // match scope. + if (MatchScopes.empty()) { + CannotYetSelect(NodeToMatch); + return 0; + } + + RecordedNodes.resize(MatchScopes.back().NumRecordedNodes); + NodeStack.resize(MatchScopes.back().NodeStackSize); + MatcherIndex = MatchScopes.back().FailIndex; + MatchScopes.pop_back(); + } +} + + #endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */ diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h index 460c3c7..d59e22a 100644 --- a/include/llvm/CodeGen/DwarfWriter.h +++ b/include/llvm/CodeGen/DwarfWriter.h @@ -76,11 +76,11 @@ public: /// BeginFunction - Gather pre-function debug information. Assumes being /// emitted immediately after the function entry point. - void BeginFunction(MachineFunction *MF); + void BeginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function debug information. /// - void EndFunction(MachineFunction *MF); + void EndFunction(const MachineFunction *MF); /// RecordSourceLine - Register a source line with debug info. Returns a /// unique label ID used to generate a label and provide correspondence to diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h deleted file mode 100644 index 9dba838..0000000 --- a/include/llvm/CodeGen/FileWriters.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Functions to add the various file writer passes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_FILEWRITERS_H -#define LLVM_CODEGEN_FILEWRITERS_H - -namespace llvm { - - class PassManagerBase; - class ObjectCodeEmitter; - class TargetMachine; - class raw_ostream; - class formatted_raw_ostream; - class MachineFunctionPass; - class MCAsmInfo; - class MCCodeEmitter; - - ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); - MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O, - TargetMachine &TM, - const MCAsmInfo *T, - MCCodeEmitter *MCE); - -} // end llvm namespace - -#endif // LLVM_CODEGEN_FILEWRITERS_H diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index 9c4e5b9..0a1d4f4 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -146,7 +146,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index e31a7f0..512c94d 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -320,7 +320,7 @@ namespace llvm { /// advanceTo - Advance the specified iterator to point to the LiveRange /// containing the specified position, or end() if the position is past the /// end of the interval. If no LiveRange contains this position, but the - /// position is in a hole, this method returns an iterator pointing the the + /// position is in a hole, this method returns an iterator pointing to the /// LiveRange immediately after the hole. iterator advanceTo(iterator I, SlotIndex Pos) { if (Pos >= endIndex()) diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 20644c1..db82ba5 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -21,6 +21,9 @@ namespace llvm { class BasicBlock; class MachineFunction; +class MCContext; +class MCSymbol; +class StringRef; class raw_ostream; template <> @@ -338,7 +341,7 @@ public: bool isCond); /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping - /// any DEBUG_VALUE instructions. Return UnknownLoc if there is none. + /// any DBG_VALUE instructions. Return UnknownLoc if there is none. DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI); // Debugging methods. @@ -352,6 +355,10 @@ public: int getNumber() const { return Number; } void setNumber(int N) { Number = N; } + /// getSymbol - Return the MCSymbol for this basic block. + /// + MCSymbol *getSymbol(MCContext &Ctx) const; + private: // Methods used to maintain doubly linked list of blocks... friend struct ilist_traits<MachineBasicBlock>; diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index d598a93..48b4082 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -155,7 +155,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 8d6c1d1..e6698a5 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -136,7 +136,7 @@ public: : TD(td), PoolAlignment(1) {} ~MachineConstantPool(); - /// getConstantPoolAlignment - Return the the alignment required by + /// getConstantPoolAlignment - Return the alignment required by /// the whole constant pool, of which the first element must be aligned. unsigned getConstantPoolAlignment() const { return PoolAlignment; } diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 968e4ea..043e97f 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -276,6 +276,7 @@ public: assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && "Invalid Object Idx!"); Objects[ObjectIdx+NumFixedObjects].Alignment = Align; + MaxAlignment = std::max(MaxAlignment, Align); } /// getObjectOffset - Return the assigned stack offset of the specified object @@ -328,19 +329,6 @@ public: /// void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } - /// calculateMaxStackAlignment() - If there is a local object which requires - /// greater alignment than the current max alignment, adjust accordingly. - void calculateMaxStackAlignment() { - for (int i = getObjectIndexBegin(), - e = getObjectIndexEnd(); i != e; ++i) { - if (isDeadObjectIndex(i)) - continue; - - unsigned Align = getObjectAlignment(i); - MaxAlignment = std::max(MaxAlignment, Align); - } - } - /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// @@ -402,6 +390,7 @@ public: Objects.push_back(StackObject(Size, Alignment, 0, false, isSS)); int Index = (int)Objects.size()-NumFixedObjects-1; assert(Index >= 0 && "Bad frame index!"); + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } @@ -412,6 +401,7 @@ public: int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { CreateStackObject(Size, Alignment, true); int Index = (int)Objects.size()-NumFixedObjects-1; + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 6ca51bf..3c5b466 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -33,6 +33,7 @@ class MachineRegisterInfo; class MachineFrameInfo; class MachineConstantPool; class MachineJumpTableInfo; +class Pass; class TargetMachine; class TargetRegisterClass; @@ -112,6 +113,11 @@ class MachineFunction { // Tracks debug locations. DebugLocTracker DebugLocInfo; + /// FunctionNumber - This provides a unique ID for each function emitted in + /// this translation unit. + /// + unsigned FunctionNumber; + // The alignment of the function. unsigned Alignment; @@ -119,13 +125,17 @@ class MachineFunction { void operator=(const MachineFunction&); // intentionally unimplemented public: - MachineFunction(Function *Fn, const TargetMachine &TM); + MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum); ~MachineFunction(); /// getFunction - Return the LLVM function that this machine code represents /// Function *getFunction() const { return Fn; } + /// getFunctionNumber - Return a unique ID for the current function. + /// + unsigned getFunctionNumber() const { return FunctionNumber; } + /// getTarget - Return the target machine this machine code is compiled with /// const TargetMachine &getTarget() const { return Target; } @@ -143,11 +153,16 @@ public: const MachineFrameInfo *getFrameInfo() const { return FrameInfo; } /// getJumpTableInfo - Return the jump table info object for the current - /// function. This object contains information about jump tables for switch - /// instructions in the current function. - /// - MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; } + /// function. This object contains information about jump tables in the + /// current function. If the current function has no jump tables, this will + /// return null. const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; } + MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; } + + /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it + /// does already exist, allocate one. + MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind); + /// getConstantPool - Return the constant pool object for the current /// function. @@ -163,6 +178,11 @@ public: /// void setAlignment(unsigned A) { Alignment = A; } + /// EnsureAlignment - Make sure the function is at least 'A' bits aligned. + void EnsureAlignment(unsigned A) { + if (Alignment < A) Alignment = A; + } + /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. /// @@ -310,7 +330,7 @@ public: bool NoImp = false); /// CloneMachineInstr - Create a new MachineInstr which is a copy of the - /// 'Orig' instruction, identical in all ways except the the instruction + /// 'Orig' instruction, identical in all ways except the instruction /// has no parent, prev, or next. /// /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned @@ -363,6 +383,17 @@ public: MachineInstr::mmo_iterator End); //===--------------------------------------------------------------------===// + // Label Manipulation. + // + + /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table. + /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a + /// normal 'L' label is returned. + MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, + bool isLinkerPrivate = false) const; + + + //===--------------------------------------------------------------------===// // Debug location. // diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h index aa4cc91..ee2c6dd 100644 --- a/include/llvm/CodeGen/MachineFunctionAnalysis.h +++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h @@ -28,7 +28,7 @@ private: const TargetMachine &TM; CodeGenOpt::Level OptLevel; MachineFunction *MF; - + unsigned NextFnNum; public: static char ID; explicit MachineFunctionAnalysis(const TargetMachine &tm, @@ -39,6 +39,7 @@ public: CodeGenOpt::Level getOptLevel() const { return OptLevel; } private: + virtual bool doInitialization(Module &) { NextFnNum = 1; return false; } virtual bool runOnFunction(Function &F); virtual void releaseMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const; diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index c2a0578..6e33fb3 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -19,9 +19,9 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/Target/TargetInstrDesc.h" +#include "llvm/Target/TargetOpcodes.h" #include "llvm/Support/DebugLoc.h" #include <vector> @@ -41,6 +41,14 @@ class MachineInstr : public ilist_node<MachineInstr> { public: typedef MachineMemOperand **mmo_iterator; + /// Flags to specify different kinds of comments to output in + /// assembly code. These flags carry semantic information not + /// otherwise easily derivable from the IR text. + /// + enum CommentFlag { + ReloadReuse = 0x1 + }; + private: const TargetInstrDesc *TID; // Instruction descriptor. unsigned short NumImplicitOps; // Number of implicit operands (which @@ -121,14 +129,14 @@ public: /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set. /// - bool getAsmPrinterFlag(AsmPrinter::CommentFlag Flag) const { + bool getAsmPrinterFlag(CommentFlag Flag) const { return AsmPrinterFlags & Flag; } /// setAsmPrinterFlag - Set a flag for the AsmPrinter. /// - void setAsmPrinterFlag(unsigned short Flag) { - AsmPrinterFlags |= Flag; + void setAsmPrinterFlag(CommentFlag Flag) { + AsmPrinterFlags |= (unsigned short)Flag; } /// getDebugLoc - Returns the debug location id of this MachineInstr. @@ -193,12 +201,31 @@ public: /// isLabel - Returns true if the MachineInstr represents a label. /// - bool isLabel() const; - - /// isDebugLabel - Returns true if the MachineInstr represents a debug label. - /// - bool isDebugLabel() const; - + bool isLabel() const { + return getOpcode() == TargetOpcode::DBG_LABEL || + getOpcode() == TargetOpcode::EH_LABEL || + getOpcode() == TargetOpcode::GC_LABEL; + } + + bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } + bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } + bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } + bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } + + bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } + bool isKill() const { return getOpcode() == TargetOpcode::KILL; } + bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } + bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } + bool isExtractSubreg() const { + return getOpcode() == TargetOpcode::EXTRACT_SUBREG; + } + bool isInsertSubreg() const { + return getOpcode() == TargetOpcode::INSERT_SUBREG; + } + bool isSubregToReg() const { + return getOpcode() == TargetOpcode::SUBREG_TO_REG; + } + /// readsRegister - Return true if the MachineInstr reads the specified /// register. If TargetRegisterInfo is passed, then it also checks if there /// is a read of a super-register. @@ -320,7 +347,7 @@ public: /// isInvariantLoad - Return true if this instruction is loading from a /// location whose value is invariant across the function. For example, - /// loading a value from the constant pool or from from the argument area of + /// loading a value from the constant pool or from the argument area of /// a function if it does not change. This should only return true of *all* /// loads the instruction does are invariant (if it does multiple loads). bool isInvariantLoad(AliasAnalysis *AA) const; diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 8eb0add..a263a97 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -32,6 +32,7 @@ namespace RegState { Dead = 0x10, Undef = 0x20, EarlyClobber = 0x40, + Debug = 0x80, ImplicitDefine = Implicit | Define, ImplicitKill = Implicit | Kill }; @@ -62,7 +63,8 @@ public: flags & RegState::Dead, flags & RegState::Undef, flags & RegState::EarlyClobber, - SubReg)); + SubReg, + flags & RegState::Debug)); return *this; } diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index 57c65c8..5a4c9a9fb 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -40,13 +40,45 @@ struct MachineJumpTableEntry { }; class MachineJumpTableInfo { - unsigned EntrySize; - unsigned Alignment; +public: + /// JTEntryKind - This enum indicates how each entry of the jump table is + /// represented and emitted. + enum JTEntryKind { + /// EK_BlockAddress - Each entry is a plain address of block, e.g.: + /// .word LBB123 + EK_BlockAddress, + + /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded + /// with a relocation as gp-relative, e.g.: + /// .gprel32 LBB123 + EK_GPRel32BlockAddress, + + /// EK_LabelDifference32 - Each entry is the address of the block minus + /// the address of the jump table. This is used for PIC jump tables where + /// gprel32 is not supported. e.g.: + /// .word LBB123 - LJTI1_2 + /// If the .set directive is supported, this is emitted as: + /// .set L4_5_set_123, LBB123 - LJTI1_2 + /// .word L4_5_set_123 + EK_LabelDifference32, + + /// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the + /// TargetLowering::LowerCustomJumpTableEntry hook. + EK_Custom32 + }; +private: + JTEntryKind EntryKind; std::vector<MachineJumpTableEntry> JumpTables; public: - MachineJumpTableInfo(unsigned Size, unsigned Align) - : EntrySize(Size), Alignment(Align) {} + MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {} + JTEntryKind getEntryKind() const { return EntryKind; } + + /// getEntrySize - Return the size of each entry in the jump table. + unsigned getEntrySize(const TargetData &TD) const; + /// getEntryAlignment - Return the alignment of each entry in the jump table. + unsigned getEntryAlignment(const TargetData &TD) const; + /// getJumpTableIndex - Create a new jump table or return an existing one. /// unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs); @@ -58,9 +90,9 @@ public: const std::vector<MachineJumpTableEntry> &getJumpTables() const { return JumpTables; } - - /// RemoveJumpTable - Mark the specific index as being dead. This will cause - /// it to not be emitted. + + /// RemoveJumpTable - Mark the specific index as being dead. This will + /// prevent it from being emitted. void RemoveJumpTable(unsigned Idx) { JumpTables[Idx].MBBs.clear(); } @@ -74,13 +106,6 @@ public: bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old, MachineBasicBlock *New); - /// getEntrySize - Returns the size of an individual field in a jump table. - /// - unsigned getEntrySize() const { return EntrySize; } - - /// getAlignment - returns the target's preferred alignment for jump tables - unsigned getAlignment() const { return Alignment; } - /// print - Used by the MachineFunction printer to print information about /// jump tables. Implemented in MachineFunction.cpp /// diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 5dee199..7272aa5 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -46,7 +46,11 @@ public: /// The memory access writes data. MOStore = 2, /// The memory access is volatile. - MOVolatile = 4 + MOVolatile = 4, + /// The memory access is non-temporal. + MONonTemporal = 8, + // This is the number of bits we need to represent flags. + MOMaxBits = 4 }; /// MachineMemOperand - Construct an MachineMemOperand object with the @@ -64,7 +68,7 @@ public: const Value *getValue() const { return V; } /// getFlags - Return the raw flags of the source value, \see MemOperandFlags. - unsigned int getFlags() const { return Flags & 7; } + unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } /// getOffset - For normal values, this is a byte offset added to the base /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex @@ -80,11 +84,12 @@ public: /// getBaseAlignment - Return the minimum known alignment in bytes of the /// base address, without the offset. - uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; } + uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; } bool isLoad() const { return Flags & MOLoad; } bool isStore() const { return Flags & MOStore; } bool isVolatile() const { return Flags & MOVolatile; } + bool isNonTemporal() const { return Flags & MONonTemporal; } /// refineAlignment - Update this MachineMemOperand to reflect the alignment /// of MMO, if it has a greater alignment. This must only be used when the diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index d365029..8eeac9f 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -50,6 +50,7 @@ namespace llvm { //===----------------------------------------------------------------------===// // Forward declarations. class Constant; +class MCSymbol; class MDNode; class GlobalVariable; class MachineBasicBlock; @@ -66,6 +67,12 @@ class StructType; class MachineModuleInfoImpl { public: virtual ~MachineModuleInfoImpl(); + + typedef std::vector<std::pair<MCSymbol*, MCSymbol*> > + SymbolListTy; +protected: + static SymbolListTy + GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map); }; @@ -113,7 +120,14 @@ class MachineModuleInfo : public ImmutablePass { // LandingPads - List of LandingPadInfo describing the landing pad information // in the current function. std::vector<LandingPadInfo> LandingPads; - + + // Map of invoke call site index values to associated begin EH_LABEL for + // the current function. + DenseMap<unsigned, unsigned> CallSiteMap; + + // The current call site index being processed, if any. 0 if none. + unsigned CurCallSite; + // TypeInfos - List of C++ TypeInfo used in the current function. // std::vector<GlobalVariable *> TypeInfos; @@ -157,10 +171,6 @@ public: bool doInitialization(); bool doFinalization(); - /// BeginFunction - Begin gathering function meta information. - /// - void BeginFunction(MachineFunction *) {} - /// EndFunction - Discard function meta information. /// void EndFunction(); @@ -298,7 +308,26 @@ public: const std::vector<LandingPadInfo> &getLandingPads() const { return LandingPads; } - + + /// setCallSiteBeginLabel - Map the begin label for a call site + void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) { + CallSiteMap[BeginLabel] = Site; + } + + /// getCallSiteBeginLabel - Get the call site number for a begin label + unsigned getCallSiteBeginLabel(unsigned BeginLabel) { + assert(CallSiteMap.count(BeginLabel) && + "Missing call site number for EH_LABEL!"); + return CallSiteMap[BeginLabel]; + } + + /// setCurrentCallSite - Set the call site currently being processed. + void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } + + /// getCurrentCallSite - Get the call site currently being processed, if any. + /// return zero if none. + unsigned getCurrentCallSite(void) { return CurCallSite; } + /// getTypeInfos - Return a reference to the C++ typeinfo for the current /// function. const std::vector<GlobalVariable *> &getTypeInfos() const { diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index 44813cb..89b8207 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -19,46 +19,43 @@ namespace llvm { class MCSymbol; - + /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation /// for MachO targets. class MachineModuleInfoMachO : public MachineModuleInfoImpl { /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub", /// the value is something like "_foo". - DenseMap<const MCSymbol*, const MCSymbol*> FnStubs; + DenseMap<MCSymbol*, MCSymbol*> FnStubs; /// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like /// "Lfoo$non_lazy_ptr", the value is something like "_foo". - DenseMap<const MCSymbol*, const MCSymbol*> GVStubs; + DenseMap<MCSymbol*, MCSymbol*> GVStubs; /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like /// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs /// these are for things with hidden visibility. - DenseMap<const MCSymbol*, const MCSymbol*> HiddenGVStubs; + DenseMap<MCSymbol*, MCSymbol*> HiddenGVStubs; virtual void Anchor(); // Out of line virtual method. public: MachineModuleInfoMachO(const MachineModuleInfo &) {} - const MCSymbol *&getFnStubEntry(const MCSymbol *Sym) { + MCSymbol *&getFnStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return FnStubs[Sym]; } - const MCSymbol *&getGVStubEntry(const MCSymbol *Sym) { + MCSymbol *&getGVStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return GVStubs[Sym]; } - const MCSymbol *&getHiddenGVStubEntry(const MCSymbol *Sym) { + MCSymbol *&getHiddenGVStubEntry(MCSymbol *Sym) { assert(Sym && "Key cannot be null"); return HiddenGVStubs[Sym]; } - + /// Accessor methods to return the set of stubs in sorted order. - typedef std::vector<std::pair<const MCSymbol*, const MCSymbol*> > - SymbolListTy; - SymbolListTy GetFnStubList() const { return GetSortedStubs(FnStubs); } @@ -68,12 +65,31 @@ namespace llvm { SymbolListTy GetHiddenGVStubList() const { return GetSortedStubs(HiddenGVStubs); } - - private: - static SymbolListTy - GetSortedStubs(const DenseMap<const MCSymbol*, const MCSymbol*> &Map); }; - + + /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation + /// for ELF targets. + class MachineModuleInfoELF : public MachineModuleInfoImpl { + /// GVStubs - These stubs are used to materialize global addresses in PIC + /// mode. + DenseMap<MCSymbol*, MCSymbol*> GVStubs; + + virtual void Anchor(); // Out of line virtual method. + public: + MachineModuleInfoELF(const MachineModuleInfo &) {} + + MCSymbol *&getGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return GVStubs[Sym]; + } + + /// Accessor methods to return the set of stubs in sorted order. + + SymbolListTy GetGVStubList() const { + return GetSortedStubs(GVStubs); + } + }; + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 07d886d..dac0092 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -87,6 +87,10 @@ private: /// model the GCC inline asm '&' constraint modifier. bool IsEarlyClobber : 1; + /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo, + /// not a real instruction. Such uses should be ignored during codegen. + bool IsDebug : 1; + /// ParentMI - This is the instruction that this operand is embedded into. /// This is valid for all operand types, when the operand is in an instr. MachineInstr *ParentMI; @@ -214,6 +218,11 @@ public: return IsEarlyClobber; } + bool isDebug() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return IsDebug; + } + /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { @@ -236,11 +245,13 @@ public: void setIsUse(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); + assert((Val || !isDebug()) && "Marking a debug operation as def"); IsDef = !Val; } void setIsDef(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); + assert((!Val || !isDebug()) && "Marking a debug operation as def"); IsDef = Val; } @@ -251,6 +262,7 @@ public: void setIsKill(bool Val = true) { assert(isReg() && !IsDef && "Wrong MachineOperand accessor"); + assert((!Val || !isDebug()) && "Marking a debug operation as kill"); IsKill = Val; } @@ -366,7 +378,7 @@ public: /// the setReg method should be used. void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false, bool isKill = false, bool isDead = false, - bool isUndef = false); + bool isUndef = false, bool isDebug = false); //===--------------------------------------------------------------------===// // Construction methods. @@ -388,7 +400,8 @@ public: bool isKill = false, bool isDead = false, bool isUndef = false, bool isEarlyClobber = false, - unsigned SubReg = 0) { + unsigned SubReg = 0, + bool isDebug = false) { MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; @@ -396,6 +409,7 @@ public: Op.IsDead = isDead; Op.IsUndef = isUndef; Op.IsEarlyClobber = isEarlyClobber; + Op.IsDebug = isDebug; Op.Contents.Reg.RegNo = Reg; Op.Contents.Reg.Prev = 0; Op.Contents.Reg.Next = 0; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index c55cb32..01dc018 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -78,12 +78,12 @@ public: /// 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. - template<bool Uses, bool Defs> + template<bool Uses, bool Defs, bool SkipDebug> class defusechain_iterator; /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified /// register. - typedef defusechain_iterator<true,true> reg_iterator; + typedef defusechain_iterator<true,true,false> reg_iterator; reg_iterator reg_begin(unsigned RegNo) const { return reg_iterator(getRegUseDefListHead(RegNo)); } @@ -94,7 +94,7 @@ public: bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); } /// def_iterator/def_begin/def_end - Walk all defs of the specified register. - typedef defusechain_iterator<false,true> def_iterator; + typedef defusechain_iterator<false,true,false> def_iterator; def_iterator def_begin(unsigned RegNo) const { return def_iterator(getRegUseDefListHead(RegNo)); } @@ -105,7 +105,7 @@ public: bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); } /// use_iterator/use_begin/use_end - Walk all uses of the specified register. - typedef defusechain_iterator<true,false> use_iterator; + typedef defusechain_iterator<true,false,false> use_iterator; use_iterator use_begin(unsigned RegNo) const { return use_iterator(getRegUseDefListHead(RegNo)); } @@ -115,7 +115,20 @@ public: /// register. bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); } + /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the + /// specified register, skipping those marked as Debug. + typedef defusechain_iterator<true,false,true> use_nodbg_iterator; + use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const { + return use_nodbg_iterator(getRegUseDefListHead(RegNo)); + } + static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); } + /// use_nodbg_empty - Return true if there are no non-Debug instructions + /// using the specified register. + bool use_nodbg_empty(unsigned RegNo) const { + return use_nodbg_begin(RegNo) == use_nodbg_end(); + } + /// replaceRegWith - Replace all instances of FromReg with ToReg in the /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), /// except that it also changes any definitions of the register as well. @@ -258,8 +271,9 @@ public: /// operands in the function that use or define a specific register. If /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it /// returns defs. If neither are true then you are silly and it always - /// returns end(). - template<bool ReturnUses, bool ReturnDefs> + /// returns end(). If SkipDebug is true it skips uses marked Debug + /// when incrementing. + template<bool ReturnUses, bool ReturnDefs, bool SkipDebug> class defusechain_iterator : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> { MachineOperand *Op; @@ -268,7 +282,8 @@ public: // we are interested in. if (op) { if ((!ReturnUses && op->isUse()) || - (!ReturnDefs && op->isDef())) + (!ReturnDefs && op->isDef()) || + (SkipDebug && op->isDebug())) ++*this; } } @@ -299,7 +314,8 @@ public: // If this is an operand we don't care about, skip it. while (Op && ((!ReturnUses && Op->isUse()) || - (!ReturnDefs && Op->isDef()))) + (!ReturnDefs && Op->isDef()) || + (SkipDebug && Op->isDebug()))) Op = Op->getNextOperandForReg(); return *this; diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h index 1c15fab..c316785 100644 --- a/include/llvm/CodeGen/MachineRelocation.h +++ b/include/llvm/CodeGen/MachineRelocation.h @@ -138,14 +138,15 @@ public: /// static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, const char *ES, intptr_t cst = 0, - bool GOTrelative = 0) { + bool GOTrelative = 0, + bool NeedStub = true) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); MachineRelocation Result; Result.Offset = offset; Result.ConstantVal = cst; Result.TargetReloType = RelocationType; Result.AddrType = isExtSym; - Result.MayNeedFarStub = true; + Result.MayNeedFarStub = NeedStub; Result.GOTRelative = GOTrelative; Result.TargetResolve = false; Result.Target.ExtSym = ES; diff --git a/include/llvm/CodeGen/ObjectCodeEmitter.h b/include/llvm/CodeGen/ObjectCodeEmitter.h index 8252e07..170c0c8 100644 --- a/include/llvm/CodeGen/ObjectCodeEmitter.h +++ b/include/llvm/CodeGen/ObjectCodeEmitter.h @@ -81,7 +81,7 @@ public: /// written to the data stream in big-endian format. void emitDWordBE(uint64_t W); - /// emitAlignment - Move the CurBufferPtr pointer up the the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7e0da3f..dbc73cb 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -174,6 +174,10 @@ namespace llvm { /// optimization by increasing uses of extended values. FunctionPass *createOptimizeExtsPass(); + /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs + /// to take advantage of opportunities created during DAG legalization. + FunctionPass *createOptimizePHIsPass(); + /// createStackSlotColoringPass - This pass performs stack slot coloring. FunctionPass *createStackSlotColoringPass(bool); diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 33ebd00..e628603 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -581,18 +581,18 @@ public: /// determined by their operands, and they produce a value AND a token chain. /// SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, - SDValue Chain, SDValue Ptr, const Value *SV, - int SVOffset, EVT MemVT, bool isVolatile=false, - unsigned Alignment=0); + SDValue Chain, SDValue Ptr, const Value *SV, + int SVOffset, EVT MemVT, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, const Value *SV, int SVOffset, EVT MemVT, - bool isVolatile=false, unsigned Alignment=0); + bool isVolatile, bool isNonTemporal, unsigned Alignment); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, EVT MemVT, MachineMemOperand *MMO); @@ -600,13 +600,14 @@ public: /// getStore - Helper function to build ISD::STORE nodes. /// SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, MachineMemOperand *MMO); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, EVT TVT, - bool isVolatile=false, unsigned Alignment=0); + const Value *SV, int SVOffset, EVT TVT, + bool isNonTemporal, bool isVolatile, + unsigned Alignment); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, EVT TVT, MachineMemOperand *MMO); SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base, @@ -841,7 +842,7 @@ public: } /// AssignOrdering - Assign an order to the SDNode. - void AssignOrdering(SDNode *SD, unsigned Order); + void AssignOrdering(const SDNode *SD, unsigned Order); /// GetOrdering - Get the order for the SDNode. unsigned GetOrdering(const SDNode *SD) const; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index b33b21d..0be91b4 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -85,11 +85,13 @@ public: return true; } - /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of - /// U can be folded during instruction selection that starts at Root and - /// folding N is profitable. - virtual - bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const; + /// IsProfitableToFold - Returns true if it's profitable to fold the specific + /// operand node N of U during instruction selection that starts at Root. + virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const; + + /// IsLegalToFold - Returns true if the specific operand node N of + /// U can be folded during instruction selection that starts at Root. + virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const; /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. @@ -110,6 +112,25 @@ protected: bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; + + /// CheckPatternPredicate - This function is generated by tblgen in the + /// target. It runs the specified pattern predicate and returns true if it + /// succeeds or false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckPatternPredicate(unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + + /// CheckNodePredicate - This function is generated by tblgen in the + /// target. It runs node predicate #PredNo and returns true if it succeeds or + /// false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDNode *N); SDNode *Select_UNDEF(SDNode *N); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 45a9d40..df1f91b 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -609,7 +609,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+80; /// Node predicates @@ -821,6 +821,8 @@ public: /// set the SDNode 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; } @@ -1594,6 +1596,7 @@ public: } bool isVolatile() const { return (SubclassData >> 5) & 1; } + bool isNonTemporal() const { return MMO->isNonTemporal(); } /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return MMO->getValue(); } diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 163642a..dd4caba 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -72,10 +72,13 @@ namespace llvm { } } + bool isValid() const { + return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX); + } + MachineInstr* getInstr() const { return mi; } void setInstr(MachineInstr *mi) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->mi = mi; } @@ -83,25 +86,21 @@ namespace llvm { void setIndex(unsigned index) { assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && "Attempt to set index to invalid value."); - assert(this->index != EMPTY_KEY_INDEX && - this->index != TOMBSTONE_KEY_INDEX && - "Attempt to reset reserved index value."); + assert(isValid() && "Attempt to reset reserved index value."); this->index = index; } IndexListEntry* getNext() { return next; } const IndexListEntry* getNext() const { return next; } void setNext(IndexListEntry *next) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->next = next; } IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to modify reserved index."); + assert(isValid() && "Attempt to modify reserved index."); this->prev = prev; } @@ -192,7 +191,8 @@ namespace llvm { /// Returns true if this is a valid index. Invalid indicies do /// not point into an index table, and cannot be compared. bool isValid() const { - return (lie.getPointer() != 0) && (lie.getPointer()->getIndex() != 0); + IndexListEntry *entry = lie.getPointer(); + return ((entry!= 0) && (entry->isValid())); } /// Print this index to the given raw_ostream. diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h new file mode 100644 index 0000000..c5aa626 --- /dev/null +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -0,0 +1,202 @@ +//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object 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 implements classes used to handle lowerings specific to common +// object file formats. +// +//===----------------------------------------------------------------------===// + +#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" + +namespace llvm { + class MachineModuleInfo; + class Mangler; + class MCAsmInfo; + class MCExpr; + class MCSection; + class MCSectionMachO; + class MCSymbol; + class MCContext; + class GlobalValue; + class TargetMachine; + + +class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +protected: + /// TLSDataSection - Section directive for Thread Local data. + /// + const MCSection *TLSDataSection; // Defaults to ".tdata". + + /// TLSBSSSection - Section directive for Thread Local uninitialized data. + /// Null if this target doesn't support a BSS section. + /// + const MCSection *TLSBSSSection; // Defaults to ".tbss". + + const MCSection *DataRelSection; + const MCSection *DataRelLocalSection; + const MCSection *DataRelROSection; + const MCSection *DataRelROLocalSection; + + const MCSection *MergeableConst4Section; + const MCSection *MergeableConst8Section; + const MCSection *MergeableConst16Section; + +protected: + const MCSection *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind, + bool IsExplicit = false) const; +public: + TargetLoweringObjectFileELF() : UniquingMap(0) {} + ~TargetLoweringObjectFileELF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + const MCSection *getDataRelSection() const { return DataRelSection; } + + /// getSectionForConstant - Given a constant with the SectionKind, return a + /// section that it should be placed in. + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; + + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference + /// to the specified global variable from exception handling information. + /// + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; +}; + + + +class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { + mutable void *UniquingMap; + + const MCSection *CStringSection; + const MCSection *UStringSection; + const MCSection *TextCoalSection; + const MCSection *ConstTextCoalSection; + const MCSection *ConstDataCoalSection; + const MCSection *ConstDataSection; + const MCSection *DataCoalSection; + const MCSection *DataCommonSection; + const MCSection *DataBSSSection; + const MCSection *FourByteConstantSection; + const MCSection *EightByteConstantSection; + const MCSection *SixteenByteConstantSection; + + const MCSection *LazySymbolPointerSection; + const MCSection *NonLazySymbolPointerSection; +public: + TargetLoweringObjectFileMachO() : UniquingMap(0) {} + ~TargetLoweringObjectFileMachO(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; + + /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively + /// decide not to emit the UsedDirective for some symbols in llvm.used. + /// FIXME: REMOVE this (rdar://7071300) + virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, + Mangler *) const; + + /// getMachOSection - Return the MCSection for the specified mach-o section. + /// This requires the operands to be valid. + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + SectionKind K) const { + return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); + } + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + unsigned Reserved2, + SectionKind K) const; + + /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak + /// text symbols into. + const MCSection *getTextCoalSection() const { + return TextCoalSection; + } + + /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section + /// we put weak read-only symbols into. + const MCSection *getConstTextCoalSection() const { + return ConstTextCoalSection; + } + + /// getLazySymbolPointerSection - Return the section corresponding to + /// the .lazy_symbol_pointer directive. + const MCSection *getLazySymbolPointerSection() const { + return LazySymbolPointerSection; + } + + /// getNonLazySymbolPointerSection - Return the section corresponding to + /// the .non_lazy_symbol_pointer directive. + const MCSection *getNonLazySymbolPointerSection() const { + return NonLazySymbolPointerSection; + } + + /// getSymbolForDwarfGlobalReference - The mach-o version of this method + /// defaults to returning a stub reference. + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; +}; + + + +class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +public: + TargetLoweringObjectFileCOFF() : UniquingMap(0) {} + ~TargetLoweringObjectFileCOFF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getCOFFSection - Return the MCSection for the specified COFF section. + /// FIXME: Switch this to a semantic view eventually. + const MCSection *getCOFFSection(StringRef Name, bool isDirective, + SectionKind K) const; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 0125190..a7aafc0 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -492,26 +492,31 @@ namespace llvm { /// bitsEq - Return true if this has the same number of bits as VT. bool bitsEq(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() == VT.getSizeInBits(); } /// bitsGT - Return true if this has more bits than VT. bool bitsGT(EVT VT) const { + if (EVT::operator==(VT)) return false; return getSizeInBits() > VT.getSizeInBits(); } /// bitsGE - Return true if this has no less bits than VT. bool bitsGE(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() >= VT.getSizeInBits(); } /// bitsLT - Return true if this has less bits than VT. bool bitsLT(EVT VT) const { + if (EVT::operator==(VT)) return false; return getSizeInBits() < VT.getSizeInBits(); } /// bitsLE - Return true if this has no more bits than VT. bool bitsLE(EVT VT) const { + if (EVT::operator==(VT)) return true; return getSizeInBits() <= VT.getSizeInBits(); } diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 8051f55..ce4f374 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -1,13 +1,5 @@ /* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */ -/* Define if dlopen(0) will open the symbols of the program */ -#undef CAN_DLOPEN_SELF - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - /* 32 bit multilib directory. */ #undef CXX_INCLUDE_32BIT_DIR @@ -20,9 +12,6 @@ /* Directory with the libstdc++ headers. */ #undef CXX_INCLUDE_ROOT -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - /* Directories clang will search for headers */ #undef C_INCLUDE_DIRS @@ -35,13 +24,6 @@ /* Define if threads enabled */ #undef ENABLE_THREADS -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - /* Define to 1 if you have the `argz_append' function. */ #undef HAVE_ARGZ_APPEND @@ -69,9 +51,6 @@ /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY -/* Does not have bi-directional iterator */ -#undef HAVE_BI_ITERATOR - /* Define to 1 if you have the `ceilf' function. */ #undef HAVE_CEILF @@ -148,9 +127,6 @@ /* Define to 1 if you have the `fmodf' function. */ #undef HAVE_FMODF -/* Does not have forward iterator */ -#undef HAVE_FWD_ITERATOR - /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD @@ -276,9 +252,6 @@ /* Define if mmap() can map files into memory */ #undef HAVE_MMAP_FILE -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H @@ -375,9 +348,6 @@ /* Set to 1 if the std::isnan function is found in <cmath> */ #undef HAVE_STD_ISNAN_IN_CMATH -/* Does not have std namespace iterator */ -#undef HAVE_STD_ITERATOR - /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR @@ -587,14 +557,6 @@ /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ #undef STAT_MACROS_BROKEN diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 8072fd9..8647299 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -104,8 +104,7 @@ public: /// type, returns the elements of the vector in the specified smallvector. /// This handles breaking down a vector undef into undef elements, etc. For /// constant exprs and other cases we can't handle, we return an empty vector. - void getVectorElements(LLVMContext &Context, - SmallVectorImpl<Constant*> &Elts) const; + void getVectorElements(SmallVectorImpl<Constant*> &Elts) 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 diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index f34f9cb..bd14303d 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -33,6 +33,7 @@ namespace llvm { class ArrayType; class IntegerType; class StructType; +class UnionType; class PointerType; class VectorType; @@ -453,6 +454,50 @@ struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> { DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant) //===----------------------------------------------------------------------===// +// ConstantUnion - Constant Union Declarations +// +class ConstantUnion : public Constant { + friend struct ConstantCreator<ConstantUnion, UnionType, Constant*>; + ConstantUnion(const ConstantUnion &); // DO NOT IMPLEMENT +protected: + ConstantUnion(const UnionType *T, Constant* Val); +public: + // ConstantUnion accessors + static Constant *get(const UnionType *T, Constant* V); + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + + /// getType() specialization - Reduce amount of casting... + /// + inline const UnionType *getType() const { + return reinterpret_cast<const UnionType*>(Value::getType()); + } + + /// isNullValue - Return true if this is the value that would be returned by + /// getNullValue. This always returns false because zero structs are always + /// created as ConstantAggregateZero objects. + virtual bool isNullValue() const { + return false; + } + + 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 ConstantUnion *) { return true; } + static bool classof(const Value *V) { + return V->getValueID() == ConstantUnionVal; + } +}; + +template <> +struct OperandTraits<ConstantUnion> : public FixedNumOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantUnion, Constant) + +//===----------------------------------------------------------------------===// /// ConstantVector - Constant Vector Declarations /// class ConstantVector : public Constant { @@ -644,8 +689,7 @@ public: /// /// getAlignOf constant expr - computes the alignment of a type in a target - /// independent way (Note: the return type is an i32; Note: assumes that i8 - /// is byte aligned). + /// independent way (Note: the return type is an i64). static Constant *getAlignOf(const Type* Ty); /// getSizeOf constant expr - computes the size of a type in a target @@ -653,10 +697,15 @@ public: /// static Constant *getSizeOf(const Type* Ty); - /// getOffsetOf constant expr - computes the offset of a field in a target - /// independent way (Note: the return type is an i64). + /// 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(const StructType* STy, unsigned FieldNo); + + /// getOffsetOf constant expr - This is a generalized form of getOffsetOf, + /// which supports any aggregate type, and any Constant index. /// - static Constant *getOffsetOf(const StructType* Ty, unsigned FieldNo); + static Constant *getOffsetOf(const Type* Ty, Constant *FieldNo); static Constant *getNeg(Constant *C); static Constant *getFNeg(Constant *C); @@ -693,9 +742,13 @@ public: static Constant *getBitCast (Constant *C, const Type *Ty); static Constant *getNSWNeg(Constant *C); + static Constant *getNUWNeg(Constant *C); static Constant *getNSWAdd(Constant *C1, Constant *C2); + static Constant *getNUWAdd(Constant *C1, Constant *C2); static Constant *getNSWSub(Constant *C1, Constant *C2); + static Constant *getNUWSub(Constant *C1, Constant *C2); static Constant *getNSWMul(Constant *C1, Constant *C2); + static Constant *getNUWMul(Constant *C1, Constant *C2); static Constant *getExactSDiv(Constant *C1, Constant *C2); /// Transparently provide more efficient getOperand methods. diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index c220608..912bb6d 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -27,6 +27,7 @@ template<class ValType, class TypeClass> class TypeMap; class FunctionValType; class ArrayValType; class StructValType; +class UnionValType; class PointerValType; class VectorValType; class IntegerValType; @@ -229,7 +230,8 @@ public: return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || T->getTypeID() == PointerTyID || - T->getTypeID() == VectorTyID; + T->getTypeID() == VectorTyID || + T->getTypeID() == UnionTyID; } }; @@ -301,6 +303,63 @@ public: }; +/// UnionType - Class to represent union types. A union type is similar to +/// a structure, except that all member fields begin at offset 0. +/// +class UnionType : public CompositeType { + friend class TypeMap<UnionValType, UnionType>; + UnionType(const UnionType &); // Do not implement + const UnionType &operator=(const UnionType &); // Do not implement + UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes); +public: + /// UnionType::get - This static method is the primary way to create a + /// UnionType. + static UnionType *get(const Type* const* Types, unsigned NumTypes); + + /// UnionType::get - This static method is a convenience method for + /// creating union types by specifying the elements as arguments. + static UnionType *get(const Type *type, ...) END_WITH_NULL; + + /// isValidElementType - Return true if the specified type is valid as a + /// element type. + static bool isValidElementType(const Type *ElemTy); + + /// Given an element type, return the member index of that type, or -1 + /// if there is no such member type. + int getElementTypeIndex(const Type *ElemTy) const; + + // Iterator access to the elements + typedef Type::subtype_iterator element_iterator; + element_iterator element_begin() const { return ContainedTys; } + element_iterator element_end() const { return &ContainedTys[NumContainedTys];} + + // Random access to the elements + unsigned getNumElements() const { return NumContainedTys; } + const Type *getElementType(unsigned N) const { + assert(N < NumContainedTys && "Element number out of range!"); + return ContainedTys[N]; + } + + /// getTypeAtIndex - Given an index value into the type, return the type of + /// the element. For a union type, this must be a constant value... + /// + virtual const Type *getTypeAtIndex(const Value *V) const; + virtual const Type *getTypeAtIndex(unsigned Idx) const; + virtual bool indexValid(const Value *V) const; + virtual bool indexValid(unsigned Idx) const; + + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UnionType *) { return true; } + static inline bool classof(const Type *T) { + return T->getTypeID() == UnionTyID; + } +}; + + /// SequentialType - This is the superclass of the array, pointer and vector /// type classes. All of these represent "arrays" in memory. The array type /// represents a specifically sized array, pointer types are unsized/unknown @@ -496,6 +555,7 @@ public: /// OpaqueType - Class to represent abstract types /// class OpaqueType : public DerivedType { + friend class LLVMContextImpl; OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT OpaqueType(LLVMContext &C); diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index d2c547d..c3f1902 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -19,6 +19,7 @@ #include <map> #include <string> #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/System/Mutex.h" @@ -36,7 +37,6 @@ class JITEventListener; class JITMemoryManager; class MachineCodeInfo; class Module; -class ModuleProvider; class MutexGuard; class TargetData; class Type; @@ -95,9 +95,9 @@ class ExecutionEngine { friend class EngineBuilder; // To allow access to JITCtor and InterpCtor. protected: - /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We - /// use a smallvector to optimize for the case where there is only one module. - SmallVector<ModuleProvider*, 1> Modules; + /// Modules - This is a list of Modules that we are JIT'ing from. We use a + /// smallvector to optimize for the case where there is only one module. + SmallVector<Module*, 1> Modules; void setTargetData(const TargetData *td) { TD = td; @@ -109,13 +109,17 @@ protected: // To avoid having libexecutionengine depend on the JIT and interpreter // libraries, the JIT and Interpreter set these functions to ctor pointers // at startup time if they are linked in. - static ExecutionEngine *(*JITCtor)(ModuleProvider *MP, - std::string *ErrorStr, - JITMemoryManager *JMM, - CodeGenOpt::Level OptLevel, - bool GVsWithCode, - CodeModel::Model CMM); - static ExecutionEngine *(*InterpCtor)(ModuleProvider *MP, + static ExecutionEngine *(*JITCtor)( + Module *M, + std::string *ErrorStr, + JITMemoryManager *JMM, + CodeGenOpt::Level OptLevel, + bool GVsWithCode, + CodeModel::Model CMM, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs); + static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); /// LazyFunctionCreator - If an unknown function is needed, this function @@ -141,8 +145,8 @@ public: /// create - This is the factory method for creating an execution engine which /// is appropriate for the current machine. This takes ownership of the - /// module provider. - static ExecutionEngine *create(ModuleProvider *MP, + /// module. + static ExecutionEngine *create(Module *M, bool ForceInterpreter = false, std::string *ErrorStr = 0, CodeGenOpt::Level OptLevel = @@ -158,18 +162,13 @@ public: // default freeMachineCodeForFunction works. bool GVsWithCode = true); - /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. This takes ownership of the - /// module. - static ExecutionEngine *create(Module *M); - /// createJIT - This is the factory method for creating a JIT for the current /// machine, it does not fall back to the interpreter. This takes ownership - /// of the ModuleProvider and JITMemoryManager if successful. + /// of the Module and JITMemoryManager if successful. /// /// Clients should make sure to initialize targets prior to calling this /// function. - static ExecutionEngine *createJIT(ModuleProvider *MP, + static ExecutionEngine *createJIT(Module *M, std::string *ErrorStr = 0, JITMemoryManager *JMM = 0, CodeGenOpt::Level OptLevel = @@ -178,11 +177,11 @@ public: CodeModel::Model CMM = CodeModel::Default); - /// addModuleProvider - Add a ModuleProvider to the list of modules that we - /// can JIT from. Note that this takes ownership of the ModuleProvider: when - /// the ExecutionEngine is destroyed, it destroys the MP as well. - virtual void addModuleProvider(ModuleProvider *P) { - Modules.push_back(P); + /// addModule - Add a Module to the list of modules that we can JIT from. + /// Note that this takes ownership of the Module: when the ExecutionEngine is + /// destroyed, it destroys the Module as well. + virtual void addModule(Module *M) { + Modules.push_back(M); } //===----------------------------------------------------------------------===// @@ -190,16 +189,9 @@ public: const TargetData *getTargetData() const { return TD; } - /// removeModuleProvider - Remove a ModuleProvider from the list of modules. - /// Relases the Module from the ModuleProvider, materializing it in the - /// process, and returns the materialized Module. - virtual Module* removeModuleProvider(ModuleProvider *P, - std::string *ErrInfo = 0); - - /// deleteModuleProvider - Remove a ModuleProvider from the list of modules, - /// and deletes the ModuleProvider and owned Module. Avoids materializing - /// the underlying module. - virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0); + /// removeModule - Remove a Module from the list of modules. Returns true if + /// M is found. + virtual bool removeModule(Module *M); /// FindFunctionNamed - Search all of the active modules to find the one that /// defines FnName. This is very slow operation and shouldn't be used for @@ -393,7 +385,7 @@ public: } protected: - explicit ExecutionEngine(ModuleProvider *P); + explicit ExecutionEngine(Module *M); void emitGlobals(); @@ -422,13 +414,16 @@ namespace EngineKind { class EngineBuilder { private: - ModuleProvider *MP; + Module *M; EngineKind::Kind WhichEngine; std::string *ErrorStr; CodeGenOpt::Level OptLevel; JITMemoryManager *JMM; bool AllocateGVsWithCode; CodeModel::Model CMModel; + std::string MArch; + std::string MCPU; + SmallVector<std::string, 4> MAttrs; /// InitEngine - Does the common initialization of default options. /// @@ -443,16 +438,11 @@ class EngineBuilder { public: /// EngineBuilder - Constructor for EngineBuilder. If create() is called and - /// is successful, the created engine takes ownership of the module - /// provider. - EngineBuilder(ModuleProvider *mp) : MP(mp) { + /// is successful, the created engine takes ownership of the module. + EngineBuilder(Module *m) : M(m) { InitEngine(); } - /// EngineBuilder - Overloaded constructor that automatically creates an - /// ExistingModuleProvider for an existing module. - EngineBuilder(Module *m); - /// setEngineKind - Controls whether the user wants the interpreter, the JIT, /// or whichever engine works. This option defaults to EngineKind::Either. EngineBuilder &setEngineKind(EngineKind::Kind w) { @@ -502,6 +492,26 @@ class EngineBuilder { return *this; } + /// setMArch - Override the architecture set by the Module's triple. + EngineBuilder &setMArch(StringRef march) { + MArch.assign(march.begin(), march.end()); + return *this; + } + + /// setMCPU - Target a specific cpu type. + EngineBuilder &setMCPU(StringRef mcpu) { + MCPU.assign(mcpu.begin(), mcpu.end()); + return *this; + } + + /// setMAttrs - Set cpu-specific attributes. + template<typename StringSequence> + EngineBuilder &setMAttrs(const StringSequence &mattrs) { + MAttrs.clear(); + MAttrs.append(mattrs.begin(), mattrs.end()); + return *this; + } + ExecutionEngine *create(); }; diff --git a/include/llvm/GVMaterializer.h b/include/llvm/GVMaterializer.h new file mode 100644 index 0000000..c143552 --- /dev/null +++ b/include/llvm/GVMaterializer.h @@ -0,0 +1,66 @@ +//===-- llvm/GVMaterializer.h - Interface for GV materializers --*- 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 an abstract interface for loading a module from some +// place. This interface allows incremental or random access loading of +// functions from the file. This is useful for applications like JIT compilers +// or interprocedural optimizers that do not need the entire program in memory +// at the same time. +// +//===----------------------------------------------------------------------===// + +#ifndef GVMATERIALIZER_H +#define GVMATERIALIZER_H + +#include <string> + +namespace llvm { + +class Function; +class GlobalValue; +class Module; + +class GVMaterializer { +protected: + GVMaterializer() {} + +public: + virtual ~GVMaterializer(); + + /// isMaterializable - True if GV can be materialized from whatever backing + /// store this GVMaterializer uses and has not been materialized yet. + virtual bool isMaterializable(const GlobalValue *GV) const = 0; + + /// isDematerializable - True if GV has been materialized and can be + /// dematerialized back to whatever backing store this GVMaterializer uses. + virtual bool isDematerializable(const GlobalValue *GV) const = 0; + + /// Materialize - make sure the given GlobalValue is fully read. If the + /// module is corrupt, this returns true and fills in the optional string with + /// information about the problem. If successful, this returns false. + /// + virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0) = 0; + + /// Dematerialize - If the given GlobalValue is read in, and if the + /// GVMaterializer supports it, release the memory for the GV, and set it up + /// to be materialized lazily. If the Materializer doesn't support this + /// capability, this method is a noop. + /// + virtual void Dematerialize(GlobalValue *) {} + + /// MaterializeModule - make sure the entire Module has been completely read. + /// On error, this returns true and fills in the optional string with + /// information about the problem. If successful, this returns false. + /// + virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0) = 0; +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 9875a83..c15b555 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -43,7 +43,6 @@ public: DLLImportLinkage, ///< Function to be imported from DLL DLLExportLinkage, ///< Function to be accessible from DLL. ExternalWeakLinkage,///< ExternalWeak linkage description. - GhostLinkage, ///< Stand-in functions for streaming fns from BC files. CommonLinkage ///< Tentative definitions. }; @@ -93,7 +92,7 @@ public: void setSection(StringRef S) { Section = S; } /// If the usage is empty (except transitively dead constants), then this - /// global value can can be safely deleted since the destructor will + /// global value can be safely deleted since the destructor will /// delete the dead constants as well. /// @brief Determine if the usage of this global value is empty except /// for transitively dead constants. @@ -132,7 +131,6 @@ public: bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; } bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; } bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; } - bool hasGhostLinkage() const { return Linkage == GhostLinkage; } bool hasCommonLinkage() const { return Linkage == CommonLinkage; } void setLinkage(LinkageTypes LT) { Linkage = LT; } @@ -164,12 +162,33 @@ public: /// create a GlobalValue) from the GlobalValue Src to this one. virtual void copyAttributesFrom(const GlobalValue *Src); - /// hasNotBeenReadFromBitcode - If a module provider is being used to lazily - /// stream in functions from disk, this method can be used to check to see if - /// the function has been read in yet or not. Unless you are working on the - /// JIT or something else that streams stuff in lazily, you don't need to - /// worry about this. - bool hasNotBeenReadFromBitcode() const { return Linkage == GhostLinkage; } +/// @name Materialization +/// Materialization is used to construct functions only as they're needed. This +/// is useful to reduce memory usage in LLVM or parsing work done by the +/// BitcodeReader to load the Module. +/// @{ + + /// isMaterializable - If this function's Module is being lazily streamed in + /// functions from disk or some other source, this method can be used to check + /// to see if the function has been read in yet or not. + bool isMaterializable() const; + + /// isDematerializable - Returns true if this function was loaded from a + /// GVMaterializer that's still attached to its Module and that knows how to + /// dematerialize the function. + bool isDematerializable() const; + + /// Materialize - make sure this GlobalValue is fully read. If the module is + /// corrupt, this returns true and fills in the optional string with + /// information about the problem. If successful, this returns false. + bool Materialize(std::string *ErrInfo = 0); + + /// Dematerialize - If this GlobalValue is read in, and if the GVMaterializer + /// supports it, release the memory for the function, and set it up to be + /// materialized lazily. If !isDematerializable(), this method is a noop. + void Dematerialize(); + +/// @} /// Override from Constant class. No GlobalValue's are null values so this /// always returns false. diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index 482e53e..4490ce5 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -39,7 +39,7 @@ class InlineAsm : public Value { virtual ~InlineAsm(); public: - /// InlineAsm::get - Return the the specified uniqued inline asm string. + /// InlineAsm::get - Return the specified uniqued inline asm string. /// static InlineAsm *get(const FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index b5cc659..49cdd6a 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -299,6 +299,27 @@ public: return BO; } + /// CreateNUWMul - Create a Mul operator with the NUW flag set. + /// + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateMul(V1, V2, Name); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateMul(V1, V2, Name, BB); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWMul(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateMul(V1, V2, Name, I); + BO->setHasNoUnsignedWrap(true); + return BO; + } + /// CreateExactSDiv - Create an SDiv operator with the exact flag set. /// static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, @@ -334,6 +355,10 @@ public: Instruction *InsertBefore = 0); static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); + static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "", + Instruction *InsertBefore = 0); + static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "", Instruction *InsertBefore = 0); static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name, @@ -671,36 +696,36 @@ public: /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the /// predicate values are not overlapping between the classes. enum Predicate { - // Opcode U L G E Intuitive operation - FCMP_FALSE = 0, /// 0 0 0 0 Always false (always folded) - FCMP_OEQ = 1, /// 0 0 0 1 True if ordered and equal - FCMP_OGT = 2, /// 0 0 1 0 True if ordered and greater than - FCMP_OGE = 3, /// 0 0 1 1 True if ordered and greater than or equal - FCMP_OLT = 4, /// 0 1 0 0 True if ordered and less than - FCMP_OLE = 5, /// 0 1 0 1 True if ordered and less than or equal - FCMP_ONE = 6, /// 0 1 1 0 True if ordered and operands are unequal - FCMP_ORD = 7, /// 0 1 1 1 True if ordered (no nans) - FCMP_UNO = 8, /// 1 0 0 0 True if unordered: isnan(X) | isnan(Y) - FCMP_UEQ = 9, /// 1 0 0 1 True if unordered or equal - FCMP_UGT = 10, /// 1 0 1 0 True if unordered or greater than - FCMP_UGE = 11, /// 1 0 1 1 True if unordered, greater than, or equal - FCMP_ULT = 12, /// 1 1 0 0 True if unordered or less than - FCMP_ULE = 13, /// 1 1 0 1 True if unordered, less than, or equal - FCMP_UNE = 14, /// 1 1 1 0 True if unordered or not equal - FCMP_TRUE = 15, /// 1 1 1 1 Always true (always folded) + // Opcode U L G E Intuitive operation + FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded) + FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal + FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than + FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal + FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than + FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal + FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal + FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans) + FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y) + FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal + FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than + FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal + FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than + FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal + FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal + FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded) FIRST_FCMP_PREDICATE = FCMP_FALSE, LAST_FCMP_PREDICATE = FCMP_TRUE, BAD_FCMP_PREDICATE = FCMP_TRUE + 1, - ICMP_EQ = 32, /// equal - ICMP_NE = 33, /// not equal - ICMP_UGT = 34, /// unsigned greater than - ICMP_UGE = 35, /// unsigned greater or equal - ICMP_ULT = 36, /// unsigned less than - ICMP_ULE = 37, /// unsigned less or equal - ICMP_SGT = 38, /// signed greater than - ICMP_SGE = 39, /// signed greater or equal - ICMP_SLT = 40, /// signed less than - ICMP_SLE = 41, /// signed less or equal + ICMP_EQ = 32, ///< equal + ICMP_NE = 33, ///< not equal + ICMP_UGT = 34, ///< unsigned greater than + ICMP_UGE = 35, ///< unsigned greater or equal + ICMP_ULT = 36, ///< unsigned less than + ICMP_ULE = 37, ///< unsigned less or equal + ICMP_SGT = 38, ///< signed greater than + ICMP_SGE = 39, ///< signed greater or equal + ICMP_SLT = 40, ///< signed less than + ICMP_SLE = 41, ///< signed less or equal FIRST_ICMP_PREDICATE = ICMP_EQ, LAST_ICMP_PREDICATE = ICMP_SLE, BAD_ICMP_PREDICATE = ICMP_SLE + 1 diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index d45da97..cf9dc44 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -148,7 +148,7 @@ public: getAllMetadataImpl(MDs); } - /// setMetadata - Set the metadata of of the specified kind to the specified + /// 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. void setMetadata(unsigned KindID, MDNode *Node); diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index c6cdbd5..1ae495f 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -590,7 +590,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || isa<PointerType>(getOperand(0)->getType())) && "Invalid operand types for ICmp instruction"); } @@ -611,7 +611,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || isa<PointerType>(getOperand(0)->getType())) && "Invalid operand types for ICmp instruction"); } @@ -630,7 +630,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || isa<PointerType>(getOperand(0)->getType())) && "Invalid operand types for ICmp instruction"); } @@ -740,7 +740,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } @@ -759,7 +759,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } @@ -776,7 +776,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index 8f1b1ae..5cfe551 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -63,9 +63,9 @@ namespace Intrinsic { /// declaration for an intrinsic, and return it. /// /// The Tys and numTys parameters are for intrinsics with overloaded types - /// (e.g., those using iAny or fAny). For a declaration for an overloaded - /// intrinsic, Tys should point to an array of numTys pointers to Type, - /// and must provide exactly one type for each overloaded type in the + /// (e.g., those using iAny, fAny, vAny, or iPTRAny). For a declaration for an + /// overloaded intrinsic, Tys should point to an array of numTys pointers to + /// Type, and must provide exactly one type for each overloaded type in the /// intrinsic. Function *getDeclaration(Module *M, ID id, const Type **Tys = 0, unsigned numTys = 0); diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 684f872..3a0da9c 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -309,6 +309,7 @@ let Properties = [IntrNoMem] in { def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>; def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; + def int_eh_sjlj_callsite: Intrinsic<[llvm_void_ty], [llvm_i32_ty]>; } //===---------------- Generic Variable Attribute Intrinsics----------------===// diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h index a68a2e0..cc7bf88 100644 --- a/include/llvm/Linker.h +++ b/include/llvm/Linker.h @@ -223,7 +223,7 @@ class Linker { /// 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 the archive has been processed + /// 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. diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 5e31dfe..3effea4 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -47,17 +47,6 @@ namespace llvm { /// emitted in Static relocation model. bool HasStaticCtorDtorReferenceInStaticMode; // Default is false. - /// NeedsSet - True if target asm treats expressions in data directives - /// as linktime-relocatable. For assembly-time computation, we need to - /// use a .set. Thus: - /// .set w, x-y - /// .long w - /// is computed at assembly time, while - /// .long x-y - /// is relocated if the relative locations of x and y change at linktime. - /// We want both these things in different places. - bool NeedsSet; // Defaults to false. - /// MaxInstLength - This is the maximum possible length of an instruction, /// which is needed to compute the size of an inline asm. unsigned MaxInstLength; // Defaults to 4. @@ -73,7 +62,7 @@ namespace llvm { /// CommentColumn - This indicates the comment num (zero-based) at /// which asm comments should be printed. - unsigned CommentColumn; // Defaults to 60 + unsigned CommentColumn; // Defaults to 40 /// CommentString - This indicates the comment character used by the /// assembler. @@ -134,6 +123,11 @@ namespace llvm { const char *Data32bitsDirective; // Defaults to "\t.long\t" const char *Data64bitsDirective; // Defaults to "\t.quad\t" + /// GPRel32Directive - if non-null, a directive that is used to emit a word + /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword + /// on Mips or .gprel32 on Alpha. + const char *GPRel32Directive; // Defaults to NULL. + /// getDataASDirective - Return the directive that should be used to emit /// data of the specified size to the specified numeric address space. virtual const char *getDataASDirective(unsigned Size, unsigned AS) const { @@ -168,14 +162,6 @@ namespace llvm { /// space created as the result of a alignment directive. unsigned TextAlignFillValue; // Defaults to 0 - //===--- Section Switching Directives ---------------------------------===// - - /// JumpTableDirective - if non-null, the directive to emit before jump - /// table entries. FIXME: REMOVE THIS. - const char *JumpTableDirective; // Defaults to NULL. - const char *PICJumpTableDirective; // Defaults to NULL. - - //===--- Global Variable Emission Directives --------------------------===// /// GlobalDirective - This is the directive used to declare a global entity. @@ -187,17 +173,16 @@ namespace llvm { /// const char *ExternDirective; // Defaults to NULL. - /// SetDirective - This is the name of a directive that can be used to tell - /// the assembler to set the value of a variable to some expression. - const char *SetDirective; // Defaults to null. + /// HasSetDirective - True if the assembler supports the .set directive. + bool HasSetDirective; // Defaults to true. /// HasLCOMMDirective - This is true if the target supports the .lcomm /// directive. - bool HasLCOMMDirective; // Defaults to false. + bool HasLCOMMDirective; // Defaults to false. - /// COMMDirectiveTakesAlignment - True if COMMDirective take a third - /// argument that specifies the alignment of the declaration. - bool COMMDirectiveTakesAlignment; // Defaults to true. + /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional + /// alignment is to be specified in bytes instead of log2(n). + bool COMMDirectiveAlignmentIsInBytes; // Defaults to true; /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. @@ -305,6 +290,7 @@ namespace llvm { const char *getData64bitsDirective(unsigned AS = 0) const { return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS); } + const char *getGPRel32Directive() const { return GPRel32Directive; } /// getNonexecutableStackSection - Targets can implement this method to /// specify a section to switch to if the translation unit doesn't have any @@ -327,9 +313,6 @@ namespace llvm { bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } - bool needsSet() const { - return NeedsSet; - } unsigned getMaxInstLength() const { return MaxInstLength; } @@ -378,9 +361,6 @@ namespace llvm { const char *getAscizDirective() const { return AscizDirective; } - const char *getJumpTableDirective(bool isPIC) const { - return isPIC ? PICJumpTableDirective : JumpTableDirective; - } const char *getAlignDirective() const { return AlignDirective; } @@ -396,14 +376,12 @@ namespace llvm { const char *getExternDirective() const { return ExternDirective; } - const char *getSetDirective() const { - return SetDirective; - } + bool hasSetDirective() const { return HasSetDirective; } bool hasLCOMMDirective() const { return HasLCOMMDirective; } - bool getCOMMDirectiveTakesAlignment() const { - return COMMDirectiveTakesAlignment; - } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} + bool getCOMMDirectiveAlignmentIsInBytes() const { + return COMMDirectiveAlignmentIsInBytes; + } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } const char *getWeakRefDirective() const { return WeakRefDirective; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index be017bf..4527f3c 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -14,6 +14,7 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/Casting.h" +#include "llvm/MC/MCFixup.h" #include "llvm/System/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -22,10 +23,34 @@ class raw_ostream; class MCAssembler; class MCContext; class MCExpr; +class MCFragment; class MCSection; class MCSectionData; class MCSymbol; +/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment +/// which needs to be rewritten. This region will either be rewritten by the +/// assembler or cause a relocation entry to be generated. +struct MCAsmFixup { + /// Offset - The offset inside the fragment which needs to be rewritten. + uint64_t Offset; + + /// Value - The expression to eventually write into the fragment. + const MCExpr *Value; + + /// Kind - The fixup kind. + MCFixupKind Kind; + + /// FixedValue - The value to replace the fix up by. + // + // FIXME: This should not be here. + uint64_t FixedValue; + +public: + MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) + : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {} +}; + class MCFragment : public ilist_node<MCFragment> { MCFragment(const MCFragment&); // DO NOT IMPLEMENT void operator=(const MCFragment&); // DO NOT IMPLEMENT @@ -85,7 +110,7 @@ public: uint64_t getAddress() const; - uint64_t getFileSize() const { + uint64_t getFileSize() const { assert(FileSize != ~UINT64_C(0) && "File size not set!"); return FileSize; } @@ -103,11 +128,20 @@ public: /// @} static bool classof(const MCFragment *O) { return true; } + + virtual void dump(); }; class MCDataFragment : public MCFragment { SmallString<32> Contents; + /// Fixups - The list of fixups in this fragment. + std::vector<MCAsmFixup> Fixups; + +public: + typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator; + typedef std::vector<MCAsmFixup>::iterator fixup_iterator; + public: MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} @@ -123,10 +157,28 @@ public: /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Data; + /// @name Fixup Access + /// @{ + + std::vector<MCAsmFixup> &getFixups() { return Fixups; } + const std::vector<MCAsmFixup> &getFixups() const { return Fixups; } + + fixup_iterator fixup_begin() { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + + 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; } static bool classof(const MCDataFragment *) { return true; } + + virtual void dump(); }; class MCAlignFragment : public MCFragment { @@ -158,7 +210,7 @@ public: } unsigned getAlignment() const { return Alignment; } - + int64_t getValue() const { return Value; } unsigned getValueSize() const { return ValueSize; } @@ -167,15 +219,17 @@ public: /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Align; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Align; } static bool classof(const MCAlignFragment *) { return true; } + + virtual void dump(); }; class MCFillFragment : public MCFragment { /// Value - Value to use for filling bytes. - const MCExpr *Value; + int64_t Value; /// ValueSize - The size (in bytes) of \arg Value to use when filling. unsigned ValueSize; @@ -184,10 +238,10 @@ class MCFillFragment : public MCFragment { uint64_t Count; public: - MCFillFragment(const MCExpr &_Value, unsigned _ValueSize, uint64_t _Count, - MCSectionData *SD = 0) + MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count, + MCSectionData *SD = 0) : MCFragment(FT_Fill, SD), - Value(&_Value), ValueSize(_ValueSize), Count(_Count) {} + Value(_Value), ValueSize(_ValueSize), Count(_Count) {} /// @name Accessors /// @{ @@ -196,25 +250,27 @@ public: return ValueSize * Count; } - const MCExpr &getValue() const { return *Value; } - + int64_t getValue() const { return Value; } + unsigned getValueSize() const { return ValueSize; } uint64_t getCount() const { return Count; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Fill; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Fill; } static bool classof(const MCFillFragment *) { return true; } + + virtual void dump(); }; class MCOrgFragment : public MCFragment { /// Offset - The offset this fragment should start at. const MCExpr *Offset; - /// Value - Value to use for filling bytes. + /// Value - Value to use for filling bytes. int8_t Value; public: @@ -231,15 +287,17 @@ public: } const MCExpr &getOffset() const { return *Offset; } - + uint8_t getValue() const { return Value; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Org; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Org; } static bool classof(const MCOrgFragment *) { return true; } + + virtual void dump(); }; /// MCZeroFillFragment - Represent data which has a fixed size and alignment, @@ -265,15 +323,17 @@ public: } uint64_t getSize() const { return Size; } - + unsigned getAlignment() const { return Alignment; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_ZeroFill; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_ZeroFill; } static bool classof(const MCZeroFillFragment *) { return true; } + + virtual void dump(); }; // FIXME: Should this be a separate class, or just merged into MCSection? Since @@ -284,41 +344,13 @@ class MCSectionData : public ilist_node<MCSectionData> { void operator=(const MCSectionData&); // DO NOT IMPLEMENT public: - /// Fixup - Represent a fixed size region of bytes inside some fragment which - /// needs to be rewritten. This region will either be rewritten by the - /// assembler or cause a relocation entry to be generated. - struct Fixup { - /// Fragment - The fragment containing the fixup. - MCFragment *Fragment; - - /// Offset - The offset inside the fragment which needs to be rewritten. - uint64_t Offset; - - /// Value - The expression to eventually write into the fragment. - const MCExpr *Value; - - /// Size - The fixup size. - unsigned Size; - - /// FixedValue - The value to replace the fix up by. - // - // FIXME: This should not be here. - uint64_t FixedValue; - - public: - Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value, - unsigned _Size) - : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size), - FixedValue(0) {} - }; - typedef iplist<MCFragment> FragmentListType; typedef FragmentListType::const_iterator const_iterator; typedef FragmentListType::iterator iterator; - typedef std::vector<Fixup>::const_iterator const_fixup_iterator; - typedef std::vector<Fixup>::iterator fixup_iterator; + typedef FragmentListType::const_reverse_iterator const_reverse_iterator; + typedef FragmentListType::reverse_iterator reverse_iterator; private: iplist<MCFragment> Fragments; @@ -343,15 +375,13 @@ private: /// initialized. uint64_t FileSize; - /// LastFixupLookup - Cache for the last looked up fixup. - mutable unsigned LastFixupLookup; + /// HasInstructions - Whether this section has had instructions emitted into + /// it. + unsigned HasInstructions : 1; - /// Fixups - The list of fixups in this section. - std::vector<Fixup> Fixups; - /// @} -public: +public: // Only for use as sentinel. MCSectionData(); MCSectionData(const MCSection &Section, MCAssembler *A = 0); @@ -373,27 +403,15 @@ public: iterator end() { return Fragments.end(); } const_iterator end() const { return Fragments.end(); } - size_t size() const { return Fragments.size(); } + reverse_iterator rbegin() { return Fragments.rbegin(); } + const_reverse_iterator rbegin() const { return Fragments.rbegin(); } - bool empty() const { return Fragments.empty(); } + reverse_iterator rend() { return Fragments.rend(); } + const_reverse_iterator rend() const { return Fragments.rend(); } - /// @} - /// @name Fixup Access - /// @{ - - std::vector<Fixup> &getFixups() { - return Fixups; - } - - fixup_iterator fixup_begin() { - return Fixups.begin(); - } - - fixup_iterator fixup_end() { - return Fixups.end(); - } + size_t size() const { return Fragments.size(); } - size_t fixup_size() const { return Fixups.size(); } + bool empty() const { return Fragments.empty(); } /// @} /// @name Assembler Backend Support @@ -401,35 +419,30 @@ public: // // FIXME: This could all be kept private to the assembler implementation. - /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg - /// Offset. - /// - /// If multiple fixups exist for the same fragment and offset it is undefined - /// which one is returned. - // - // FIXME: This isn't horribly slow in practice, but there are much nicer - // solutions to applying the fixups. - const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const; - - uint64_t getAddress() const { + uint64_t getAddress() const { assert(Address != ~UINT64_C(0) && "Address not set!"); return Address; } void setAddress(uint64_t Value) { Address = Value; } - uint64_t getSize() const { + uint64_t getSize() const { assert(Size != ~UINT64_C(0) && "File size not set!"); return Size; } void setSize(uint64_t Value) { Size = Value; } - uint64_t getFileSize() const { + uint64_t getFileSize() const { assert(FileSize != ~UINT64_C(0) && "File size not set!"); return FileSize; } - void setFileSize(uint64_t Value) { FileSize = Value; } + void setFileSize(uint64_t Value) { FileSize = Value; } + + bool hasInstructions() const { return HasInstructions; } + void setHasInstructions(bool Value) { HasInstructions = Value; } /// @} + + void dump(); }; // FIXME: Same concerns as with SectionData. @@ -443,7 +456,7 @@ public: /// Offset - The offset to apply to the fragment address to form this symbol's /// value. uint64_t Offset; - + /// IsExternal - True if this symbol is visible outside this translation /// unit. unsigned IsExternal : 1; @@ -489,10 +502,10 @@ public: /// @} /// @name Symbol Attributes /// @{ - + bool isExternal() const { return IsExternal; } void setExternal(bool Value) { IsExternal = Value; } - + bool isPrivateExtern() const { return IsPrivateExtern; } void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } @@ -525,14 +538,16 @@ public: /// setFlags - Set the (implementation defined) symbol flags. void setFlags(uint32_t Value) { Flags = Value; } - + /// getIndex - Get the (implementation defined) index. uint64_t getIndex() const { return Index; } /// setIndex - Set the (implementation defined) index. void setIndex(uint64_t Value) { Index = Value; } - - /// @} + + /// @} + + void dump(); }; // FIXME: This really doesn't belong here. See comments below. @@ -561,7 +576,7 @@ private: MCContext &Context; raw_ostream &OS; - + iplist<MCSectionData> Sections; iplist<MCSymbolData> Symbols; @@ -605,7 +620,7 @@ public: /// @{ const SectionDataListType &getSectionList() const { return Sections; } - SectionDataListType &getSectionList() { return Sections; } + SectionDataListType &getSectionList() { return Sections; } iterator begin() { return Sections.begin(); } const_iterator begin() const { return Sections.begin(); } @@ -652,6 +667,8 @@ public: size_t indirect_symbol_size() const { return IndirectSymbols.size(); } /// @} + + void dump(); }; } // end namespace llvm diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index ad42dc2..fe1aff4 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -10,23 +10,60 @@ #ifndef LLVM_MC_MCCODEEMITTER_H #define LLVM_MC_MCCODEEMITTER_H +#include "llvm/MC/MCFixup.h" + +#include <cassert> + namespace llvm { +class MCExpr; class MCInst; class raw_ostream; +template<typename T> class SmallVectorImpl; + +/// MCFixupKindInfo - Target independent information on a fixup kind. +struct MCFixupKindInfo { + /// A target specific name for the fixup kind. The names will be unique for + /// distinct kinds on any given target. + const char *Name; + + /// The bit offset to write the relocation into. + // + // FIXME: These two fields are under-specified and not general enough, but it + // is covers many things, and is enough to let the AsmStreamer pretty-print + // the encoding. + unsigned TargetOffset; + + /// The number of bits written by this fixup. The bits are assumed to be + /// contiguous. + unsigned TargetSize; +}; /// MCCodeEmitter - Generic instruction encoding interface. class MCCodeEmitter { +private: MCCodeEmitter(const MCCodeEmitter &); // DO NOT IMPLEMENT void operator=(const MCCodeEmitter &); // DO NOT IMPLEMENT protected: // Can only create subclasses. MCCodeEmitter(); - + public: virtual ~MCCodeEmitter(); + /// @name Target Independent Fixup Information + /// @{ + + /// getNumFixupKinds - Get the number of target specific fixup kinds. + virtual unsigned getNumFixupKinds() const = 0; + + /// getFixupKindInfo - Get information on a fixup kind. + virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; + + /// @} + /// EncodeInstruction - Encode the given \arg Inst to bytes on the output /// stream \arg OS. - virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS) const = 0; + virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups) const = 0; }; } // End llvm namespace diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 57ce75d..1f7364d 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -17,26 +17,32 @@ namespace llvm { enum MCSymbolAttr { - MCSA_Invalid = 0, /// Not a valid directive. + MCSA_Invalid = 0, ///< Not a valid directive. // Various directives in alphabetical order. - MCSA_Global, /// .globl - MCSA_Hidden, /// .hidden (ELF) - MCSA_IndirectSymbol, /// .indirect_symbol (MachO) - MCSA_Internal, /// .internal (ELF) - MCSA_LazyReference, /// .lazy_reference (MachO) - MCSA_Local, /// .local (ELF) - MCSA_NoDeadStrip, /// .no_dead_strip (MachO) - MCSA_PrivateExtern, /// .private_extern (MachO) - MCSA_Protected, /// .protected (ELF) - MCSA_Reference, /// .reference (MachO) - MCSA_Weak, /// .weak - MCSA_WeakDefinition, /// .weak_definition (MachO) - MCSA_WeakReference /// .weak_reference (MachO) + MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function + MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC + MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object + MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object + MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common + MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype + MCSA_Global, ///< .globl + MCSA_Hidden, ///< .hidden (ELF) + MCSA_IndirectSymbol, ///< .indirect_symbol (MachO) + MCSA_Internal, ///< .internal (ELF) + MCSA_LazyReference, ///< .lazy_reference (MachO) + MCSA_Local, ///< .local (ELF) + MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) + MCSA_PrivateExtern, ///< .private_extern (MachO) + MCSA_Protected, ///< .protected (ELF) + MCSA_Reference, ///< .reference (MachO) + MCSA_Weak, ///< .weak + MCSA_WeakDefinition, ///< .weak_definition (MachO) + MCSA_WeakReference ///< .weak_reference (MachO) }; enum MCAssemblerFlag { - MCAF_SubsectionsViaSymbols /// .subsections_via_symbols (MachO) + MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO) }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 73d5f8e..fce7602 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -29,7 +29,8 @@ public: Binary, ///< Binary expressions. Constant, ///< Constant expressions. SymbolRef, ///< References to labels and assigned expressions. - Unary ///< Unary expressions. + Unary, ///< Unary expressions. + Target ///< Target specific expression. }; private: @@ -39,7 +40,7 @@ private: void operator=(const MCExpr&); // DO NOT IMPLEMENT protected: - MCExpr(ExprKind _Kind) : Kind(_Kind) {} + explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} public: /// @name Accessors @@ -85,7 +86,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { class MCConstantExpr : public MCExpr { int64_t Value; - MCConstantExpr(int64_t _Value) + explicit MCConstantExpr(int64_t _Value) : MCExpr(MCExpr::Constant), Value(_Value) {} public: @@ -117,7 +118,7 @@ public: class MCSymbolRefExpr : public MCExpr { const MCSymbol *Symbol; - MCSymbolRefExpr(const MCSymbol *_Symbol) + explicit MCSymbolRefExpr(const MCSymbol *_Symbol) : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {} public: @@ -201,20 +202,24 @@ public: enum Opcode { Add, ///< Addition. And, ///< Bitwise and. - Div, ///< Division. + Div, ///< Signed division. EQ, ///< Equality comparison. - GT, ///< Greater than comparison. - GTE, ///< Greater than or equal comparison. + GT, ///< Signed greater than comparison (result is either 0 or some + ///< target-specific non-zero value) + GTE, ///< Signed greater than or equal comparison (result is either 0 or + ///< some target-specific non-zero value). LAnd, ///< Logical and. LOr, ///< Logical or. - LT, ///< Less than comparison. - LTE, ///< Less than or equal comparison. - Mod, ///< Modulus. + LT, ///< Signed less than comparison (result is either 0 or + ///< some target-specific non-zero value). + LTE, ///< Signed less than or equal comparison (result is either 0 or + ///< some target-specific non-zero value). + Mod, ///< Signed remainder. Mul, ///< Multiplication. NE, ///< Inequality comparison. Or, ///< Bitwise or. - Shl, ///< Bitwise shift left. - Shr, ///< Bitwise shift right. + Shl, ///< Shift left. + Shr, ///< Shift right (arithmetic or logical, depending on target) Sub, ///< Subtraction. Xor ///< Bitwise exclusive or. }; @@ -326,6 +331,28 @@ public: static bool classof(const MCBinaryExpr *) { return true; } }; +/// MCTargetExpr - This is an extension point for target-specific MCExpr +/// subclasses to implement. +/// +/// NOTE: All subclasses are required to have trivial destructors because +/// MCExprs are bump pointer allocated and not destructed. +class MCTargetExpr : public MCExpr { + virtual void Anchor(); +protected: + MCTargetExpr() : MCExpr(Target) {} + virtual ~MCTargetExpr() {} +public: + + virtual void PrintImpl(raw_ostream &OS) const = 0; + virtual bool EvaluateAsRelocatableImpl(MCValue &Res) const = 0; + + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } + static bool classof(const MCTargetExpr *) { return true; } +}; + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h new file mode 100644 index 0000000..cd0dd19 --- /dev/null +++ b/include/llvm/MC/MCFixup.h @@ -0,0 +1,108 @@ +//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- 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_MCFIXUP_H +#define LLVM_MC_MCFIXUP_H + +#include <cassert> + +namespace llvm { +class MCExpr; + +// Private constants, do not use. +// +// This is currently laid out so that the MCFixup fields can be efficiently +// accessed, while keeping the offset field large enough that the assembler +// backend can reasonably use the MCFixup representation for an entire fragment +// (splitting any overly large fragments). +// +// The division of bits between the kind and the opindex can be tweaked if we +// end up needing more bits for target dependent kinds. +enum { + MCFIXUP_NUM_GENERIC_KINDS = 128, + MCFIXUP_NUM_KIND_BITS = 16, + MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_KIND_BITS) +}; + +/// MCFixupKind - Extensible enumeration to represent the type of a fixup. +enum MCFixupKind { + FK_Data_1 = 0, ///< A one-byte fixup. + FK_Data_2, ///< A two-byte fixup. + FK_Data_4, ///< A four-byte fixup. + FK_Data_8, ///< A eight-byte fixup. + + FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS, + + MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS) +}; + +/// MCFixup - Encode information on a single operation to perform on an byte +/// sequence (e.g., an encoded instruction) which requires assemble- or run- +/// time patching. +/// +/// Fixups are used any time the target instruction encoder needs to represent +/// some value in an instruction which is not yet concrete. The encoder will +/// encode the instruction assuming the value is 0, and emit a fixup which +/// communicates to the assembler backend how it should rewrite the encoded +/// value. +/// +/// During the process of relaxation, the assembler will apply fixups as +/// symbolic values become concrete. When relaxation is complete, any remaining +/// fixups become relocations in the object file (or errors, if the fixup cannot +/// be encoded on the target). +class MCFixup { + static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS; + + /// The value to put into the fixup location. The exact interpretation of the + /// expression is target dependent, usually it will one of the operands to an + /// instruction or an assembler directive. + const MCExpr *Value; + + /// The byte index of start of the relocation inside the encoded instruction. + unsigned Offset : MCFIXUP_NUM_OFFSET_BITS; + + /// The target dependent kind of fixup item this is. The kind is used to + /// determine how the operand value should be encoded into the instruction. + unsigned Kind : MCFIXUP_NUM_KIND_BITS; + +public: + static MCFixup Create(unsigned Offset, const MCExpr *Value, + MCFixupKind Kind) { + MCFixup FI; + FI.Value = Value; + FI.Offset = Offset; + FI.Kind = unsigned(Kind); + + assert(Offset == FI.getOffset() && "Offset out of range!"); + assert(Kind == FI.getKind() && "Kind out of range!"); + return FI; + } + + MCFixupKind getKind() const { return MCFixupKind(Kind); } + + unsigned getOffset() const { return Offset; } + + const MCExpr *getValue() const { return Value; } + + /// getKindForSize - Return the generic fixup kind for a value with the given + /// size. It is an error to pass an unsupported size. + static MCFixupKind getKindForSize(unsigned Size) { + switch (Size) { + default: assert(0 && "Invalid generic fixup size!"); + case 1: return FK_Data_1; + case 2: return FK_Data_2; + case 4: return FK_Data_4; + case 8: return FK_Data_8; + } + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index d62a9da..d2ddc5b 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -14,22 +14,36 @@ namespace llvm { class MCInst; class raw_ostream; class MCAsmInfo; +class StringRef; - /// MCInstPrinter - This is an instance of a target assembly language printer /// that converts an MCInst to valid target assembly syntax. class MCInstPrinter { protected: + /// O - The main stream to emit instruction text to. raw_ostream &O; + + /// CommentStream - a stream that comments can be emitted to if desired. + /// Each comment must end with a newline. This will be null if verbose + /// assembly emission is disable. + raw_ostream *CommentStream; const MCAsmInfo &MAI; public: - MCInstPrinter(raw_ostream &o, const MCAsmInfo &mai) : O(o), MAI(mai) {} + MCInstPrinter(raw_ostream &o, const MCAsmInfo &mai) + : O(o), CommentStream(0), MAI(mai) {} virtual ~MCInstPrinter(); + + /// setCommentStream - Specify a stream to emit comments to. + void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } /// printInst - Print the specified MCInst to the current raw_ostream. /// virtual void printInst(const MCInst *MI) = 0; + + /// getOpcodeName - Return the name of the specified opcode enum (e.g. + /// "MOV32ri") or empty if we can't resolve it. + virtual StringRef getOpcodeName(unsigned Opcode) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index f82584c..829604c 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -61,8 +61,8 @@ private: /// in the directive name and the location of the directive keyword. StringMap<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap; public: - AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, - const MCAsmInfo &_MAI); + AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, + const MCAsmInfo &MAI); ~AsmParser(); bool Run(); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 2bcb594..624d9a6 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -60,6 +60,10 @@ namespace llvm { /// @name Assembly File Formatting. /// @{ + + /// isVerboseAsm - Return true if this streamer supports verbose assembly at + /// all. + virtual bool isVerboseAsm() const { return false; } /// AddComment - Add a comment that can be emitted to the generated .s /// file if applicable as a QoI issue to make the output of the compiler @@ -129,6 +133,14 @@ namespace llvm { /// @param DescValue - The value to set into the n_desc field. virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0; + + /// EmitELFSize - Emit an ELF .size directive. + /// + /// This corresponds to an assembler statement such as: + /// .size symbol, expression + /// + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0; + /// EmitCommonSymbol - Emit a common symbol. /// /// @param Symbol - The common symbol to emit. @@ -180,6 +192,13 @@ namespace llvm { /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace); + /// EmitGPRel32Value - Emit the expression @param Value into the output as a + /// gprel32 (32-bit GP relative) value. + /// + /// This is used to implement assembler directives such as .gprel32 on + /// targets that support them. + virtual void EmitGPRel32Value(const MCExpr *Value) = 0; + /// 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, @@ -225,6 +244,15 @@ namespace llvm { unsigned char Value = 0) = 0; /// @} + + /// EmitFileDirective - Switch to a new logical file. This is used to + /// implement the '.file "foo.c"' assembler directive. + virtual void EmitFileDirective(StringRef Filename) = 0; + + /// EmitDwarfFileDirective - Associate a filename with a specified logical + /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler + /// directive. + virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0; /// EmitInstruction - Emit the given @param Instruction into the current /// section. @@ -241,11 +269,21 @@ namespace llvm { /// createAsmStreamer - Create a machine code streamer which will print out /// assembly for the native target, suitable for compiling with a native /// assembler. + /// + /// \param InstPrint - If given, the instruction printer to use. If not given + /// the MCInst representation will be printed. + /// + /// \param CE - If given, a code emitter to use to show the instruction + /// encoding inline with the assembly. + /// + /// \param ShowInst - Whether to show the MCInst representation inline with + /// the assembly. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, const MCAsmInfo &MAI, bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *InstPrint = 0, - MCCodeEmitter *CE = 0); + MCCodeEmitter *CE = 0, + bool ShowInst = false); // FIXME: These two may end up getting rolled into a single // createObjectStreamer interface, which implements the assembler backend, and @@ -254,7 +292,7 @@ namespace llvm { /// createMachOStream - Create a machine code streamer which will generative /// Mach-O format object files. MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS, - MCCodeEmitter *CE = 0); + MCCodeEmitter *CE); /// createELFStreamer - Create a machine code streamer which will generative /// ELF format object files. diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index e770604..d5c4d95 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -89,7 +89,7 @@ namespace llvm { return !isDefined(); } - /// isAbsolute - Check if this this is an absolute symbol. + /// isAbsolute - Check if this is an absolute symbol. bool isAbsolute() const { return Section == AbsolutePseudoSection; } diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index f1e7a22..4e459bf 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -112,7 +112,7 @@ protected: bool isFunctionLocal); static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, - FunctionLocalness FL); + FunctionLocalness FL, bool Insert = true); public: // Constructors and destructors. static MDNode *get(LLVMContext &Context, Value *const *Vals, @@ -121,6 +121,9 @@ public: // from isFunctionLocal argument, not by analyzing Vals. static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals, unsigned NumVals, bool isFunctionLocal); + + static MDNode *getIfExists(LLVMContext &Context, Value *const *Vals, + unsigned NumVals); /// getOperand - Return specified operand. Value *getOperand(unsigned i) const; diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 3c8055d..901fada 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -19,12 +19,14 @@ #include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" #include "llvm/Metadata.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/System/DataTypes.h" #include <vector> namespace llvm { class FunctionType; +class GVMaterializer; class LLVMContext; class MDSymbolTable; @@ -145,6 +147,7 @@ private: std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values TypeSymbolTable *TypeSymTab; ///< Symbol table for types + OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues std::string ModuleID; ///< Human readable identifier for the module std::string TargetTriple; ///< Platform target triple Module compiled on std::string DataLayout; ///< Target data description @@ -211,11 +214,13 @@ public: /// Set the module-scope inline assembly blocks. void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; } - /// Append to the module-scope inline assembly blocks, automatically - /// appending a newline to the end. + /// Append to the module-scope inline assembly blocks, automatically inserting + /// a separating newline if necessary. void appendModuleInlineAsm(StringRef Asm) { + if (!GlobalScopeAsm.empty() && + GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n') + GlobalScopeAsm += '\n'; GlobalScopeAsm += Asm; - GlobalScopeAsm += '\n'; } /// @} @@ -345,6 +350,50 @@ public: const Type *getTypeByName(StringRef Name) const; /// @} +/// @name Materialization +/// @{ + + /// setMaterializer - Sets the GVMaterializer to GVM. This module must not + /// yet have a Materializer. To reset the materializer for a module that + /// already has one, call MaterializeAllPermanently first. Destroying this + /// module will destroy its materializer without materializing any more + /// GlobalValues. Without destroying the Module, there is no way to detach or + /// destroy a materializer without materializing all the GVs it controls, to + /// avoid leaving orphan unmaterialized GVs. + void setMaterializer(GVMaterializer *GVM); + /// getMaterializer - Retrieves the GVMaterializer, if any, for this Module. + GVMaterializer *getMaterializer() const { return Materializer.get(); } + + /// isMaterializable - True if the definition of GV has yet to be materialized + /// from the GVMaterializer. + bool isMaterializable(const GlobalValue *GV) const; + /// isDematerializable - Returns true if this GV was loaded from this Module's + /// GVMaterializer and the GVMaterializer knows how to dematerialize the GV. + bool isDematerializable(const GlobalValue *GV) const; + + /// Materialize - Make sure the GlobalValue is fully read. If the module is + /// corrupt, this returns true and fills in the optional string with + /// information about the problem. If successful, this returns false. + bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0); + /// Dematerialize - If the GlobalValue is read in, and if the GVMaterializer + /// supports it, release the memory for the function, and set it up to be + /// materialized lazily. If !isDematerializable(), this method is a noop. + void Dematerialize(GlobalValue *GV); + + /// MaterializeAll - Make sure all GlobalValues in this Module are fully read. + /// If the module is corrupt, this returns true and fills in the optional + /// string with information about the problem. If successful, this returns + /// false. + bool MaterializeAll(std::string *ErrInfo = 0); + + /// MaterializeAllPermanently - Make sure all GlobalValues in this Module are + /// fully read and clear the Materializer. If the module is corrupt, this + /// returns true, fills in the optional string with information about the + /// problem, and DOES NOT clear the old Materializer. If successful, this + /// returns false. + bool MaterializeAllPermanently(std::string *ErrInfo = 0); + +/// @} /// @name Direct access to the globals list, functions list, and symbol table /// @{ diff --git a/include/llvm/ModuleProvider.h b/include/llvm/ModuleProvider.h deleted file mode 100644 index 8a0a20c..0000000 --- a/include/llvm/ModuleProvider.h +++ /dev/null @@ -1,88 +0,0 @@ -//===-- llvm/ModuleProvider.h - Interface for module providers --*- 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 an abstract interface for loading a module from some -// place. This interface allows incremental or random access loading of -// functions from the file. This is useful for applications like JIT compilers -// or interprocedural optimizers that do not need the entire program in memory -// at the same time. -// -//===----------------------------------------------------------------------===// - -#ifndef MODULEPROVIDER_H -#define MODULEPROVIDER_H - -#include <string> - -namespace llvm { - -class Function; -class Module; - -class ModuleProvider { -protected: - Module *TheModule; - ModuleProvider(); - -public: - virtual ~ModuleProvider(); - - /// getModule - returns the module this provider is encapsulating. - /// - Module* getModule() { return TheModule; } - - /// materializeFunction - make sure the given function is fully read. If the - /// module is corrupt, this returns true and fills in the optional string - /// with information about the problem. If successful, this returns false. - /// - virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) = 0; - - /// dematerializeFunction - If the given function is read in, and if the - /// module provider supports it, release the memory for the function, and set - /// it up to be materialized lazily. If the provider doesn't support this - /// capability, this method is a noop. - /// - virtual void dematerializeFunction(Function *) {} - - /// materializeModule - make sure the entire Module has been completely read. - /// On error, return null and fill in the error string if specified. - /// - virtual Module* materializeModule(std::string *ErrInfo = 0) = 0; - - /// releaseModule - no longer delete the Module* when provider is destroyed. - /// On error, return null and fill in the error string if specified. - /// - virtual Module* releaseModule(std::string *ErrInfo = 0) { - // Since we're losing control of this Module, we must hand it back complete - if (!materializeModule(ErrInfo)) - return 0; - Module *tempM = TheModule; - TheModule = 0; - return tempM; - } -}; - - -/// ExistingModuleProvider - Allow conversion from a fully materialized Module -/// into a ModuleProvider, allowing code that expects a ModuleProvider to work -/// if we just have a Module. Note that the ModuleProvider takes ownership of -/// the Module specified. -struct ExistingModuleProvider : public ModuleProvider { - explicit ExistingModuleProvider(Module *M) { - TheModule = M; - } - bool materializeFunction(Function *, std::string * = 0) { - return false; - } - Module* materializeModule(std::string * = 0) { return TheModule; } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index ab08afb..e822a0f 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -56,11 +56,11 @@ typedef const PassInfo* AnalysisID; /// Ordering of pass manager types is important here. enum PassManagerType { PMT_Unknown = 0, - PMT_ModulePassManager = 1, /// MPPassManager - PMT_CallGraphPassManager, /// CGPassManager - PMT_FunctionPassManager, /// FPPassManager - PMT_LoopPassManager, /// LPPassManager - PMT_BasicBlockPassManager, /// BBPassManager + PMT_ModulePassManager = 1, ///< MPPassManager + PMT_CallGraphPassManager, ///< CGPassManager + PMT_FunctionPassManager, ///< FPPassManager + PMT_LoopPassManager, ///< LPPassManager + PMT_BasicBlockPassManager, ///< BBPassManager PMT_Last }; diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h index a6703fd..4d91163 100644 --- a/include/llvm/PassManager.h +++ b/include/llvm/PassManager.h @@ -24,7 +24,6 @@ namespace llvm { class Pass; class ModulePass; class Module; -class ModuleProvider; class PassManagerImpl; class FunctionPassManagerImpl; @@ -71,8 +70,8 @@ private: class FunctionPassManager : public PassManagerBase { public: /// FunctionPassManager ctor - This initializes the pass manager. It needs, - /// but does not take ownership of, the specified module provider. - explicit FunctionPassManager(ModuleProvider *P); + /// but does not take ownership of, the specified Module. + explicit FunctionPassManager(Module *M); ~FunctionPassManager(); /// add - Add a pass to the queue of passes to run. This passes @@ -96,15 +95,9 @@ public: /// bool doFinalization(); - /// getModuleProvider - Return the module provider that this passmanager is - /// currently using. This is the module provider that it uses when a function - /// is optimized that is non-resident in the module. - ModuleProvider *getModuleProvider() const { return MP; } - void setModuleProvider(ModuleProvider *NewMP) { MP = NewMP; } - private: FunctionPassManagerImpl *FPM; - ModuleProvider *MP; + Module *M; }; } // End llvm namespace diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index 443a9e0..d5685c6 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -394,8 +394,8 @@ private: const AnalysisUsage::VectorType &Set) const; // Set of available Analysis. This information is used while scheduling - // pass. If a pass requires an analysis which is not not available then - // equired analysis pass is scheduled to run before the pass itself is + // 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; diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 37a7c3b..17bcb59 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -180,8 +180,9 @@ template<class To, class From, class SimpleFrom> struct cast_convert_val { template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { // This _is_ a simple type, just cast it. static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { - return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>( - const_cast<FromTy&>(Val)); + typename cast_retty<To, FromTy>::ret_type Res2 + = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); + return Res2; } }; diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 7f8b10c..3ee2313 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -1168,7 +1168,7 @@ class bits_storage<DataType, bool> { template<class T> static unsigned Bit(const T &V) { - unsigned BitPos = reinterpret_cast<unsigned>(V); + unsigned BitPos = (unsigned)V; assert(BitPos < sizeof(unsigned) * CHAR_BIT && "enum exceeds width of bit vector!"); return 1 << BitPos; diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index 1339e9f..ea6c5fd 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -39,6 +39,9 @@ public: Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getNSWAdd(LHS, RHS); } + Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNUWAdd(LHS, RHS); + } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFAdd(LHS, RHS); } @@ -48,6 +51,9 @@ public: Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getNSWSub(LHS, RHS); } + Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNUWSub(LHS, RHS); + } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFSub(LHS, RHS); } @@ -57,6 +63,9 @@ public: Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getNSWMul(LHS, RHS); } + Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const { + return ConstantExpr::getNUWMul(LHS, RHS); + } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return ConstantExpr::getFMul(LHS, RHS); } @@ -115,6 +124,9 @@ public: Constant *CreateNSWNeg(Constant *C) const { return ConstantExpr::getNSWNeg(C); } + Constant *CreateNUWNeg(Constant *C) const { + return ConstantExpr::getNUWNeg(C); + } Constant *CreateFNeg(Constant *C) const { return ConstantExpr::getFNeg(C); } diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index bfccc52..5f591d4 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -580,7 +580,6 @@ const char *MacinfoString(unsigned Encoding); /// CallFrameString - Return the string for the specified call frame instruction /// encodings. const char *CallFrameString(unsigned Encoding); - } // End of namespace dwarf } // End of namespace llvm diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index af546f0..58a1885 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/FormattedStream.h - Formatted streams ------*- C++ -*-===// +//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -119,7 +119,7 @@ namespace llvm /// space. /// /// \param NewCol - The column to move to. - void PadToColumn(unsigned NewCol); + formatted_raw_ostream &PadToColumn(unsigned NewCol); private: void releaseStream() { diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index eabf6ad..c8aef9c 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -94,7 +94,7 @@ public: //===--------------------------------------------------------------------===// /// CreateGlobalString - Make a new global variable with an initializer that - /// has array of i8 type filled in the the nul terminated string value + /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable /// created. Value *CreateGlobalString(const char *Str = "", const Twine &Name = ""); @@ -318,6 +318,12 @@ public: return Folder.CreateNSWAdd(LC, RC); return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name); } + Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNUWAdd(LC, RC); + return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name); + } Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) @@ -336,6 +342,12 @@ public: return Folder.CreateNSWSub(LC, RC); return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name); } + Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNUWSub(LC, RC); + return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name); + } Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) @@ -354,6 +366,12 @@ public: return Folder.CreateNSWMul(LC, RC); return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name); } + Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast<Constant>(LHS)) + if (Constant *RC = dyn_cast<Constant>(RHS)) + return Folder.CreateNUWMul(LC, RC); + return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name); + } Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) @@ -484,6 +502,11 @@ public: return Folder.CreateNSWNeg(VC); return Insert(BinaryOperator::CreateNSWNeg(V), Name); } + Value *CreateNUWNeg(Value *V, const Twine &Name = "") { + if (Constant *VC = dyn_cast<Constant>(V)) + return Folder.CreateNUWNeg(VC); + return Insert(BinaryOperator::CreateNUWNeg(V), Name); + } Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) return Folder.CreateFNeg(VC); diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h index e7780b0..66314e0 100644 --- a/include/llvm/Support/IRReader.h +++ b/include/llvm/Support/IRReader.h @@ -23,44 +23,39 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" -#include "llvm/ModuleProvider.h" namespace llvm { - /// If the given MemoryBuffer holds a bitcode image, return a ModuleProvider - /// for it which does lazy deserialization of function bodies. Otherwise, - /// attempt to parse it as LLVM Assembly and return a fully populated - /// ModuleProvider. This function *always* takes ownership of the given - /// MemoryBuffer. - inline ModuleProvider *getIRModuleProvider(MemoryBuffer *Buffer, - SMDiagnostic &Err, - LLVMContext &Context) { + /// 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; - ModuleProvider *MP = getBitcodeModuleProvider(Buffer, Context, &ErrMsg); - if (MP == 0) { + Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg); + if (M == 0) { Err = SMDiagnostic(Buffer->getBufferIdentifier(), -1, -1, ErrMsg, ""); // ParseBitcodeFile does not take ownership of the Buffer in the // case of an error. delete Buffer; } - return MP; + return M; } - Module *M = ParseAssembly(Buffer, 0, Err, Context); - if (M == 0) - return 0; - return new ExistingModuleProvider(M); + return ParseAssembly(Buffer, 0, Err, Context); } - /// If the given file holds a bitcode image, return a ModuleProvider + /// 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 - /// ModuleProvider. - inline ModuleProvider *getIRFileModuleProvider(const std::string &Filename, - SMDiagnostic &Err, - LLVMContext &Context) { + /// Module. + inline Module *getLazyIRFileModule(const std::string &Filename, + SMDiagnostic &Err, + LLVMContext &Context) { std::string ErrMsg; MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); if (F == 0) { @@ -69,7 +64,7 @@ namespace llvm { return 0; } - return getIRModuleProvider(F, Err, Context); + return getLazyIRModule(F, Err, Context); } /// If the given MemoryBuffer holds a bitcode image, return a Module diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h new file mode 100644 index 0000000..e6fccfc --- /dev/null +++ b/include/llvm/Support/MachO.h @@ -0,0 +1,56 @@ +//===-- llvm/Support/MachO.h - The MachO file format ------------*- 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 manifest constants for the MachO object file format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MACHO_H +#define LLVM_SUPPORT_MACHO_H + +// NOTE: The enums in this file are intentially named to be different than those +// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts +// with those macros. +namespace llvm { + namespace MachO { + // Enums from <mach/machine.h> + enum { + // Capability bits used in the definition of cpu_type. + CPUArchMask = 0xff000000, // Mask for architecture bits + CPUArchABI64 = 0x01000000, // 64 bit ABI + + // Constants for the cputype field. + CPUTypeI386 = 7, + CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64, + CPUTypeARM = 12, + CPUTypeSPARC = 14, + CPUTypePowerPC = 18, + CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64, + + + // Constants for the cpusubtype field. + + // X86 + CPUSubType_I386_ALL = 3, + CPUSubType_X86_64_ALL = 3, + + // ARM + CPUSubType_ARM_ALL = 0, + CPUSubType_ARM_V4T = 5, + CPUSubType_ARM_V6 = 6, + + // PowerPC + CPUSubType_POWERPC_ALL = 0, + + CPUSubType_SPARC_ALL = 0 + }; + } // end namespace MachO +} // end namespace llvm + +#endif diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 78a9035..01256e1 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -45,6 +45,9 @@ public: Value *CreateNSWAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWAdd(LHS, RHS); } + Value *CreateNUWAdd(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWAdd(LHS, RHS); + } Value *CreateFAdd(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFAdd(LHS, RHS); } @@ -54,6 +57,9 @@ public: Value *CreateNSWSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWSub(LHS, RHS); } + Value *CreateNUWSub(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWSub(LHS, RHS); + } Value *CreateFSub(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFSub(LHS, RHS); } @@ -63,6 +69,9 @@ public: Value *CreateNSWMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateNSWMul(LHS, RHS); } + Value *CreateNUWMul(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNUWMul(LHS, RHS); + } Value *CreateFMul(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFMul(LHS, RHS); } @@ -121,6 +130,9 @@ public: Value *CreateNSWNeg(Constant *C) const { return BinaryOperator::CreateNSWNeg(C); } + Value *CreateNUWNeg(Constant *C) const { + return BinaryOperator::CreateNUWNeg(C); + } Value *CreateNot(Constant *C) const { return BinaryOperator::CreateNot(C); } diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 23daad9..f02bc34 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -423,7 +423,7 @@ m_Select(const Cond &C, const LHS &L, const RHS &R) { } /// m_SelectCst - This matches a select of two constants, e.g.: -/// m_SelectCst(m_Value(V), -1, 0) +/// m_SelectCst<-1, 0>(m_Value(V)) template<int64_t L, int64_t R, typename Cond> inline SelectClass_match<Cond, constantint_ty<L>, constantint_ty<R> > m_SelectCst(const Cond &C) { @@ -466,6 +466,20 @@ inline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) { return CastClass_match<OpTy, Instruction::Trunc>(Op); } + +/// m_SExt +template<typename OpTy> +inline CastClass_match<OpTy, Instruction::SExt> +m_SExt(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::SExt>(Op); +} + +/// m_ZExt +template<typename OpTy> +inline CastClass_match<OpTy, Instruction::ZExt> +m_ZExt(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::ZExt>(Op); +} //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 5433a00..fd56b16 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -34,33 +34,33 @@ class SourceMgr { struct SrcBuffer { /// Buffer - The memory buffer for the file. MemoryBuffer *Buffer; - + /// IncludeLoc - This is the location of the parent include, or null if at /// the top level. SMLoc IncludeLoc; }; - + /// Buffers - This is all of the buffers that we are reading from. std::vector<SrcBuffer> Buffers; - + // IncludeDirectories - This is the list of directories we should search for // include files in. std::vector<std::string> IncludeDirectories; - + /// LineNoCache - This is a cache for line number queries, its implementation /// is really private to SourceMgr.cpp. mutable void *LineNoCache; - + SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT void operator=(const SourceMgr&); // DO NOT IMPLEMENT public: SourceMgr() : LineNoCache(0) {} ~SourceMgr(); - + void setIncludeDirs(const std::vector<std::string> &Dirs) { IncludeDirectories = Dirs; } - + const SrcBuffer &getBufferInfo(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i]; @@ -70,12 +70,12 @@ public: assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i].Buffer; } - + SMLoc getParentIncludeLoc(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i].IncludeLoc; } - + unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { SrcBuffer NB; NB.Buffer = F; @@ -83,20 +83,20 @@ public: Buffers.push_back(NB); return Buffers.size()-1; } - + /// AddIncludeFile - Search for a file with the specified name in the current /// directory or in one of the IncludeDirs. If no file is found, this returns /// ~0, otherwise it returns the buffer ID of the stacked file. unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc); - + /// FindBufferContainingLoc - Return the ID of the buffer containing the /// specified location, returning -1 if not found. int FindBufferContainingLoc(SMLoc Loc) const; - + /// FindLineNumber - Find the line number for the specified location in the /// specified file. This is not a fast method. unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const; - + /// PrintMessage - Emit a message about the specified location with the /// specified string. /// @@ -105,8 +105,8 @@ public: /// @param ShowLine - Should the diagnostic show the source line. void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type, bool ShowLine = true) const; - - + + /// GetMessage - Return an SMDiagnostic at the specified location with the /// specified string. /// @@ -116,13 +116,13 @@ public: SMDiagnostic GetMessage(SMLoc Loc, const std::string &Msg, const char *Type, bool ShowLine = true) const; - - + + private: void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const; }; - + /// SMDiagnostic - Instances of this class encapsulate one diagnostic report, /// allowing printing to a raw_ostream as a caret diagnostic. class SMDiagnostic { @@ -132,16 +132,16 @@ class SMDiagnostic { unsigned ShowLine : 1; public: - SMDiagnostic() : LineNo(0), ColumnNo(0) {} + SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {} SMDiagnostic(const std::string &FN, int Line, int Col, const std::string &Msg, const std::string &LineStr, bool showline = true) : Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg), LineContents(LineStr), ShowLine(showline) {} - void Print(const char *ProgName, raw_ostream &S); + void Print(const char *ProgName, raw_ostream &S) const; }; - + } // end llvm namespace #endif diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 59dd29b..384c493 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -52,6 +52,9 @@ public: Constant *CreateNSWAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getNSWAdd(LHS, RHS)); } + Constant *CreateNUWAdd(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNUWAdd(LHS, RHS)); + } Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFAdd(LHS, RHS)); } @@ -61,6 +64,9 @@ public: Constant *CreateNSWSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getNSWSub(LHS, RHS)); } + Constant *CreateNUWSub(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNUWSub(LHS, RHS)); + } Constant *CreateFSub(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFSub(LHS, RHS)); } @@ -70,6 +76,9 @@ public: Constant *CreateNSWMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getNSWMul(LHS, RHS)); } + Constant *CreateNUWMul(Constant *LHS, Constant *RHS) const { + return Fold(ConstantExpr::getNUWMul(LHS, RHS)); + } Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFMul(LHS, RHS)); } @@ -128,6 +137,9 @@ public: Constant *CreateNSWNeg(Constant *C) const { return Fold(ConstantExpr::getNSWNeg(C)); } + Constant *CreateNUWNeg(Constant *C) const { + return Fold(ConstantExpr::getNUWNeg(C)); + } Constant *CreateFNeg(Constant *C) const { return Fold(ConstantExpr::getFNeg(C)); } diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index fb22e3f..270ac52 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -231,6 +231,12 @@ public: /// we special case it. template<> class TypeBuilder<void*, false> : public TypeBuilder<types::i<8>*, false> {}; +template<> class TypeBuilder<const void*, false> + : public TypeBuilder<types::i<8>*, false> {}; +template<> class TypeBuilder<volatile void*, false> + : public TypeBuilder<types::i<8>*, false> {}; +template<> class TypeBuilder<const volatile void*, false> + : public TypeBuilder<types::i<8>*, false> {}; template<typename R, bool cross> class TypeBuilder<R(), cross> { public: diff --git a/include/llvm/System/DynamicLibrary.h b/include/llvm/System/DynamicLibrary.h index ac58407..745b8f8 100644 --- a/include/llvm/System/DynamicLibrary.h +++ b/include/llvm/System/DynamicLibrary.h @@ -23,7 +23,7 @@ namespace sys { /// might be known as shared libraries, shared objects, dynamic shared /// objects, or dynamic link libraries. Regardless of the terminology or the /// operating system interface, this class provides a portable interface that - /// allows dynamic libraries to be loaded and and searched for externally + /// allows dynamic libraries to be loaded and searched for externally /// defined symbols. This is typically used to provide "plug-in" support. /// It also allows for symbols to be defined which don't live in any library, /// but rather the main program itself, useful on Windows where the main diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h index bdfb9aa..1be27b2 100644 --- a/include/llvm/System/Path.h +++ b/include/llvm/System/Path.h @@ -28,7 +28,7 @@ namespace sys { /// platform independent and eliminates many of the unix-specific fields. /// However, to support llvm-ar, the mode, user, and group fields are /// retained. These pertain to unix security and may not have a meaningful - /// value on non-Unix platforms. However, the other fields fields should + /// value on non-Unix platforms. However, the other fields should /// always be applicable on all platforms. The structure is filled in by /// the PathWithStatus class. /// @brief File status structure diff --git a/include/llvm/System/Program.h b/include/llvm/System/Program.h index 6799562..69ce478 100644 --- a/include/llvm/System/Program.h +++ b/include/llvm/System/Program.h @@ -120,10 +120,12 @@ namespace sys { /// @brief Construct a Program by finding it by name. static Path FindProgramByName(const std::string& name); - // These methods change the specified standard stream (stdin or stdout) to - // binary mode. They return true if an error occurred + // These methods change the specified standard stream (stdin, + // stdout, or stderr) to binary mode. They return true if an error + // occurred static bool ChangeStdinToBinary(); static bool ChangeStdoutToBinary(); + static bool ChangeStderrToBinary(); /// A convenience function equivalent to Program prg; prg.Execute(..); /// prg.Wait(..); diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h index 04de4e9..45cbf9d 100644 --- a/include/llvm/Target/Mangler.h +++ b/include/llvm/Target/Mangler.h @@ -1,4 +1,4 @@ -//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===// +//===-- llvm/Target/Mangler.h - Self-contained name mangler ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 354e743..9a117df 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -376,7 +376,7 @@ class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops> // InstrInfo - This class should only be instantiated once to provide parameters -// which are global to the the target machine. +// which are global to the target machine. // class InstrInfo { // If the target wants to associate some target-specific information with each @@ -399,19 +399,19 @@ def PHI : Instruction { let OutOperandList = (ops); let InOperandList = (ops variable_ops); let AsmString = "PHINODE"; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; } def INLINEASM : Instruction { let OutOperandList = (ops); let InOperandList = (ops variable_ops); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; } def DBG_LABEL : Instruction { let OutOperandList = (ops); let InOperandList = (ops i32imm:$id); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -419,7 +419,7 @@ def EH_LABEL : Instruction { let OutOperandList = (ops); let InOperandList = (ops i32imm:$id); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -427,7 +427,7 @@ def GC_LABEL : Instruction { let OutOperandList = (ops); let InOperandList = (ops i32imm:$id); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -435,21 +435,21 @@ def KILL : Instruction { let OutOperandList = (ops); let InOperandList = (ops variable_ops); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def EXTRACT_SUBREG : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops unknown:$supersrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def INSERT_SUBREG : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let Constraints = "$supersrc = $dst"; } @@ -457,7 +457,7 @@ def IMPLICIT_DEF : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let isReMaterializable = 1; let isAsCheapAsAMove = 1; @@ -466,22 +466,22 @@ def SUBREG_TO_REG : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def COPY_TO_REGCLASS : Instruction { let OutOperandList = (ops unknown:$dst); let InOperandList = (ops unknown:$src, i32imm:$regclass); let AsmString = ""; - let Namespace = "TargetInstrInfo"; + let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let isAsCheapAsAMove = 1; } -def DEBUG_VALUE : Instruction { +def DBG_VALUE : Instruction { let OutOperandList = (ops); let InOperandList = (ops variable_ops); - let AsmString = "DEBUG_VALUE"; - let Namespace = "TargetInstrInfo"; + let AsmString = "DBG_VALUE"; + let Namespace = "TargetOpcode"; let isAsCheapAsAMove = 1; } } diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/Target/TargetAsmLexer.h index daba1ba..9fcf449 100644 --- a/include/llvm/Target/TargetAsmLexer.h +++ b/include/llvm/Target/TargetAsmLexer.h @@ -38,12 +38,22 @@ protected: // Can only create subclasses. /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + MCAsmLexer *Lexer; public: virtual ~TargetAsmLexer(); const Target &getTarget() const { return TheTarget; } + /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg 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(); diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 2e63188..cc88dae 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -224,6 +224,11 @@ public: /// getABITypeAlignment - Return the minimum ABI-required alignment for the /// specified type. unsigned char getABITypeAlignment(const Type *Ty) const; + + /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for + /// an integer type of the specified bitwidth. + unsigned char getABIIntegerTypeAlignment(unsigned BitWidth) const; + /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment /// for the specified type when it is part of a call frame. diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 7144fe0..d95e4e8 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -45,55 +45,6 @@ public: TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes); virtual ~TargetInstrInfo(); - // Invariant opcodes: All instruction sets have these as their low opcodes. - enum { - PHI = 0, - INLINEASM = 1, - DBG_LABEL = 2, - EH_LABEL = 3, - GC_LABEL = 4, - - /// KILL - This instruction is a noop that is used only to adjust the liveness - /// of registers. This can be useful when dealing with sub-registers. - KILL = 5, - - /// EXTRACT_SUBREG - This instruction takes two operands: a register - /// that has subregisters, and a subregister index. It returns the - /// extracted subregister value. This is commonly used to implement - /// truncation operations on target architectures which support it. - EXTRACT_SUBREG = 6, - - /// INSERT_SUBREG - This instruction takes three operands: a register - /// that has subregisters, a register providing an insert value, and a - /// subregister index. It returns the value of the first register with - /// the value of the second register inserted. The first register is - /// often defined by an IMPLICIT_DEF, as is commonly used to implement - /// anyext operations on target architectures which support it. - INSERT_SUBREG = 7, - - /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. - IMPLICIT_DEF = 8, - - /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except - /// that the first operand is an immediate integer constant. This constant - /// is often zero, as is commonly used to implement zext operations on - /// target architectures which support it, such as with x86-64 (with - /// zext from i32 to i64 via implicit zero-extension). - SUBREG_TO_REG = 9, - - /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain - /// register-to-register copy into a specific register class. This is only - /// used between instruction selection and MachineInstr creation, before - /// virtual registers have been created for all the instructions, and it's - /// only needed in cases where the register classes implied by the - /// instructions are insufficient. The actual MachineInstrs to perform - /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. - COPY_TO_REGCLASS = 10, - - // DEBUG_VALUE - a mapping of the llvm.dbg.value intrinsic - DEBUG_VALUE = 11 - }; - unsigned getNumOpcodes() const { return NumOpcodes; } /// get - Return the machine instruction descriptor that corresponds to the @@ -109,7 +60,7 @@ public: /// that aren't always available. bool isTriviallyReMaterializable(const MachineInstr *MI, AliasAnalysis *AA = 0) const { - return MI->getOpcode() == IMPLICIT_DEF || + return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF || (MI->getDesc().isRematerializable() && (isReallyTriviallyReMaterializable(MI, AA) || isReallyTriviallyReMaterializableGeneric(MI, AA))); @@ -167,12 +118,12 @@ public: SrcReg == DstReg) return true; - if (MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG && + if (MI.getOpcode() == TargetOpcode::EXTRACT_SUBREG && MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) return true; - if ((MI.getOpcode() == TargetInstrInfo::INSERT_SUBREG || - MI.getOpcode() == TargetInstrInfo::SUBREG_TO_REG) && + if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG || + MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) && MI.getOperand(0).getReg() == MI.getOperand(2).getReg()) return true; return false; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 15da845..c6ac89a 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -46,7 +46,10 @@ namespace llvm { class MachineFunction; class MachineFrameInfo; class MachineInstr; + class MachineJumpTableInfo; class MachineModuleInfo; + class MCContext; + class MCExpr; class DwarfWriter; class SDNode; class SDValue; @@ -115,10 +118,6 @@ public: MVT getPointerTy() const { return PointerTy; } MVT getShiftAmountTy() const { return ShiftAmountTy; } - /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC - /// codegen. - bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; } - /// isSelectExpensive - Return true if the select operation is expensive for /// this target. bool isSelectExpensive() const { return SelectIsExpensive; } @@ -347,6 +346,11 @@ public: return true; } + /// canOpTrap - Returns true if the operation can trap for the value type. + /// VT must be a legal type. By default, we optimistically assume most + /// operations don't trap except for divide and remainder. + virtual bool canOpTrap(unsigned Op, EVT VT) const; + /// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is /// used by Targets can use this to indicate if there is a suitable /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant @@ -752,11 +756,31 @@ public: 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 { + assert(0 && "Need to implement this hook if target has custom JTIs"); + return 0; + } + /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC /// jumptable. virtual SDValue getPICJumpTableRelocBase(SDValue Table, - SelectionDAG &DAG) const; - + 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. @@ -886,10 +910,6 @@ public: // protected: - /// setUsesGlobalOffsetTable - Specify that this target does or doesn't use a - /// GOT for PC-relative code. - void setUsesGlobalOffsetTable(bool V) { UsesGlobalOffsetTable = V; } - /// setShiftAmountType - Describe the type that should be used for shift /// amounts. This type defaults to the pointer type. void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; } @@ -1152,15 +1172,9 @@ public: /// 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. - /// - /// The isTailCall flag here is normative. If it is true, the - /// implementation must emit a tail call. The - /// IsEligibleForTailCallOptimization hook should be used to catch - /// cases that cannot be handled. - /// virtual SDValue LowerCall(SDValue Chain, SDValue Callee, - CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + CallingConv::ID CallConv, bool isVarArg, bool &isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, @@ -1286,19 +1300,6 @@ public: assert(0 && "ReplaceNodeResults not implemented for this target!"); } - /// IsEligibleForTailCallOptimization - Check whether the call is eligible for - /// tail call optimization. Targets which want to do tail call optimization - /// should override this function. - virtual bool - IsEligibleForTailCallOptimization(SDValue Callee, - CallingConv::ID CalleeCC, - bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - SelectionDAG& DAG) const { - // Conservative default: no calls are eligible. - return false; - } - /// getTargetNodeName() - This method returns the name of a target specific /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; @@ -1572,10 +1573,6 @@ private: /// bool IsLittleEndian; - /// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen. - /// - bool UsesGlobalOffsetTable; - /// SelectIsExpensive - Tells the code generator not to expand operations /// into sequences that use the select operations if possible. bool SelectIsExpensive; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index d3e5cf2..42d88a0 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -25,6 +25,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSectionMachO; + class MCSymbol; class MCContext; class GlobalValue; class TargetMachine; @@ -175,187 +176,26 @@ public: return 0; } - /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a - /// pc-relative reference to the specified global variable from exception - /// handling information. In addition to the symbol, this returns - /// by-reference: - /// - /// IsIndirect - True if the returned symbol is actually a stub that contains - /// the address of the symbol, false if the symbol is the global itself. - /// - /// IsPCRel - True if the symbol reference is already pc-relative, false if - /// the caller needs to subtract off the address of the reference from the - /// symbol. + /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference + /// to the specified global variable from exception handling information. /// virtual const MCExpr * getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, - bool &IsIndirect, bool &IsPCRel) const; - -protected: - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; -}; - - - + MachineModuleInfo *MMI, unsigned Encoding) const; -class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { - mutable void *UniquingMap; -protected: - /// TLSDataSection - Section directive for Thread Local data. - /// - const MCSection *TLSDataSection; // Defaults to ".tdata". - - /// TLSBSSSection - Section directive for Thread Local uninitialized data. - /// Null if this target doesn't support a BSS section. - /// - const MCSection *TLSBSSSection; // Defaults to ".tbss". - - const MCSection *DataRelSection; - const MCSection *DataRelLocalSection; - const MCSection *DataRelROSection; - const MCSection *DataRelROLocalSection; - - const MCSection *MergeableConst4Section; - const MCSection *MergeableConst8Section; - const MCSection *MergeableConst16Section; - -protected: - const MCSection *getELFSection(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind, - bool IsExplicit = false) const; -public: - TargetLoweringObjectFileELF() : UniquingMap(0) {} - ~TargetLoweringObjectFileELF(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - /// getSectionForConstant - Given a constant with the SectionKind, return a - /// section that it should be placed in. - virtual const MCSection *getSectionForConstant(SectionKind Kind) const; - - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; -}; - - - -class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { - mutable void *UniquingMap; - - const MCSection *CStringSection; - const MCSection *UStringSection; - const MCSection *TextCoalSection; - const MCSection *ConstTextCoalSection; - const MCSection *ConstDataCoalSection; - const MCSection *ConstDataSection; - const MCSection *DataCoalSection; - const MCSection *DataCommonSection; - const MCSection *DataBSSSection; - const MCSection *FourByteConstantSection; - const MCSection *EightByteConstantSection; - const MCSection *SixteenByteConstantSection; - - const MCSection *LazySymbolPointerSection; - const MCSection *NonLazySymbolPointerSection; -public: - TargetLoweringObjectFileMachO() : UniquingMap(0) {} - ~TargetLoweringObjectFileMachO(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection *getSectionForConstant(SectionKind Kind) const; - - /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively - /// decide not to emit the UsedDirective for some symbols in llvm.used. - /// FIXME: REMOVE this (rdar://7071300) - virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, - Mangler *) const; - - /// getMachOSection - Return the MCSection for the specified mach-o section. - /// This requires the operands to be valid. - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - SectionKind K) const { - return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); - } - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind K) const; - - /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak - /// text symbols into. - const MCSection *getTextCoalSection() const { - return TextCoalSection; - } - - /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section - /// we put weak read-only symbols into. - const MCSection *getConstTextCoalSection() const { - return ConstTextCoalSection; - } - - /// getLazySymbolPointerSection - Return the section corresponding to - /// the .lazy_symbol_pointer directive. - const MCSection *getLazySymbolPointerSection() const { - return LazySymbolPointerSection; - } - - /// getNonLazySymbolPointerSection - Return the section corresponding to - /// the .non_lazy_symbol_pointer directive. - const MCSection *getNonLazySymbolPointerSection() const { - return NonLazySymbolPointerSection; - } - - /// getSymbolForDwarfGlobalReference - The mach-o version of this method - /// defaults to returning a stub reference. virtual const MCExpr * - getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, - bool &IsIndirect, bool &IsPCRel) const; -}; + getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI, + unsigned Encoding) const; + virtual unsigned getPersonalityEncoding() const; + virtual unsigned getLSDAEncoding() const; + virtual unsigned getFDEEncoding() const; + virtual unsigned getTTypeEncoding() const; - -class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { - mutable void *UniquingMap; -public: - TargetLoweringObjectFileCOFF() : UniquingMap(0) {} - ~TargetLoweringObjectFileCOFF(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - +protected: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; - - /// getCOFFSection - Return the MCSection for the specified COFF section. - /// FIXME: Switch this to a semantic view eventually. - const MCSection *getCOFFSection(StringRef Name, bool isDirective, - SectionKind K) const; }; } // end namespace llvm diff --git a/include/llvm/Target/TargetMachOWriterInfo.h b/include/llvm/Target/TargetMachOWriterInfo.h deleted file mode 100644 index f723bb5..0000000 --- a/include/llvm/Target/TargetMachOWriterInfo.h +++ /dev/null @@ -1,112 +0,0 @@ -//===-- llvm/Target/TargetMachOWriterInfo.h - MachO Writer 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 defines the TargetMachOWriterInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETMACHOWRITERINFO_H -#define LLVM_TARGET_TARGETMACHOWRITERINFO_H - -#include "llvm/CodeGen/MachineRelocation.h" - -namespace llvm { - - class MachineBasicBlock; - class OutputBuffer; - - //===--------------------------------------------------------------------===// - // TargetMachOWriterInfo - //===--------------------------------------------------------------------===// - - class TargetMachOWriterInfo { - uint32_t CPUType; // CPU specifier - uint32_t CPUSubType; // Machine specifier - public: - // The various CPU_TYPE_* constants are already defined by at least one - // system header file and create compilation errors if not respected. -#if !defined(CPU_TYPE_I386) -#define CPU_TYPE_I386 7 -#endif -#if !defined(CPU_TYPE_X86_64) -#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | 0x1000000) -#endif -#if !defined(CPU_TYPE_ARM) -#define CPU_TYPE_ARM 12 -#endif -#if !defined(CPU_TYPE_SPARC) -#define CPU_TYPE_SPARC 14 -#endif -#if !defined(CPU_TYPE_POWERPC) -#define CPU_TYPE_POWERPC 18 -#endif -#if !defined(CPU_TYPE_POWERPC64) -#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | 0x1000000) -#endif - - // Constants for the cputype field - // see <mach/machine.h> - enum { - HDR_CPU_TYPE_I386 = CPU_TYPE_I386, - HDR_CPU_TYPE_X86_64 = CPU_TYPE_X86_64, - HDR_CPU_TYPE_ARM = CPU_TYPE_ARM, - HDR_CPU_TYPE_SPARC = CPU_TYPE_SPARC, - HDR_CPU_TYPE_POWERPC = CPU_TYPE_POWERPC, - HDR_CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC64 - }; - -#if !defined(CPU_SUBTYPE_I386_ALL) -#define CPU_SUBTYPE_I386_ALL 3 -#endif -#if !defined(CPU_SUBTYPE_X86_64_ALL) -#define CPU_SUBTYPE_X86_64_ALL 3 -#endif -#if !defined(CPU_SUBTYPE_ARM_ALL) -#define CPU_SUBTYPE_ARM_ALL 0 -#endif -#if !defined(CPU_SUBTYPE_SPARC_ALL) -#define CPU_SUBTYPE_SPARC_ALL 0 -#endif -#if !defined(CPU_SUBTYPE_POWERPC_ALL) -#define CPU_SUBTYPE_POWERPC_ALL 0 -#endif - - // Constants for the cpusubtype field - // see <mach/machine.h> - enum { - HDR_CPU_SUBTYPE_I386_ALL = CPU_SUBTYPE_I386_ALL, - HDR_CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_X86_64_ALL, - HDR_CPU_SUBTYPE_ARM_ALL = CPU_SUBTYPE_ARM_ALL, - HDR_CPU_SUBTYPE_SPARC_ALL = CPU_SUBTYPE_SPARC_ALL, - HDR_CPU_SUBTYPE_POWERPC_ALL = CPU_SUBTYPE_POWERPC_ALL - }; - - TargetMachOWriterInfo(uint32_t cputype, uint32_t cpusubtype) - : CPUType(cputype), CPUSubType(cpusubtype) {} - virtual ~TargetMachOWriterInfo(); - - virtual MachineRelocation GetJTRelocation(unsigned Offset, - MachineBasicBlock *MBB) const; - - virtual unsigned GetTargetRelocation(MachineRelocation &MR, - unsigned FromIdx, - unsigned ToAddr, - unsigned ToIdx, - OutputBuffer &RelocOut, - OutputBuffer &SecOut, - bool Scattered, - bool Extern) const { return 0; } - - uint32_t getCPUType() const { return CPUType; } - uint32_t getCPUSubType() const { return CPUSubType; } - }; - -} // end llvm namespace - -#endif // LLVM_TARGET_TARGETMACHOWRITERINFO_H diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 4db3d3e..c496e11 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -29,14 +29,11 @@ class TargetIntrinsicInfo; class TargetJITInfo; class TargetLowering; class TargetFrameInfo; -class MachineCodeEmitter; class JITCodeEmitter; -class ObjectCodeEmitter; class TargetRegisterInfo; class PassManagerBase; class PassManager; class Pass; -class TargetMachOWriterInfo; class TargetELFWriterInfo; class formatted_raw_ostream; @@ -61,16 +58,6 @@ namespace CodeModel { }; } -namespace FileModel { - enum Model { - Error, - None, - AsmFile, - MachOFile, - ElfFile - }; -} - // Code generation optimization level. namespace CodeGenOpt { enum Level { @@ -81,15 +68,6 @@ namespace CodeGenOpt { }; } -// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes. -namespace DwarfLSDAEncoding { - enum Encoding { - Default, - FourByte, - EightByte - }; -} - //===----------------------------------------------------------------------===// /// /// TargetMachine - Primary interface to the complete machine description for @@ -163,11 +141,6 @@ public: return InstrItineraryData(); } - /// getMachOWriterInfo - If this target supports a Mach-O writer, return - /// information for it, otherwise return null. - /// - virtual const TargetMachOWriterInfo *getMachOWriterInfo() const { return 0; } - /// getELFWriterInfo - If this target supports an ELF writer, return /// information for it, otherwise return null. /// @@ -197,24 +170,13 @@ public: /// is false. static void setAsmVerbosityDefault(bool); - /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are - /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that - /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded - /// as a 4-byte pointer by default. However, some systems may require a - /// different size due to bugs or other conditions. We will default to a - /// 4-byte encoding unless the system tells us otherwise. - /// - /// FIXME: This call-back isn't good! We should be using the correct encoding - /// regardless of the system. However, there are some systems which have bugs - /// that prevent this from occuring. - virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const { - return DwarfLSDAEncoding::Default; - } - /// CodeGenFileType - These enums are meant to be passed into - /// addPassesToEmitFile to indicate what type of file to emit. + /// addPassesToEmitFile to indicate what type of file to emit, and returned by + /// it to indicate what type of file could actually be made. enum CodeGenFileType { - AssemblyFile, ObjectFile, DynamicLibrary + CGFT_AssemblyFile, + CGFT_ObjectFile, + CGFT_Null // Do not emit any output. }; /// getEnableTailMergeDefault - the default setting for -enable-tail-merge @@ -223,61 +185,17 @@ public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code - /// generation. - /// This method should return FileModel::Error if emission of this file type - /// is not supported. - /// - virtual FileModel::Model addPassesToEmitFile(PassManagerBase &, - formatted_raw_ostream &, - CodeGenFileType, - CodeGenOpt::Level) { - return FileModel::None; - } - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &, - MachineCodeEmitter *, - CodeGenOpt::Level) { - return true; - } - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &, - JITCodeEmitter *, - CodeGenOpt::Level) { - return true; - } - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &, - ObjectCodeEmitter *, - CodeGenOpt::Level) { - return true; - } - - /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle - /// actually outputting the machine code and resolving things like the address - /// of functions. This method returns true if machine code emission is - /// not supported. - /// - virtual bool addPassesToEmitMachineCode(PassManagerBase &, - MachineCodeEmitter &, - CodeGenOpt::Level) { + /// generation. This method should return true if emission of this file type + /// is not supported, or false on success. + virtual bool addPassesToEmitFile(PassManagerBase &, + formatted_raw_ostream &, + CodeGenFileType Filetype, + CodeGenOpt::Level) { return true; } /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle + /// get machine code emitted. This uses a JITCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address /// of functions. This method returns true if machine code emission is /// not supported. @@ -312,9 +230,6 @@ protected: // Can only create subclasses. bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level); private: - // These routines are used by addPassesToEmitFileFinish and - // addPassesToEmitMachineCode to set the CodeModel if it's still marked - // as default. virtual void setCodeModelForJIT(); virtual void setCodeModelForStatic(); @@ -322,56 +237,15 @@ public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code - /// generation. If OptLevel is None, the code generator should emit code as fast - /// as possible, though the generated code may be less efficient. This method - /// should return FileModel::Error if emission of this file type is not - /// supported. - /// - /// The default implementation of this method adds components from the - /// LLVM retargetable code generator, invoking the methods below to get - /// target-specific passes in standard locations. - /// - virtual FileModel::Model addPassesToEmitFile(PassManagerBase &PM, - formatted_raw_ostream &Out, - CodeGenFileType FileType, - CodeGenOpt::Level); - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &PM, - MachineCodeEmitter *MCE, - CodeGenOpt::Level); - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &PM, - JITCodeEmitter *JCE, - CodeGenOpt::Level); - - /// addPassesToEmitFileFinish - If the passes to emit the specified file had - /// to be split up (e.g., to add an object writer pass), this method can be - /// used to finish up adding passes to emit the file, if necessary. - /// - virtual bool addPassesToEmitFileFinish(PassManagerBase &PM, - ObjectCodeEmitter *OCE, - CodeGenOpt::Level); - - /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle - /// actually outputting the machine code and resolving things like the address - /// of functions. This method returns true if machine code emission is - /// not supported. - /// - virtual bool addPassesToEmitMachineCode(PassManagerBase &PM, - MachineCodeEmitter &MCE, - CodeGenOpt::Level); + /// generation. If OptLevel is None, the code generator should emit code as + /// fast as possible, though the generated code may be less efficient. + virtual bool addPassesToEmitFile(PassManagerBase &PM, + formatted_raw_ostream &Out, + CodeGenFileType FileType, + CodeGenOpt::Level); /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle + /// get machine code emitted. This uses a JITCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address /// of functions. This method returns true if machine code emission is /// not supported. @@ -424,61 +298,13 @@ public: /// code emitter, if supported. If this is not supported, 'true' should be /// returned. virtual bool addCodeEmitter(PassManagerBase &, CodeGenOpt::Level, - MachineCodeEmitter &) { - return true; - } - - /// addCodeEmitter - This pass should be overridden by the target to add a - /// code emitter, if supported. If this is not supported, 'true' should be - /// returned. - virtual bool addCodeEmitter(PassManagerBase &, CodeGenOpt::Level, JITCodeEmitter &) { return true; } - /// addSimpleCodeEmitter - This pass should be overridden by the target to add - /// a code emitter (without setting flags), if supported. If this is not - /// supported, 'true' should be returned. - virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level, - MachineCodeEmitter &) { - return true; - } - - /// addSimpleCodeEmitter - This pass should be overridden by the target to add - /// a code emitter (without setting flags), if supported. If this is not - /// supported, 'true' should be returned. - virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level, - JITCodeEmitter &) { - return true; - } - - /// addSimpleCodeEmitter - This pass should be overridden by the target to add - /// a code emitter (without setting flags), if supported. If this is not - /// supported, 'true' should be returned. - virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level, - ObjectCodeEmitter &) { - return true; - } - /// getEnableTailMergeDefault - the default setting for -enable-tail-merge /// on this target. User flag overrides. virtual bool getEnableTailMergeDefault() const { return true; } - - /// addAssemblyEmitter - Helper function which creates a target specific - /// assembly printer, if available. - /// - /// \return Returns 'false' on success. - bool addAssemblyEmitter(PassManagerBase &, CodeGenOpt::Level, - bool /* VerboseAsmDefault */, - formatted_raw_ostream &); - - /// addObjectFileEmitter - Helper function which creates a target specific - /// object files emitter, if available. This interface is temporary, for - /// bringing up MCAssembler-based object file emitters. - /// - /// \return Returns 'false' on success. - bool addObjectFileEmitter(PassManagerBase &, CodeGenOpt::Level, - formatted_raw_ostream &); }; } // End llvm namespace diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h new file mode 100644 index 0000000..10cb45f --- /dev/null +++ b/include/llvm/Target/TargetOpcodes.h @@ -0,0 +1,72 @@ +//===-- llvm/Target/TargetOpcodes.h - Target Indep Opcodes ------*- 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 target independent instruction opcodes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETOPCODES_H +#define LLVM_TARGET_TARGETOPCODES_H + +namespace llvm { + +// Invariant opcodes: All instruction sets have these as their low opcodes. +namespace TargetOpcode { + enum { + PHI = 0, + INLINEASM = 1, + DBG_LABEL = 2, + EH_LABEL = 3, + GC_LABEL = 4, + + /// KILL - This instruction is a noop that is used only to adjust the + /// liveness of registers. This can be useful when dealing with + /// sub-registers. + KILL = 5, + + /// EXTRACT_SUBREG - This instruction takes two operands: a register + /// that has subregisters, and a subregister index. It returns the + /// extracted subregister value. This is commonly used to implement + /// truncation operations on target architectures which support it. + EXTRACT_SUBREG = 6, + + /// INSERT_SUBREG - This instruction takes three operands: a register + /// that has subregisters, a register providing an insert value, and a + /// subregister index. It returns the value of the first register with + /// the value of the second register inserted. The first register is + /// often defined by an IMPLICIT_DEF, as is commonly used to implement + /// anyext operations on target architectures which support it. + INSERT_SUBREG = 7, + + /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. + IMPLICIT_DEF = 8, + + /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except + /// that the first operand is an immediate integer constant. This constant + /// is often zero, as is commonly used to implement zext operations on + /// target architectures which support it, such as with x86-64 (with + /// zext from i32 to i64 via implicit zero-extension). + SUBREG_TO_REG = 9, + + /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain + /// register-to-register copy into a specific register class. This is only + /// used between instruction selection and MachineInstr creation, before + /// virtual registers have been created for all the instructions, and it's + /// only needed in cases where the register classes implied by the + /// instructions are insufficient. The actual MachineInstrs to perform + /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. + COPY_TO_REGCLASS = 10, + + // DBG_VALUE - a mapping of the llvm.dbg.value intrinsic + DBG_VALUE = 11 + }; +} // end namespace TargetOpcode +} // end namespace llvm + +#endif diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index b43450d..b63c2bf 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -116,10 +116,13 @@ namespace llvm { /// be emitted for all functions. extern bool UnwindTablesMandatory; - /// PerformTailCallOpt - This flag is enabled when -tailcallopt is specified - /// on the commandline. When the flag is on, the target will perform tail call - /// optimization (pop the caller's stack) providing it supports it. - extern bool PerformTailCallOpt; + /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is + /// specified on the commandline. When the flag is on, participating targets + /// will perform tail call optimization on all calls which use the fastcc + /// calling convention and which satisfy certain target-independent + /// criteria (being at the end of a function, having the same return type + /// as their parent function, etc.), using an alternate ABI if necessary. + extern bool GuaranteedTailCallOpt; /// StackAlignment - Override default stack alignment for target. extern unsigned StackAlignment; diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index f93eadb..65b60f7 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -169,7 +169,7 @@ public: return I; } - /// hasSubClass - return true if the the specified TargetRegisterClass + /// hasSubClass - return true if the specified TargetRegisterClass /// is a proper subset of this TargetRegisterClass. bool hasSubClass(const TargetRegisterClass *cs) const { for (int i = 0; SubClasses[i] != NULL; ++i) @@ -696,12 +696,12 @@ public: /// getFrameIndexOffset - Returns the displacement from the frame register to /// the stack frame of the specified index. - virtual int getFrameIndexOffset(MachineFunction &MF, int FI) const; + virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const; /// getFrameIndexReference - This method should return the base register /// and offset used to reference a frame index location. The offset is /// returned directly, and the base register is returned via FrameReg. - virtual int getFrameIndexReference(MachineFunction &MF, int FI, + virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const { // By default, assume all frame indices are referenced via whatever // getFrameRegister() says. The target can override this if it's doing diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index d3aa867..37380ab 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -25,12 +25,14 @@ namespace llvm { class AsmPrinter; - class MCAsmParser; - class MCCodeEmitter; class Module; class MCAsmInfo; + class MCAsmParser; + class MCCodeEmitter; + class MCContext; class MCDisassembler; class MCInstPrinter; + class MCStreamer; class TargetAsmLexer; class TargetAsmParser; class TargetMachine; @@ -58,8 +60,9 @@ namespace llvm { const std::string &Features); typedef AsmPrinter *(*AsmPrinterCtorTy)(formatted_raw_ostream &OS, TargetMachine &TM, - const MCAsmInfo *MAI, - bool VerboseAsm); + MCContext &Ctx, + MCStreamer &Streamer, + const MCAsmInfo *MAI); typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P); @@ -69,7 +72,8 @@ namespace llvm { const MCAsmInfo &MAI, raw_ostream &O); typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, - TargetMachine &TM); + TargetMachine &TM, + MCContext &Ctx); private: /// Next - The next registered target in the linked list, maintained by the @@ -189,12 +193,14 @@ namespace llvm { return TargetMachineCtorFn(*this, Triple, Features); } - /// createAsmPrinter - Create a target specific assembly printer pass. + /// createAsmPrinter - Create a target specific assembly printer pass. This + /// takes ownership of the MCContext and MCStreamer objects but not the MAI. AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM, - const MCAsmInfo *MAI, bool Verbose) const { + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *MAI) const { if (!AsmPrinterCtorFn) return 0; - return AsmPrinterCtorFn(OS, TM, MAI, Verbose); + return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI); } /// createAsmLexer - Create a target specific assembly lexer. @@ -231,10 +237,10 @@ namespace llvm { /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const { + MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const { if (!CodeEmitterCtorFn) return 0; - return CodeEmitterCtorFn(*this, TM); + return CodeEmitterCtorFn(*this, TM, Ctx); } /// @} @@ -547,8 +553,9 @@ namespace llvm { private: static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM, - const MCAsmInfo *MAI, bool Verbose) { - return new AsmPrinterImpl(OS, TM, MAI, Verbose); + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *MAI) { + return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI); } }; @@ -607,8 +614,9 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM) { - return new CodeEmitterImpl(T, TM); + static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM, + MCContext &Ctx) { + return new CodeEmitterImpl(T, TM, Ctx); } }; diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index dc5e644..30ece0e 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -52,10 +52,11 @@ struct Inliner : public CallGraphSCCPass { unsigned getInlineThreshold() const { return InlineThreshold; } /// Calculate the inline threshold for given Caller. This threshold is lower - /// if Caller is marked with OptimizeForSize and -inline-threshold is not - /// given on the comand line. + /// if the caller is marked with OptimizeForSize and -inline-threshold is not + /// given on the comand line. It is higher if the callee is marked with the + /// inlinehint attribute. /// - unsigned getInlineThreshold(Function* Caller) const; + unsigned getInlineThreshold(CallSite CS) const; /// getInlineCost - This method must be implemented by the subclass to /// determine the cost of inlining the specified call site. If the cost diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 7fbbef9..5f494fb 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -19,6 +19,7 @@ #define LLVM_TRANSFORMS_UTILS_CLONING_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Twine.h" namespace llvm { @@ -101,7 +102,7 @@ struct ClonedCodeInfo { /// BasicBlock *CloneBasicBlock(const BasicBlock *BB, DenseMap<const Value*, Value*> &ValueMap, - const char *NameSuffix = "", Function *F = 0, + const Twine &NameSuffix = "", Function *F = 0, ClonedCodeInfo *CodeInfo = 0); diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index f6d9f82..bb6fd56 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -38,7 +38,8 @@ template<typename T> class SmallVectorImpl; /// from this value cannot trap. If it is not obviously safe to load from the /// specified pointer, we do a quick local scan of the basic block containing /// ScanFrom, to determine if the address is already accessed. -bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom); +bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, + unsigned Align, const TargetData *TD = 0); //===----------------------------------------------------------------------===// // Local constant propagation. @@ -130,7 +131,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB); /// /// WARNING: The entry node of a method may not be simplified. /// -bool SimplifyCFG(BasicBlock *BB); +bool SimplifyCFG(BasicBlock *BB, const TargetData *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 diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 2c37a68..c52419c 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -82,10 +82,11 @@ public: IntegerTyID, ///< 8: Arbitrary bit width integers FunctionTyID, ///< 9: Functions StructTyID, ///< 10: Structures - ArrayTyID, ///< 11: Arrays - PointerTyID, ///< 12: Pointers - OpaqueTyID, ///< 13: Opaque: type with unknown structure - VectorTyID, ///< 14: SIMD 'packed' format, or other vector type + UnionTyID, ///< 11: Unions + ArrayTyID, ///< 12: Arrays + PointerTyID, ///< 13: Pointers + OpaqueTyID, ///< 14: Opaque: type with unknown structure + VectorTyID, ///< 15: SIMD 'packed' format, or other vector type NumTypeIDs, // Must remain as last defined ID LastPrimitiveTyID = LabelTyID, @@ -213,27 +214,47 @@ public: /// getDescription - Return the string representation of the type. std::string getDescription() const; - /// isInteger - True if this is an instance of IntegerType. + /// isIntegerTy - True if this is an instance of IntegerType. /// - bool isInteger() const { return ID == IntegerTyID; } + bool isIntegerTy() const { return ID == IntegerTyID; } - /// isInteger - Return true if this is an IntegerType of the specified width. - bool isInteger(unsigned Bitwidth) const; + /// isIntegerTy - Return true if this is an IntegerType of the given width. + bool isIntegerTy(unsigned Bitwidth) const; - /// isIntOrIntVector - Return true if this is an integer type or a vector of + /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of /// integer types. /// - bool isIntOrIntVector() const; + bool isIntOrIntVectorTy() const; - /// isFloatingPoint - Return true if this is one of the five floating point + /// isFloatingPointTy - Return true if this is one of the five floating point /// types - bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID || + bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID || ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; } - /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types. + /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP. /// - bool isFPOrFPVector() const; - + bool isFPOrFPVectorTy() const; + + /// isFunctionTy - True if this is an instance of FunctionType. + /// + bool isFunctionTy() const { return ID == FunctionTyID; } + + /// isStructTy - True if this is an instance of StructType. + /// + bool isStructTy() const { return ID == StructTyID; } + + /// isArrayTy - True if this is an instance of ArrayType. + /// + bool isArrayTy() const { return ID == ArrayTyID; } + + /// isPointerTy - True if this is an instance of PointerType. + /// + bool isPointerTy() const { return ID == PointerTyID; } + + /// isVectorTy - True if this is an instance of VectorType. + /// + bool isVectorTy() const { return ID == VectorTyID; } + /// isAbstract - True if the type is either an Opaque type, or is a derived /// type that includes an opaque type somewhere in it. /// @@ -277,7 +298,7 @@ public: /// does not include vector types. /// inline bool isAggregateType() const { - return ID == StructTyID || ID == ArrayTyID; + return ID == StructTyID || ID == ArrayTyID || ID == UnionTyID; } /// isSized - Return true if it makes sense to take the size of this type. To @@ -286,11 +307,12 @@ public: /// bool isSized() const { // If it's a primitive, it is always sized. - if (ID == IntegerTyID || isFloatingPoint() || ID == PointerTyID) + if (ID == IntegerTyID || isFloatingPointTy() || ID == PointerTyID) return true; // If it is not something that can have a size (e.g. a function or label), // it doesn't have a size. - if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID) + if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID && + ID != UnionTyID) return false; // If it is something that can have a size and it's concrete, it definitely // has a size, otherwise we have to try harder to decide. diff --git a/include/llvm/Value.h b/include/llvm/Value.h index f0bd8be..d06cbc0 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -215,6 +215,7 @@ public: ConstantFPVal, // This is an instance of ConstantFP ConstantArrayVal, // This is an instance of ConstantArray ConstantStructVal, // This is an instance of ConstantStruct + ConstantUnionVal, // This is an instance of ConstantUnion ConstantVectorVal, // This is an instance of ConstantVector ConstantPointerNullVal, // This is an instance of ConstantPointerNull MDNodeVal, // This is an instance of MDNode @@ -285,10 +286,11 @@ public: /// getUnderlyingObject - This method strips off any GEP address adjustments /// and pointer casts from the specified value, returning the original object /// being addressed. Note that the returned value has pointer type if the - /// specified value does. - Value *getUnderlyingObject(); - const Value *getUnderlyingObject() const { - return const_cast<Value*>(this)->getUnderlyingObject(); + /// specified value does. If the MaxLookup value is non-zero, it limits the + /// number of instructions to be stripped off. + Value *getUnderlyingObject(unsigned MaxLookup = 6); + const Value *getUnderlyingObject(unsigned MaxLookup = 6) const { + return const_cast<Value*>(this)->getUnderlyingObject(MaxLookup); } /// DoPHITranslation - If this value is a PHI node with CurBB as its parent, diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h index 53815ba..7497dae 100644 --- a/include/llvm/ValueSymbolTable.h +++ b/include/llvm/ValueSymbolTable.h @@ -17,7 +17,6 @@ #include "llvm/Value.h" #include "llvm/ADT/StringMap.h" #include "llvm/System/DataTypes.h" -#include "llvm/ADT/ilist_node.h" namespace llvm { template<typename ValueSubClass, typename ItemParentClass> @@ -195,9 +194,15 @@ public: /// @name Mutators /// @{ public: - /// insert - The method inserts a new entry into the stringmap. + /// insert - The method inserts a new entry into the stringmap. This will + /// replace existing entry, if any. void insert(StringRef Name, NamedMDNode *Node) { - (void) mmap.GetOrCreateValue(Name, Node); + StringMapEntry<NamedMDNode *> &Entry = + mmap.GetOrCreateValue(Name, Node); + if (Entry.getValue() != Node) { + mmap.remove(&Entry); + (void) mmap.GetOrCreateValue(Name, Node); + } } /// This method removes a NamedMDNode from the symbol table. |