Upgrade our copy of llvm/clang to r130700, from upstream's trunk.

This commit is contained in:
Dimitry Andric 2011-05-02 21:04:37 +00:00
commit 3b0f406639
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=221345
1219 changed files with 71426 additions and 36178 deletions

View File

@ -38,6 +38,14 @@
# xargs -n1 | sort | uniq -d; # xargs -n1 | sort | uniq -d;
# done # done
# 20110502: new clang import which bumps version from 2.9 to 3.0
OLD_FILES+=usr/include/clang/2.9/emmintrin.h
OLD_FILES+=usr/include/clang/2.9/mm_malloc.h
OLD_FILES+=usr/include/clang/2.9/mmintrin.h
OLD_FILES+=usr/include/clang/2.9/pmmintrin.h
OLD_FILES+=usr/include/clang/2.9/tmmintrin.h
OLD_FILES+=usr/include/clang/2.9/xmmintrin.h
OLD_DIRS+=usr/include/clang/2.9
# 20110417: removal of Objective-C support # 20110417: removal of Objective-C support
OLD_FILES+=usr/include/objc/encoding.h OLD_FILES+=usr/include/objc/encoding.h
OLD_FILES+=usr/include/objc/hash.h OLD_FILES+=usr/include/objc/hash.h

View File

@ -0,0 +1,149 @@
/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header provides public interface to a disassembler library. *|
|* LLVM provides an implementation of this interface. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_DISASSEMBLER_H
#define LLVM_C_DISASSEMBLER_H 1
#include <stddef.h>
#include "llvm/Support/DataTypes.h"
/**
* An opaque reference to a disassembler context.
*/
typedef void *LLVMDisasmContextRef;
/**
* The type for the operand information call back function. This is called to
* get the symbolic information for an operand of an instruction. Typically
* this is from the relocation information, symbol table, etc. That block of
* information is saved when the disassembler context is created and passed to
* the call back in the DisInfo parameter. The instruction containing operand
* is at the PC parameter. For some instruction sets, there can be more than
* one operand with symbolic information. To determine the symbolic operand
* information for each operand, the bytes for the specific operand in the
* instruction are specified by the Offset parameter and its byte widith is the
* size parameter. For instructions sets with fixed widths and one symbolic
* operand per instruction, the Offset parameter will be zero and Size parameter
* will be the instruction width. The information is returned in TagBuf and is
* Triple specific with its specific information defined by the value of
* TagType for that Triple. If symbolic information is returned the function
* returns 1 else it returns 0.
*/
typedef int (*LLVMOpInfoCallback)(void *DisInfo,
uint64_t PC,
uint64_t Offset,
uint64_t Size,
int TagType,
void *TagBuf);
/**
* The initial support in LLVM MC for the most general form of a relocatable
* expression is "AddSymbol - SubtractSymbol + Offset". For some Darwin targets
* this full form is encoded in the relocation information so that AddSymbol and
* SubtractSymbol can be link edited independent of each other. Many other
* platforms only allow a relocatable expression of the form AddSymbol + Offset
* to be encoded.
*
* The LLVMOpInfoCallback() for the TagType value of 1 uses the struct
* LLVMOpInfo1. The value of the relocatable expression for the operand,
* including any PC adjustment, is passed in to the call back in the Value
* field. The symbolic information about the operand is returned using all
* the fields of the structure with the Offset of the relocatable expression
* returned in the Value field. It is possible that some symbols in the
* relocatable expression were assembly temporary symbols, for example
* "Ldata - LpicBase + constant", and only the Values of the symbols without
* symbol names are present in the relocation information. The VariantKind
* type is one of the Target specific #defines below and is used to print
* operands like "_foo@GOT", ":lower16:_foo", etc.
*/
struct LLVMOpInfoSymbol1 {
uint64_t Present; /* 1 if this symbol is present */
char *Name; /* symbol name if not NULL */
uint64_t Value; /* symbol value if name is NULL */
};
struct LLVMOpInfo1 {
struct LLVMOpInfoSymbol1 AddSymbol;
struct LLVMOpInfoSymbol1 SubtractSymbol;
uint64_t Value;
uint64_t VariantKind;
};
/**
* The operand VariantKinds for symbolic disassembly.
*/
#define LLVMDisassembler_VariantKind_None 0 /* all targets */
/**
* The ARM target VariantKinds.
*/
#define LLVMDisassembler_VariantKind_ARM_HI16 1 /* :upper16: */
#define LLVMDisassembler_VariantKind_ARM_LO16 2 /* :lower16: */
/**
* The type for the symbol lookup function. This may be called by the
* disassembler for such things like adding a comment for a PC plus a constant
* offset load instruction to use a symbol name instead of a load address value.
* It is passed the block information is saved when the disassembler context is
* created and a value of a symbol to look up. If no symbol is found NULL is
* to be returned.
*/
typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
uint64_t SymbolValue);
#ifdef __cplusplus
extern "C" {
#endif /* !defined(__cplusplus) */
/**
* Create a disassembler for the TripleName. Symbolic disassembly is supported
* by passing a block of information in the DisInfo parameter and specifing the
* TagType and call back functions as described above. These can all be passed
* as NULL. If successful this returns a disassembler context if not it
* returns NULL.
*/
extern LLVMDisasmContextRef
LLVMCreateDisasm(const char *TripleName,
void *DisInfo,
int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Dispose of a disassembler context.
*/
extern void
LLVMDisasmDispose(LLVMDisasmContextRef DC);
/**
* Disassmble a single instruction using the disassembler context specified in
* the parameter DC. The bytes of the instruction are specified in the parameter
* Bytes, and contains at least BytesSize number of bytes. The instruction is
* at the address specified by the PC parameter. If a valid instruction can be
* disassembled its string is returned indirectly in OutString which whos size
* is specified in the parameter OutStringSize. This function returns the
* number of bytes in the instruction or zero if there was no valid instruction.
*/
extern size_t
LLVMDisasmInstruction(LLVMDisasmContextRef DC,
uint8_t *Bytes,
uint64_t BytesSize,
uint64_t PC,
char *OutString,
size_t OutStringSize);
#ifdef __cplusplus
}
#endif /* !defined(__cplusplus) */
#endif /* !defined(LLVM_C_DISASSEMBLER_H) */

View File

@ -44,7 +44,7 @@ typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
@param arg An anonymous argument for client use. @param arg An anonymous argument for client use.
@result 0 if the register could be read; -1 otherwise. @result 0 if the register could be read; -1 otherwise.
*/ */
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID, typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
void* arg); void* arg);
/*! /*!
@ -83,7 +83,7 @@ typedef void *EDTokenRef;
Encapsulates an operand of an instruction. Encapsulates an operand of an instruction.
*/ */
typedef void *EDOperandRef; typedef void *EDOperandRef;
/*! /*!
@functiongroup Getting a disassembler @functiongroup Getting a disassembler
*/ */
@ -91,7 +91,7 @@ typedef void *EDOperandRef;
/*! /*!
@function EDGetDisassembler @function EDGetDisassembler
Gets the disassembler for a given target. Gets the disassembler for a given target.
@param disassembler A pointer whose target will be filled in with the @param disassembler A pointer whose target will be filled in with the
disassembler. disassembler.
@param triple Identifies the target. Example: "x86_64-apple-darwin10" @param triple Identifies the target. Example: "x86_64-apple-darwin10"
@param syntax The assembly syntax to use when decoding instructions. @param syntax The assembly syntax to use when decoding instructions.
@ -104,12 +104,12 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
/*! /*!
@functiongroup Generic architectural queries @functiongroup Generic architectural queries
*/ */
/*! /*!
@function EDGetRegisterName @function EDGetRegisterName
Gets the human-readable name for a given register. Gets the human-readable name for a given register.
@param regName A pointer whose target will be pointed at the name of the @param regName A pointer whose target will be pointed at the name of the
register. The name does not need to be deallocated and will be register. The name does not need to be deallocated and will be
@param disassembler The disassembler to query for the name. @param disassembler The disassembler to query for the name.
@param regID The register identifier, as returned by EDRegisterTokenValue. @param regID The register identifier, as returned by EDRegisterTokenValue.
@result 0 on success; -1 otherwise. @result 0 on success; -1 otherwise.
@ -117,7 +117,7 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
int EDGetRegisterName(const char** regName, int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler, EDDisassemblerRef disassembler,
unsigned regID); unsigned regID);
/*! /*!
@function EDRegisterIsStackPointer @function EDRegisterIsStackPointer
Determines if a register is one of the platform's stack-pointer registers. Determines if a register is one of the platform's stack-pointer registers.
@ -137,16 +137,16 @@ int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
*/ */
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
unsigned regID); unsigned regID);
/*! /*!
@functiongroup Creating and querying instructions @functiongroup Creating and querying instructions
*/ */
/*! /*!
@function EDCreateInst @function EDCreateInst
Gets a set of contiguous instructions from a disassembler. Gets a set of contiguous instructions from a disassembler.
@param insts A pointer to an array that will be filled in with the @param insts A pointer to an array that will be filled in with the
instructions. Must have at least count entries. Entries not filled in will instructions. Must have at least count entries. Entries not filled in will
be set to NULL. be set to NULL.
@param count The maximum number of instructions to fill in. @param count The maximum number of instructions to fill in.
@param disassembler The disassembler to use when decoding the instructions. @param disassembler The disassembler to use when decoding the instructions.
@ -197,7 +197,7 @@ int EDGetInstString(const char **buf,
@result 0 on success; -1 otherwise. @result 0 on success; -1 otherwise.
*/ */
int EDInstID(unsigned *instID, EDInstRef inst); int EDInstID(unsigned *instID, EDInstRef inst);
/*! /*!
@function EDInstIsBranch @function EDInstIsBranch
@param inst The instruction to be queried. @param inst The instruction to be queried.
@ -217,7 +217,7 @@ int EDInstIsMove(EDInstRef inst);
/*! /*!
@function EDBranchTargetID @function EDBranchTargetID
@param inst The instruction to be queried. @param inst The instruction to be queried.
@result The ID of the branch target operand, suitable for use with @result The ID of the branch target operand, suitable for use with
EDCopyOperand. -1 if no such operand exists. EDCopyOperand. -1 if no such operand exists.
*/ */
int EDBranchTargetID(EDInstRef inst); int EDBranchTargetID(EDInstRef inst);
@ -225,7 +225,7 @@ int EDBranchTargetID(EDInstRef inst);
/*! /*!
@function EDMoveSourceID @function EDMoveSourceID
@param inst The instruction to be queried. @param inst The instruction to be queried.
@result The ID of the move source operand, suitable for use with @result The ID of the move source operand, suitable for use with
EDCopyOperand. -1 if no such operand exists. EDCopyOperand. -1 if no such operand exists.
*/ */
int EDMoveSourceID(EDInstRef inst); int EDMoveSourceID(EDInstRef inst);
@ -233,7 +233,7 @@ int EDMoveSourceID(EDInstRef inst);
/*! /*!
@function EDMoveTargetID @function EDMoveTargetID
@param inst The instruction to be queried. @param inst The instruction to be queried.
@result The ID of the move source operand, suitable for use with @result The ID of the move source operand, suitable for use with
EDCopyOperand. -1 if no such operand exists. EDCopyOperand. -1 if no such operand exists.
*/ */
int EDMoveTargetID(EDInstRef inst); int EDMoveTargetID(EDInstRef inst);
@ -241,7 +241,7 @@ int EDMoveTargetID(EDInstRef inst);
/*! /*!
@functiongroup Creating and querying tokens @functiongroup Creating and querying tokens
*/ */
/*! /*!
@function EDNumTokens @function EDNumTokens
@param inst The instruction to be queried. @param inst The instruction to be queried.
@ -261,7 +261,7 @@ int EDNumTokens(EDInstRef inst);
int EDGetToken(EDTokenRef *token, int EDGetToken(EDTokenRef *token,
EDInstRef inst, EDInstRef inst,
int index); int index);
/*! /*!
@function EDGetTokenString @function EDGetTokenString
Gets the disassembled text for a token. Gets the disassembled text for a token.
@ -287,7 +287,7 @@ int EDOperandIndexForToken(EDTokenRef token);
@result 1 if the token is whitespace; 0 if not; -1 on error. @result 1 if the token is whitespace; 0 if not; -1 on error.
*/ */
int EDTokenIsWhitespace(EDTokenRef token); int EDTokenIsWhitespace(EDTokenRef token);
/*! /*!
@function EDTokenIsPunctuation @function EDTokenIsPunctuation
@param token The token to be queried. @param token The token to be queried.
@ -335,18 +335,18 @@ int EDLiteralTokenAbsoluteValue(uint64_t *value,
/*! /*!
@function EDRegisterTokenValue @function EDRegisterTokenValue
@param registerID A pointer whose target will be filled in with the LLVM @param registerID A pointer whose target will be filled in with the LLVM
register identifier for the token. register identifier for the token.
@param token The token to be queried. @param token The token to be queried.
@result 0 on success; -1 otherwise. @result 0 on success; -1 otherwise.
*/ */
int EDRegisterTokenValue(unsigned *registerID, int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token); EDTokenRef token);
/*! /*!
@functiongroup Creating and querying operands @functiongroup Creating and querying operands
*/ */
/*! /*!
@function EDNumOperands @function EDNumOperands
@param inst The instruction to be queried. @param inst The instruction to be queried.
@ -366,7 +366,7 @@ int EDNumOperands(EDInstRef inst);
int EDGetOperand(EDOperandRef *operand, int EDGetOperand(EDOperandRef *operand,
EDInstRef inst, EDInstRef inst,
int index); int index);
/*! /*!
@function EDOperandIsRegister @function EDOperandIsRegister
@param operand The operand to be queried. @param operand The operand to be queried.
@ -391,13 +391,13 @@ int EDOperandIsMemory(EDOperandRef operand);
/*! /*!
@function EDRegisterOperandValue @function EDRegisterOperandValue
@param value A pointer whose target will be filled in with the LLVM register ID @param value A pointer whose target will be filled in with the LLVM register ID
of the register named by the operand. of the register named by the operand.
@param operand The operand to be queried. @param operand The operand to be queried.
@result 0 on success; -1 otherwise. @result 0 on success; -1 otherwise.
*/ */
int EDRegisterOperandValue(unsigned *value, int EDRegisterOperandValue(unsigned *value,
EDOperandRef operand); EDOperandRef operand);
/*! /*!
@function EDImmediateOperandValue @function EDImmediateOperandValue
@param value A pointer whose target will be filled in with the value of the @param value A pointer whose target will be filled in with the value of the
@ -427,7 +427,7 @@ int EDEvaluateOperand(uint64_t *result,
EDOperandRef operand, EDOperandRef operand,
EDRegisterReaderCallback regReader, EDRegisterReaderCallback regReader,
void *arg); void *arg);
#ifdef __BLOCKS__ #ifdef __BLOCKS__
/*! /*!
@ -458,13 +458,13 @@ typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
typedef int (^EDTokenVisitor_t)(EDTokenRef token); typedef int (^EDTokenVisitor_t)(EDTokenRef token);
/*! @functiongroup Block-based interfaces */ /*! @functiongroup Block-based interfaces */
/*! /*!
@function EDBlockCreateInsts @function EDBlockCreateInsts
Gets a set of contiguous instructions from a disassembler, using a block to Gets a set of contiguous instructions from a disassembler, using a block to
read memory. read memory.
@param insts A pointer to an array that will be filled in with the @param insts A pointer to an array that will be filled in with the
instructions. Must have at least count entries. Entries not filled in will instructions. Must have at least count entries. Entries not filled in will
be set to NULL. be set to NULL.
@param count The maximum number of instructions to fill in. @param count The maximum number of instructions to fill in.
@param disassembler The disassembler to use when decoding the instructions. @param disassembler The disassembler to use when decoding the instructions.
@ -505,7 +505,7 @@ int EDBlockVisitTokens(EDInstRef inst,
EDTokenVisitor_t visitor); EDTokenVisitor_t visitor);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -0,0 +1,77 @@
/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* */
/* This header declares the C interface to libLLVMObject.a, which */
/* implements object file reading and writing. */
/* */
/* Many exotic languages can interoperate with C code but have a harder time */
/* with C++ due to name mangling. So in addition to C, this interface enables */
/* tools written in such languages. */
/* */
/*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_OBJECT_H
#define LLVM_C_OBJECT_H
#include "llvm-c/Core.h"
#include "llvm/Config/llvm-config.h"
#ifdef __cplusplus
#include "llvm/Object/ObjectFile.h"
extern "C" {
#endif
typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf);
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
LLVMSectionIteratorRef SI);
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
#ifdef __cplusplus
}
namespace llvm {
namespace object {
inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
return reinterpret_cast<ObjectFile*>(OF);
}
inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
}
inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<ObjectFile::section_iterator*>(SI);
}
inline LLVMSectionIteratorRef
wrap(const ObjectFile::section_iterator *SI) {
return reinterpret_cast<LLVMSectionIteratorRef>
(const_cast<ObjectFile::section_iterator*>(SI));
}
}
}
#endif /* defined(__cplusplus) */
#endif

View File

@ -52,6 +52,9 @@ void LLVMAddLICMPass(LLVMPassManagerRef PM);
/** See llvm::createLoopDeletionPass function. */ /** See llvm::createLoopDeletionPass function. */
void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM); void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM);
/** See llvm::createLoopIdiomPass function */
void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM);
/** See llvm::createLoopRotatePass function. */ /** See llvm::createLoopRotatePass function. */
void LLVMAddLoopRotatePass(LLVMPassManagerRef PM); void LLVMAddLoopRotatePass(LLVMPassManagerRef PM);
@ -76,6 +79,9 @@ void LLVMAddSCCPPass(LLVMPassManagerRef PM);
/** See llvm::createScalarReplAggregatesPass function. */ /** See llvm::createScalarReplAggregatesPass function. */
void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM); void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM);
/** See llvm::createScalarReplAggregatesPass function. */
void LLVMAddScalarReplAggregatesPassSSA(LLVMPassManagerRef PM);
/** See llvm::createScalarReplAggregatesPass function. */ /** See llvm::createScalarReplAggregatesPass function. */
void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM, void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM,
int Threshold); int Threshold);
@ -95,6 +101,19 @@ void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef PM);
/** See llvm::createVerifierPass function. */ /** See llvm::createVerifierPass function. */
void LLVMAddVerifierPass(LLVMPassManagerRef PM); void LLVMAddVerifierPass(LLVMPassManagerRef PM);
/** See llvm::createCorrelatedValuePropagationPass function */
void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM);
/** See llvm::createEarlyCSEPass function */
void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM);
/** See llvm::createTypeBasedAliasAnalysisPass function */
void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
/** See llvm::createBasicAliasAnalysisPass function */
void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */

View File

@ -72,7 +72,7 @@ lto_get_version(void);
/** /**
* Returns the last error string or NULL if last operation was sucessful. * Returns the last error string or NULL if last operation was successful.
*/ */
extern const char* extern const char*
lto_get_error_message(void); lto_get_error_message(void);
@ -127,7 +127,15 @@ lto_module_create_from_memory(const void* mem, size_t length);
* Returns NULL on error (check lto_get_error_message() for details). * Returns NULL on error (check lto_get_error_message() for details).
*/ */
extern lto_module_t extern lto_module_t
lto_module_create_from_fd(int fd, const char *path, off_t size); lto_module_create_from_fd(int fd, const char *path, size_t file_size);
/**
* Loads an object file from disk. The seek point of fd is not preserved.
* Returns NULL on error (check lto_get_error_message() for details).
*/
extern lto_module_t
lto_module_create_from_fd_at_offset(int fd, const char *path, size_t file_size,
size_t map_size, off_t offset);
/** /**
@ -255,7 +263,7 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
/** /**
* Generates code for all added modules into one native object file. * Generates code for all added modules into one native object file.
* On sucess returns a pointer to a generated mach-o/ELF buffer and * On success returns a pointer to a generated mach-o/ELF buffer and
* length set to the buffer size. The buffer is owned by the * length set to the buffer size. The buffer is owned by the
* lto_code_gen_t and will be freed when lto_codegen_dispose() * lto_code_gen_t and will be freed when lto_codegen_dispose()
* is called, or lto_codegen_compile() is called again. * is called, or lto_codegen_compile() is called again.
@ -264,6 +272,13 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
extern const void* extern const void*
lto_codegen_compile(lto_code_gen_t cg, size_t* length); lto_codegen_compile(lto_code_gen_t cg, size_t* length);
/**
* Generates code for all added modules into one native object file.
* The name of the file is written to name. Returns true on error.
*/
extern bool
lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
/** /**
* Sets options to help debug codegen bugs. * Sets options to help debug codegen bugs.

View File

@ -353,6 +353,10 @@ namespace llvm {
unsigned FormatPrecision = 0, unsigned FormatPrecision = 0,
unsigned FormatMaxPadding = 3) const; unsigned FormatMaxPadding = 3) const;
/// getExactInverse - If this value has an exact multiplicative inverse,
/// store it in inv and return true.
bool getExactInverse(APFloat *inv) const;
private: private:
/* Trivial queries. */ /* Trivial queries. */

View File

@ -818,6 +818,7 @@ class APInt {
APInt usub_ov(const APInt &RHS, bool &Overflow) const; APInt usub_ov(const APInt &RHS, bool &Overflow) const;
APInt sdiv_ov(const APInt &RHS, bool &Overflow) const; APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
APInt smul_ov(const APInt &RHS, bool &Overflow) const; APInt smul_ov(const APInt &RHS, bool &Overflow) const;
APInt umul_ov(const APInt &RHS, bool &Overflow) const;
APInt sshl_ov(unsigned Amt, bool &Overflow) const; APInt sshl_ov(unsigned Amt, bool &Overflow) const;
/// @returns the bit value at bitPosition /// @returns the bit value at bitPosition
@ -1372,7 +1373,7 @@ class APInt {
/// Calculate the magic number for unsigned division by a constant. /// Calculate the magic number for unsigned division by a constant.
struct mu; struct mu;
mu magicu() const; mu magicu(unsigned LeadingZeros = 0) const;
/// @} /// @}
/// @name Building-block Operations for APInt and APFloat /// @name Building-block Operations for APInt and APFloat

View File

@ -22,8 +22,8 @@ namespace llvm {
/// ///
/// This class does not own the underlying data, it is expected to be used in /// This class does not own the underlying data, it is expected to be used in
/// situations where the data resides in some other buffer, whose lifetime /// situations where the data resides in some other buffer, whose lifetime
/// extends past that of the StringRef. For this reason, it is not in general /// extends past that of the ArrayRef. For this reason, it is not in general
/// safe to store a ArrayRef. /// safe to store an ArrayRef.
/// ///
/// This is intended to be trivially copyable, so it should be passed by /// This is intended to be trivially copyable, so it should be passed by
/// value. /// value.
@ -79,6 +79,8 @@ namespace llvm {
/// empty - Check if the array is empty. /// empty - Check if the array is empty.
bool empty() const { return Length == 0; } bool empty() const { return Length == 0; }
const T *data() const { return Data; }
/// size - Get the array size. /// size - Get the array size.
size_t size() const { return Length; } size_t size() const { return Length; }
@ -94,10 +96,22 @@ namespace llvm {
return Data[Length-1]; return Data[Length-1];
} }
/// slice(n) - Chop off the first N elements of the array.
ArrayRef<T> slice(unsigned N) {
assert(N <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, size()-N);
}
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
ArrayRef<T> slice(unsigned N, unsigned M) {
assert(N+M <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, M);
}
/// @} /// @}
/// @name Operator Overloads /// @name Operator Overloads
/// @{ /// @{
const T &operator[](size_t Index) const { const T &operator[](size_t Index) const {
assert(Index < Length && "Invalid index!"); assert(Index < Length && "Invalid index!");
return Data[Index]; return Data[Index];
@ -106,7 +120,6 @@ namespace llvm {
/// @} /// @}
/// @name Expensive Operations /// @name Expensive Operations
/// @{ /// @{
std::vector<T> vec() const { std::vector<T> vec() const {
return std::vector<T>(Data, Data+Length); return std::vector<T>(Data, Data+Length);
} }

View File

@ -53,13 +53,13 @@ class DenseMap {
CopyFrom(other); CopyFrom(other);
} }
explicit DenseMap(unsigned NumInitBuckets = 64) { explicit DenseMap(unsigned NumInitBuckets = 0) {
init(NumInitBuckets); init(NumInitBuckets);
} }
template<typename InputIt> template<typename InputIt>
DenseMap(const InputIt &I, const InputIt &E) { DenseMap(const InputIt &I, const InputIt &E) {
init(64); init(NextPowerOf2(std::distance(I, E)));
insert(I, E); insert(I, E);
} }
@ -72,7 +72,8 @@ class DenseMap {
P->first.~KeyT(); P->first.~KeyT();
} }
#ifndef NDEBUG #ifndef NDEBUG
memset(Buckets, 0x5a, sizeof(BucketT)*NumBuckets); if (NumBuckets)
memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
#endif #endif
operator delete(Buckets); operator delete(Buckets);
} }
@ -98,7 +99,10 @@ class DenseMap {
unsigned size() const { return NumEntries; } unsigned size() const { return NumEntries; }
/// Grow the densemap so that it has at least Size buckets. Does not shrink /// Grow the densemap so that it has at least Size buckets. Does not shrink
void resize(size_t Size) { grow(Size); } void resize(size_t Size) {
if (Size > NumBuckets)
grow(Size);
}
void clear() { void clear() {
if (NumEntries == 0 && NumTombstones == 0) return; if (NumEntries == 0 && NumTombstones == 0) return;
@ -248,23 +252,29 @@ class DenseMap {
if (NumBuckets) { if (NumBuckets) {
#ifndef NDEBUG #ifndef NDEBUG
memset(Buckets, 0x5a, sizeof(BucketT)*NumBuckets); memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
#endif #endif
operator delete(Buckets); operator delete(Buckets);
} }
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) *
other.NumBuckets)); NumBuckets = other.NumBuckets;
if (NumBuckets == 0) {
Buckets = 0;
return;
}
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value) if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value)
memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT)); memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
else else
for (size_t i = 0; i < other.NumBuckets; ++i) { for (size_t i = 0; i < NumBuckets; ++i) {
new (&Buckets[i].first) KeyT(other.Buckets[i].first); new (&Buckets[i].first) KeyT(other.Buckets[i].first);
if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) && if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
!KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey())) !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
new (&Buckets[i].second) ValueT(other.Buckets[i].second); new (&Buckets[i].second) ValueT(other.Buckets[i].second);
} }
NumBuckets = other.NumBuckets;
} }
BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
@ -279,11 +289,14 @@ class DenseMap {
// table completely filled with tombstones, no lookup would ever succeed, // table completely filled with tombstones, no lookup would ever succeed,
// causing infinite loops in lookup. // causing infinite loops in lookup.
++NumEntries; ++NumEntries;
if (NumEntries*4 >= NumBuckets*3 || if (NumEntries*4 >= NumBuckets*3) {
NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
this->grow(NumBuckets * 2); this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket); LookupBucketFor(Key, TheBucket);
} }
if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
this->grow(NumBuckets);
LookupBucketFor(Key, TheBucket);
}
// If we are writing over a tombstone, remember this. // If we are writing over a tombstone, remember this.
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
@ -313,6 +326,11 @@ class DenseMap {
unsigned ProbeAmt = 1; unsigned ProbeAmt = 1;
BucketT *BucketsPtr = Buckets; BucketT *BucketsPtr = Buckets;
if (NumBuckets == 0) {
FoundBucket = 0;
return false;
}
// FoundTombstone - Keep track of whether we find a tombstone while probing. // FoundTombstone - Keep track of whether we find a tombstone while probing.
BucketT *FoundTombstone = 0; BucketT *FoundTombstone = 0;
const KeyT EmptyKey = getEmptyKey(); const KeyT EmptyKey = getEmptyKey();
@ -354,6 +372,12 @@ class DenseMap {
NumEntries = 0; NumEntries = 0;
NumTombstones = 0; NumTombstones = 0;
NumBuckets = InitBuckets; NumBuckets = InitBuckets;
if (InitBuckets == 0) {
Buckets = 0;
return;
}
assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 && assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
"# initial buckets must be a power of two!"); "# initial buckets must be a power of two!");
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets)); Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
@ -367,6 +391,9 @@ class DenseMap {
unsigned OldNumBuckets = NumBuckets; unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets; BucketT *OldBuckets = Buckets;
if (NumBuckets < 64)
NumBuckets = 64;
// Double the number of buckets. // Double the number of buckets.
while (NumBuckets < AtLeast) while (NumBuckets < AtLeast)
NumBuckets <<= 1; NumBuckets <<= 1;
@ -398,7 +425,8 @@ class DenseMap {
} }
#ifndef NDEBUG #ifndef NDEBUG
memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); if (OldNumBuckets)
memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
#endif #endif
// Free the old table. // Free the old table.
operator delete(OldBuckets); operator delete(OldBuckets);
@ -431,13 +459,22 @@ class DenseMap {
} }
#ifndef NDEBUG #ifndef NDEBUG
memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
#endif #endif
// Free the old table. // Free the old table.
operator delete(OldBuckets); operator delete(OldBuckets);
NumEntries = 0; NumEntries = 0;
} }
public:
/// Return the approximate size (in bytes) of the actual map.
/// This is just the raw memory used by DenseMap.
/// If entries are pointers to objects, the size of the referenced objects
/// are not included.
size_t getMemorySize() const {
return NumBuckets * sizeof(BucketT);
}
}; };
template<typename KeyT, typename ValueT, template<typename KeyT, typename ValueT,

View File

@ -157,7 +157,10 @@ struct DenseMapInfo<std::pair<T, U> > {
key ^= (key >> 31); key ^= (key >> 31);
return (unsigned)key; return (unsigned)key;
} }
static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
}
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -143,8 +143,7 @@ class df_iterator : public std::iterator<std::forward_iterator_tag,
static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); } static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
inline bool operator==(const _Self& x) const { inline bool operator==(const _Self& x) const {
return VisitStack.size() == x.VisitStack.size() && return VisitStack == x.VisitStack;
VisitStack == x.VisitStack;
} }
inline bool operator!=(const _Self& x) const { return !operator==(x); } inline bool operator!=(const _Self& x) const { return !operator==(x); }

View File

@ -209,10 +209,10 @@ template<typename T> struct FoldingSetTrait;
/// for FoldingSetTrait implementations. /// for FoldingSetTrait implementations.
/// ///
template<typename T> struct DefaultFoldingSetTrait { template<typename T> struct DefaultFoldingSetTrait {
static void Profile(const T& X, FoldingSetNodeID& ID) { static void Profile(const T &X, FoldingSetNodeID &ID) {
X.Profile(ID); X.Profile(ID);
} }
static void Profile(T& X, FoldingSetNodeID& ID) { static void Profile(T &X, FoldingSetNodeID &ID) {
X.Profile(ID); X.Profile(ID);
} }
@ -267,7 +267,7 @@ template<typename T, typename Ctx> struct ContextualFoldingSetTrait
/// is often much larger than necessary, and the possibility of heap /// is often much larger than necessary, and the possibility of heap
/// allocation means it requires a non-trivial destructor call. /// allocation means it requires a non-trivial destructor call.
class FoldingSetNodeIDRef { class FoldingSetNodeIDRef {
const unsigned* Data; const unsigned *Data;
size_t Size; size_t Size;
public: public:
FoldingSetNodeIDRef() : Data(0), Size(0) {} FoldingSetNodeIDRef() : Data(0), Size(0) {}
@ -310,9 +310,10 @@ class FoldingSetNodeID {
void AddInteger(unsigned long long I); void AddInteger(unsigned long long I);
void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); } void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
void AddString(StringRef String); void AddString(StringRef String);
void AddNodeID(const FoldingSetNodeID &ID);
template <typename T> template <typename T>
inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); } inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
/// clear - Clear the accumulated profile, allowing this FoldingSetNodeID /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
/// object to be used to compute a new profile. /// object to be used to compute a new profile.
@ -548,7 +549,7 @@ class FoldingSetIterator : public FoldingSetIteratorImpl {
return static_cast<T*>(NodePtr); return static_cast<T*>(NodePtr);
} }
inline FoldingSetIterator& operator++() { // Preincrement inline FoldingSetIterator &operator++() { // Preincrement
advance(); advance();
return *this; return *this;
} }
@ -596,10 +597,10 @@ class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
FoldingSetBucketIterator(void **Bucket, bool) : FoldingSetBucketIterator(void **Bucket, bool) :
FoldingSetBucketIteratorImpl(Bucket, true) {} FoldingSetBucketIteratorImpl(Bucket, true) {}
T& operator*() const { return *static_cast<T*>(Ptr); } T &operator*() const { return *static_cast<T*>(Ptr); }
T* operator->() const { return static_cast<T*>(Ptr); } T *operator->() const { return static_cast<T*>(Ptr); }
inline FoldingSetBucketIterator& operator++() { // Preincrement inline FoldingSetBucketIterator &operator++() { // Preincrement
advance(); advance();
return *this; return *this;
} }
@ -615,36 +616,36 @@ template <typename T>
class FoldingSetNodeWrapper : public FoldingSetNode { class FoldingSetNodeWrapper : public FoldingSetNode {
T data; T data;
public: public:
explicit FoldingSetNodeWrapper(const T& x) : data(x) {} explicit FoldingSetNodeWrapper(const T &x) : data(x) {}
virtual ~FoldingSetNodeWrapper() {} virtual ~FoldingSetNodeWrapper() {}
template<typename A1> template<typename A1>
explicit FoldingSetNodeWrapper(const A1& a1) explicit FoldingSetNodeWrapper(const A1 &a1)
: data(a1) {} : data(a1) {}
template <typename A1, typename A2> template <typename A1, typename A2>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2) explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2)
: data(a1,a2) {} : data(a1,a2) {}
template <typename A1, typename A2, typename A3> template <typename A1, typename A2, typename A3>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3) explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3)
: data(a1,a2,a3) {} : data(a1,a2,a3) {}
template <typename A1, typename A2, typename A3, typename A4> template <typename A1, typename A2, typename A3, typename A4>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
const A4& a4) const A4 &a4)
: data(a1,a2,a3,a4) {} : data(a1,a2,a3,a4) {}
template <typename A1, typename A2, typename A3, typename A4, typename A5> template <typename A1, typename A2, typename A3, typename A4, typename A5>
explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
const A4& a4, const A5& a5) const A4 &a4, const A5 &a5)
: data(a1,a2,a3,a4,a5) {} : data(a1,a2,a3,a4,a5) {}
void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); } void Profile(FoldingSetNodeID &ID) { FoldingSetTrait<T>::Profile(data, ID); }
T& getValue() { return data; } T &getValue() { return data; }
const T& getValue() const { return data; } const T &getValue() const { return data; }
operator T&() { return data; } operator T&() { return data; }
operator const T&() const { return data; } operator const T&() const { return data; }
@ -661,20 +662,22 @@ class FastFoldingSetNode : public FoldingSetNode {
protected: protected:
explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {} explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
public: public:
void Profile(FoldingSetNodeID& ID) const { ID = FastID; } void Profile(FoldingSetNodeID &ID) const {
ID.AddNodeID(FastID);
}
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Partial specializations of FoldingSetTrait. // Partial specializations of FoldingSetTrait.
template<typename T> struct FoldingSetTrait<T*> { template<typename T> struct FoldingSetTrait<T*> {
static inline void Profile(const T* X, FoldingSetNodeID& ID) { static inline void Profile(const T *X, FoldingSetNodeID &ID) {
ID.AddPointer(X); ID.AddPointer(X);
} }
}; };
template<typename T> struct FoldingSetTrait<const T*> { template<typename T> struct FoldingSetTrait<const T*> {
static inline void Profile(const T* X, FoldingSetNodeID& ID) { static inline void Profile(const T *X, FoldingSetNodeID &ID) {
ID.AddPointer(X); ID.AddPointer(X);
} }
}; };

View File

@ -10,6 +10,10 @@
// This file defines the ImmutableIntervalMap class. // This file defines the ImmutableIntervalMap class.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
#include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/ImmutableMap.h"
namespace llvm { namespace llvm {
@ -240,3 +244,5 @@ class ImmutableIntervalMap
}; };
} // end namespace llvm } // end namespace llvm
#endif

View File

@ -1328,6 +1328,10 @@ class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
/// const_iterator - Create an iterator that isn't pointing anywhere. /// const_iterator - Create an iterator that isn't pointing anywhere.
const_iterator() : map(0) {} const_iterator() : map(0) {}
/// setMap - Change the map iterated over. This call must be followed by a
/// call to goToBegin(), goToEnd(), or find()
void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); }
/// valid - Return true if the current position is valid, false for end(). /// valid - Return true if the current position is valid, false for end().
bool valid() const { return path.valid(); } bool valid() const { return path.valid(); }

View File

@ -42,18 +42,16 @@ namespace llvm {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
template <class Derived> template <class Derived>
class RefCountedBase { class RefCountedBase {
unsigned ref_cnt; mutable unsigned ref_cnt;
protected: public:
RefCountedBase() : ref_cnt(0) {} RefCountedBase() : ref_cnt(0) {}
void Retain() { ++ref_cnt; } void Retain() const { ++ref_cnt; }
void Release() { void Release() const {
assert (ref_cnt > 0 && "Reference count is already zero."); assert (ref_cnt > 0 && "Reference count is already zero.");
if (--ref_cnt == 0) delete static_cast<Derived*>(this); if (--ref_cnt == 0) delete static_cast<const Derived*>(this);
} }
friend class IntrusiveRefCntPtr<Derived>;
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -64,21 +62,21 @@ namespace llvm {
/// inherit from RefCountedBaseVPTR can't be allocated on stack - /// inherit from RefCountedBaseVPTR can't be allocated on stack -
/// attempting to do this will produce a compile error. /// attempting to do this will produce a compile error.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
template <class Derived>
class RefCountedBaseVPTR { class RefCountedBaseVPTR {
unsigned ref_cnt; mutable unsigned ref_cnt;
protected: protected:
RefCountedBaseVPTR() : ref_cnt(0) {} RefCountedBaseVPTR() : ref_cnt(0) {}
virtual ~RefCountedBaseVPTR() {} virtual ~RefCountedBaseVPTR() {}
void Retain() { ++ref_cnt; } void Retain() const { ++ref_cnt; }
void Release() { void Release() const {
assert (ref_cnt > 0 && "Reference count is already zero."); assert (ref_cnt > 0 && "Reference count is already zero.");
if (--ref_cnt == 0) delete this; if (--ref_cnt == 0) delete this;
} }
friend class IntrusiveRefCntPtr<Derived>; template <typename T>
friend class IntrusiveRefCntPtr;
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -155,6 +153,10 @@ namespace llvm {
other.Obj = Obj; other.Obj = Obj;
Obj = tmp; Obj = tmp;
} }
void resetWithoutRelease() {
Obj = 0;
}
private: private:
void retain() { if (Obj) Obj->Retain(); } void retain() { if (Obj) Obj->Retain(); }

View File

@ -19,16 +19,33 @@
namespace llvm { namespace llvm {
/// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return template <typename T>
/// false or true respectively. struct PointerUnionTypeSelectorReturn {
template <typename PT1, typename PT2> typedef T Return;
static inline int getPointerUnionTypeNum(PT1 *P) { return 0; } };
template <typename PT1, typename PT2>
static inline int getPointerUnionTypeNum(PT2 *P) { return 1; } /// \brief Get a type based on whether two types are the same or not. For:
template <typename PT1, typename PT2> /// @code
static inline int getPointerUnionTypeNum(...) { return -1; } /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
/// @endcode
/// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
struct PointerUnionTypeSelector {
typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
};
template <typename T, typename RET_EQ, typename RET_NE>
struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
};
template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
struct PointerUnionTypeSelectorReturn<
PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
Return;
};
/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
/// for the two template arguments. /// for the two template arguments.
template <typename PT1, typename PT2> template <typename PT1, typename PT2>
@ -65,6 +82,16 @@ namespace llvm {
PointerUnionUIntTraits<PT1,PT2> > ValTy; PointerUnionUIntTraits<PT1,PT2> > ValTy;
private: private:
ValTy Val; ValTy Val;
struct IsPT1 {
static const int Num = 0;
};
struct IsPT2 {
static const int Num = 1;
};
template <typename T>
struct UNION_DOESNT_CONTAIN_TYPE { };
public: public:
PointerUnion() {} PointerUnion() {}
@ -87,8 +114,11 @@ namespace llvm {
/// is<T>() return true if the Union currently holds the type matching T. /// is<T>() return true if the Union currently holds the type matching T.
template<typename T> template<typename T>
int is() const { int is() const {
int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); typedef typename
assert(TyNo != -1 && "Type query could never succeed on PointerUnion!"); ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
int TyNo = Ty::Num;
return static_cast<int>(Val.getInt()) == TyNo; return static_cast<int>(Val.getInt()) == TyNo;
} }
@ -175,6 +205,34 @@ namespace llvm {
typedef PointerUnion<InnerUnion, PT3> ValTy; typedef PointerUnion<InnerUnion, PT3> ValTy;
private: private:
ValTy Val; ValTy Val;
struct IsInnerUnion {
ValTy Val;
IsInnerUnion(ValTy val) : Val(val) { }
template<typename T>
int is() const {
return Val.template is<InnerUnion>() &&
Val.template get<InnerUnion>().template is<T>();
}
template<typename T>
T get() const {
return Val.template get<InnerUnion>().template get<T>();
}
};
struct IsPT3 {
ValTy Val;
IsPT3(ValTy val) : Val(val) { }
template<typename T>
int is() const {
return Val.template is<T>();
}
template<typename T>
T get() const {
return Val.template get<T>();
}
};
public: public:
PointerUnion3() {} PointerUnion3() {}
@ -196,11 +254,12 @@ namespace llvm {
/// is<T>() return true if the Union currently holds the type matching T. /// is<T>() return true if the Union currently holds the type matching T.
template<typename T> template<typename T>
int is() const { int is() const {
// Is it PT1/PT2? // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) typedef typename
return Val.template is<InnerUnion>() && ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
Val.template get<InnerUnion>().template is<T>(); ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
return Val.template is<T>(); >::Return Ty;
return Ty(Val).is<T>();
} }
/// get<T>() - Return the value of the specified pointer type. If the /// get<T>() - Return the value of the specified pointer type. If the
@ -208,11 +267,12 @@ namespace llvm {
template<typename T> template<typename T>
T get() const { T get() const {
assert(is<T>() && "Invalid accessor called"); assert(is<T>() && "Invalid accessor called");
// Is it PT1/PT2? // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) typedef typename
return Val.template get<InnerUnion>().template get<T>(); ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
return Val.template get<T>(); >::Return Ty;
return Ty(Val).get<T>();
} }
/// dyn_cast<T>() - If the current value is of the specified pointer type, /// dyn_cast<T>() - If the current value is of the specified pointer type,
@ -302,12 +362,13 @@ namespace llvm {
/// is<T>() return true if the Union currently holds the type matching T. /// is<T>() return true if the Union currently holds the type matching T.
template<typename T> template<typename T>
int is() const { int is() const {
// Is it PT1/PT2? // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) typedef typename
return Val.template is<InnerUnion1>() && ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
Val.template get<InnerUnion1>().template is<T>(); ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
return Val.template is<InnerUnion2>() && >::Return Ty;
Val.template get<InnerUnion2>().template is<T>(); return Val.template is<Ty>() &&
Val.template get<Ty>().template is<T>();
} }
/// get<T>() - Return the value of the specified pointer type. If the /// get<T>() - Return the value of the specified pointer type. If the
@ -315,11 +376,12 @@ namespace llvm {
template<typename T> template<typename T>
T get() const { T get() const {
assert(is<T>() && "Invalid accessor called"); assert(is<T>() && "Invalid accessor called");
// Is it PT1/PT2? // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) typedef typename
return Val.template get<InnerUnion1>().template get<T>(); ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
return Val.template get<InnerUnion2>().template get<T>(); >::Return Ty;
return Val.template get<Ty>().template get<T>();
} }
/// dyn_cast<T>() - If the current value is of the specified pointer type, /// dyn_cast<T>() - If the current value is of the specified pointer type,

View File

@ -96,6 +96,9 @@ class ScopedHashTableScope {
ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT); ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope(); ~ScopedHashTableScope();
ScopedHashTableScope *getParentScope() { return PrevScope; }
const ScopedHashTableScope *getParentScope() const { return PrevScope; }
private: private:
friend class ScopedHashTable<K, V, KInfo, AllocatorTy>; friend class ScopedHashTable<K, V, KInfo, AllocatorTy>;
ScopedHashTableVal<K, V> *getLastValInScope() { ScopedHashTableVal<K, V> *getLastValInScope() {
@ -141,9 +144,14 @@ class ScopedHashTableIterator {
template <typename K, typename V, typename KInfo, typename AllocatorTy> template <typename K, typename V, typename KInfo, typename AllocatorTy>
class ScopedHashTable { class ScopedHashTable {
public:
/// ScopeTy - This is a helpful typedef that allows clients to get easy access
/// to the name of the scope for this hash table.
typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
private:
typedef ScopedHashTableVal<K, V> ValTy; typedef ScopedHashTableVal<K, V> ValTy;
DenseMap<K, ValTy*, KInfo> TopLevelMap; DenseMap<K, ValTy*, KInfo> TopLevelMap;
ScopedHashTableScope<K, V, KInfo, AllocatorTy> *CurScope; ScopeTy *CurScope;
AllocatorTy Allocator; AllocatorTy Allocator;
@ -157,9 +165,6 @@ class ScopedHashTable {
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
} }
/// ScopeTy - This is a helpful typedef that allows clients to get easy access
/// to the name of the scope for this hash table.
typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
/// Access to the allocator. /// Access to the allocator.
typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy; typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy;
@ -180,13 +185,7 @@ class ScopedHashTable {
} }
void insert(const K &Key, const V &Val) { void insert(const K &Key, const V &Val) {
assert(CurScope && "No scope active!"); insertIntoScope(CurScope, Key, Val);
ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key];
KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val,
Allocator);
CurScope->setLastValInScope(KeyEntry);
} }
typedef ScopedHashTableIterator<K, V, KInfo> iterator; typedef ScopedHashTableIterator<K, V, KInfo> iterator;
@ -199,6 +198,21 @@ class ScopedHashTable {
if (I == TopLevelMap.end()) return end(); if (I == TopLevelMap.end()) return end();
return iterator(I->second); return iterator(I->second);
} }
ScopeTy *getCurScope() { return CurScope; }
const ScopeTy *getCurScope() const { return CurScope; }
/// insertIntoScope - This inserts the specified key/value at the specified
/// (possibly not the current) scope. While it is ok to insert into a scope
/// that isn't the current one, it isn't ok to insert *underneath* an existing
/// value of the specified key.
void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) {
assert(S && "No scope active!");
ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key];
KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val,
Allocator);
S->setLastValInScope(KeyEntry);
}
}; };
/// ScopedHashTableScope ctor - Install this as the current scope for the hash /// ScopedHashTableScope ctor - Install this as the current scope for the hash

View File

@ -133,7 +133,7 @@ class SmallPtrSetImpl {
void shrink_and_clear(); void shrink_and_clear();
/// Grow - Allocate a larger backing store for the buckets and move it over. /// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(); void Grow(unsigned NewSize);
void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT. void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
protected: protected:

View File

@ -121,6 +121,9 @@ class Statistic {
/// \brief Enable the collection and printing of statistics. /// \brief Enable the collection and printing of statistics.
void EnableStatistics(); void EnableStatistics();
/// \brief Check if statistics are enabled.
bool AreStatisticsEnabled();
/// \brief Print statistics to the file returned by CreateInfoOutputFile(). /// \brief Print statistics to the file returned by CreateInfoOutputFile().
void PrintStatistics(); void PrintStatistics();

View File

@ -20,7 +20,6 @@
#include <cctype> #include <cctype>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <vector>
namespace llvm { namespace llvm {
template<typename T> class SmallVectorImpl; template<typename T> class SmallVectorImpl;
@ -153,7 +152,7 @@ void SplitString(StringRef Source,
SmallVectorImpl<StringRef> &OutFragments, SmallVectorImpl<StringRef> &OutFragments,
StringRef Delimiters = " \t\n\v\f\r"); StringRef Delimiters = " \t\n\v\f\r");
/// HashString - Hash funtion for strings. /// HashString - Hash function for strings.
/// ///
/// This is the Bernstein hash function. /// This is the Bernstein hash function.
// //

View File

@ -17,7 +17,6 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include <cstring> #include <cstring>
#include <string>
namespace llvm { namespace llvm {
template<typename ValueT> template<typename ValueT>
@ -81,16 +80,6 @@ class StringMapImpl {
StringMapImpl(unsigned InitSize, unsigned ItemSize); StringMapImpl(unsigned InitSize, unsigned ItemSize);
void RehashTable(); void RehashTable();
/// ShouldRehash - Return true if the table should be rehashed after a new
/// element was recently inserted.
bool ShouldRehash() const {
// If the hash table is now more than 3/4 full, or if fewer than 1/8 of
// the buckets are empty (meaning that many are filled with tombstones),
// grow the table.
return NumItems*4 > NumBuckets*3 ||
NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
}
/// LookupBucketFor - Look up the bucket that the specified string should end /// LookupBucketFor - Look up the bucket that the specified string should end
/// up in. If it already exists as a key in the map, the Item pointer for the /// up in. If it already exists as a key in the map, the Item pointer for the
/// specified bucket will be non-null. Otherwise, it will be null. In either /// specified bucket will be non-null. Otherwise, it will be null. In either
@ -339,9 +328,9 @@ class StringMap : public StringMapImpl {
--NumTombstones; --NumTombstones;
Bucket.Item = KeyValue; Bucket.Item = KeyValue;
++NumItems; ++NumItems;
assert(NumItems + NumTombstones <= NumBuckets);
if (ShouldRehash()) RehashTable();
RehashTable();
return true; return true;
} }
@ -359,6 +348,7 @@ class StringMap : public StringMapImpl {
} }
NumItems = 0; NumItems = 0;
NumTombstones = 0;
} }
/// GetOrCreateValue - Look up the specified key in the table. If a value /// GetOrCreateValue - Look up the specified key in the table. If a value
@ -378,13 +368,13 @@ class StringMap : public StringMapImpl {
if (Bucket.Item == getTombstoneVal()) if (Bucket.Item == getTombstoneVal())
--NumTombstones; --NumTombstones;
++NumItems; ++NumItems;
assert(NumItems + NumTombstones <= NumBuckets);
// Fill in the bucket for the hash table. The FullHashValue was already // Fill in the bucket for the hash table. The FullHashValue was already
// filled in by LookupBucketFor. // filled in by LookupBucketFor.
Bucket.Item = NewItem; Bucket.Item = NewItem;
if (ShouldRehash()) RehashTable();
RehashTable();
return *NewItem; return *NewItem;
} }

View File

@ -64,7 +64,8 @@ class Triple {
x86_64, // X86-64: amd64, x86_64 x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore xcore, // XCore: xcore
mblaze, // MBlaze: mblaze mblaze, // MBlaze: mblaze
ptx, // PTX: ptx ptx32, // PTX: ptx (32-bit)
ptx64, // PTX: ptx (64-bit)
InvalidArch InvalidArch
}; };
@ -72,7 +73,8 @@ class Triple {
UnknownVendor, UnknownVendor,
Apple, Apple,
PC PC,
SCEI
}; };
enum OSType { enum OSType {
UnknownOS, UnknownOS,
@ -82,8 +84,10 @@ class Triple {
Darwin, Darwin,
DragonFly, DragonFly,
FreeBSD, FreeBSD,
IOS,
Linux, Linux,
Lv2, // PS3 Lv2, // PS3
MacOSX,
MinGW32, // i*86-pc-mingw32, *-w64-mingw32 MinGW32, // i*86-pc-mingw32, *-w64-mingw32
NetBSD, NetBSD,
OpenBSD, OpenBSD,
@ -221,21 +225,81 @@ class Triple {
/// if the environment component is present). /// if the environment component is present).
StringRef getOSAndEnvironmentName() const; StringRef getOSAndEnvironmentName() const;
/// getOSNumber - Parse the version number from the OS name component of the
/// triple, if present.
///
/// For example, "fooos1.2.3" would return (1, 2, 3).
///
/// If an entry is not defined, it will be returned as 0.
void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
/// getDarwinNumber - Parse the 'darwin number' out of the specific target /// getOSMajorVersion - Return just the major version number, this is
/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
/// not defined, return 0's. This requires that the triple have an OSType of
/// darwin before it is called.
void getDarwinNumber(unsigned &Maj, unsigned &Min, unsigned &Revision) const;
/// getDarwinMajorNumber - Return just the major version number, this is
/// specialized because it is a common query. /// specialized because it is a common query.
unsigned getDarwinMajorNumber() const { unsigned getOSMajorVersion() const {
unsigned Maj, Min, Rev; unsigned Maj, Min, Micro;
getDarwinNumber(Maj, Min, Rev); getDarwinNumber(Maj, Min, Micro);
return Maj; return Maj;
} }
void getDarwinNumber(unsigned &Major, unsigned &Minor,
unsigned &Micro) const {
return getOSVersion(Major, Minor, Micro);
}
unsigned getDarwinMajorNumber() const {
return getOSMajorVersion();
}
/// isOSVersionLT - Helper function for doing comparisons against version
/// numbers included in the target triple.
bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
unsigned Micro = 0) const {
unsigned LHS[3];
getOSVersion(LHS[0], LHS[1], LHS[2]);
if (LHS[0] != Major)
return LHS[0] < Major;
if (LHS[1] != Minor)
return LHS[1] < Minor;
if (LHS[2] != Micro)
return LHS[1] < Micro;
return false;
}
/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
/// "darwin" and "osx" as OS X triples.
bool isMacOSX() const {
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
}
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const {
return isMacOSX() ||getOS() == Triple::IOS;
}
/// isOSWindows - Is this a "Windows" OS.
bool isOSWindows() const {
return getOS() == Triple::Win32 || getOS() == Triple::Cygwin ||
getOS() == Triple::MinGW32;
}
/// isMacOSXVersionLT - Comparison function for checking OS X version
/// compatibility, which handles supporting skewed version numbering schemes
/// used by the "darwin" triples.
unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
unsigned Micro = 0) const {
assert(isMacOSX() && "Not an OS X triple!");
// If this is OS X, expect a sane version number.
if (getOS() == Triple::MacOSX)
return isOSVersionLT(Major, Minor, Micro);
// Otherwise, compare to the "Darwin" number.
assert(Major == 10 && "Unexpected major version");
return isOSVersionLT(Minor + 4, Micro, 0);
}
/// @} /// @}
/// @name Mutators /// @name Mutators
/// @{ /// @{

View File

@ -289,7 +289,7 @@ template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
/// iplist - The subset of list functionality that can safely be used on nodes /// iplist - The subset of list functionality that can safely be used on nodes
/// of polymorphic types, i.e. a heterogenous list with a common base class that /// of polymorphic types, i.e. a heterogeneous list with a common base class that
/// holds the next/prev pointers. The only state of the list itself is a single /// holds the next/prev pointers. The only state of the list itself is a single
/// pointer to the head of the list. /// pointer to the head of the list.
/// ///

View File

@ -38,7 +38,6 @@
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
#include "llvm/Support/CallSite.h" #include "llvm/Support/CallSite.h"
#include <vector>
namespace llvm { namespace llvm {

View File

@ -259,6 +259,7 @@ class AliasSet : public ilist_node<AliasSet> {
if (CallSites[i] == CS.getInstruction()) { if (CallSites[i] == CS.getInstruction()) {
CallSites[i] = CallSites.back(); CallSites[i] = CallSites.back();
CallSites.pop_back(); CallSites.pop_back();
--i; --e; // Revisit the moved entry.
} }
} }
void setVolatile() { Volatile = true; } void setVolatile() { Volatile = true; }
@ -283,6 +284,7 @@ class AliasSetTracker {
class ASTCallbackVH : public CallbackVH { class ASTCallbackVH : public CallbackVH {
AliasSetTracker *AST; AliasSetTracker *AST;
virtual void deleted(); virtual void deleted();
virtual void allUsesReplacedWith(Value *);
public: public:
ASTCallbackVH(Value *V, AliasSetTracker *AST = 0); ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
ASTCallbackVH &operator=(Value *V); ASTCallbackVH &operator=(Value *V);

View File

@ -15,6 +15,7 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H #ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H #define LLVM_ANALYSIS_CFGPRINTER_H
#include "llvm/Constants.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"

View File

@ -16,6 +16,7 @@
#define LLVM_ANALYSIS_DIBUILDER_H #define LLVM_ANALYSIS_DIBUILDER_H
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
namespace llvm { namespace llvm {
@ -146,6 +147,30 @@ namespace llvm {
uint64_t AlignInBits, uint64_t OffsetInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty); unsigned Flags, DIType Ty);
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
/// @param Name Member name.
/// @param File File where this member is defined.
/// @param LineNo Line number.
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
/// @param PropertyName Name of the Objective C property assoicated with
/// this ivar.
/// @param GetterName Name of the Objective C property getter selector.
/// @param SetterName Name of the Objective C property setter selector.
/// @param PropertyAttributes Objective C property attributes.
DIType createObjCIVar(StringRef Name, DIFile File,
unsigned LineNo, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty,
StringRef PropertyName = StringRef(),
StringRef PropertyGetterName = StringRef(),
StringRef PropertySetterName = StringRef(),
unsigned PropertyAttributes = 0);
/// createClassType - Create debugging information entry for a class. /// createClassType - Create debugging information entry for a class.
/// @param Scope Scope in which this class is defined. /// @param Scope Scope in which this class is defined.
/// @param Name class name. /// @param Name class name.
@ -278,7 +303,7 @@ namespace llvm {
DIDescriptor createUnspecifiedParameter(); DIDescriptor createUnspecifiedParameter();
/// getOrCreateArray - Get a DIArray, create one if required. /// getOrCreateArray - Get a DIArray, create one if required.
DIArray getOrCreateArray(Value *const *Elements, unsigned NumElements); DIArray getOrCreateArray(ArrayRef<Value *> Elements);
/// getOrCreateSubrange - Create a descriptor for a value range. This /// getOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned. /// implicitly uniques the values returned.
@ -326,11 +351,14 @@ namespace llvm {
/// @param AlwaysPreserve Boolean. Set to true if debug info for this /// @param AlwaysPreserve Boolean. Set to true if debug info for this
/// variable should be preserved in optimized build. /// variable should be preserved in optimized build.
/// @param Flags Flags, e.g. artificial variable. /// @param Flags Flags, e.g. artificial variable.
/// @param ArgNo If this variable is an arugment then this argument's
/// number. 1 indicates 1st argument.
DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope, DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, StringRef Name,
DIFile File, unsigned LineNo, DIFile File, unsigned LineNo,
DIType Ty, bool AlwaysPreserve = false, DIType Ty, bool AlwaysPreserve = false,
unsigned Flags = 0); unsigned Flags = 0,
unsigned ArgNo = 0);
/// createComplexVariable - Create a new descriptor for the specified /// createComplexVariable - Create a new descriptor for the specified
@ -342,12 +370,13 @@ namespace llvm {
/// @param File File where this variable is defined. /// @param File File where this variable is defined.
/// @param LineNo Line number. /// @param LineNo Line number.
/// @param Ty Variable Type /// @param Ty Variable Type
/// @param Addr A pointer to a vector of complex address operations. /// @param Addr An array of complex address operations.
/// @param NumAddr Num of address operations in the vector. /// @param ArgNo If this variable is an arugment then this argument's
/// number. 1 indicates 1st argument.
DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope, DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIFile F, unsigned LineNo, StringRef Name, DIFile F, unsigned LineNo,
DIType Ty, Value *const *Addr, DIType Ty, ArrayRef<Value *> Addr,
unsigned NumAddr); unsigned ArgNo = 0);
/// createFunction - Create a new descriptor for the specified subprogram. /// createFunction - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields. /// See comments in DISubprogram for descriptions of these fields.
@ -363,6 +392,7 @@ namespace llvm {
/// This flags are used to emit dwarf attributes. /// This flags are used to emit dwarf attributes.
/// @param isOptimized True if optimization is ON. /// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer. /// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
DISubprogram createFunction(DIDescriptor Scope, StringRef Name, DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
StringRef LinkageName, StringRef LinkageName,
DIFile File, unsigned LineNo, DIFile File, unsigned LineNo,
@ -370,7 +400,9 @@ namespace llvm {
bool isDefinition, bool isDefinition,
unsigned Flags = 0, unsigned Flags = 0,
bool isOptimized = false, bool isOptimized = false,
Function *Fn = 0); Function *Fn = 0,
MDNode *TParam = 0,
MDNode *Decl = 0);
/// createMethod - Create a new descriptor for the specified C++ method. /// createMethod - Create a new descriptor for the specified C++ method.
/// See comments in DISubprogram for descriptions of these fields. /// See comments in DISubprogram for descriptions of these fields.
@ -382,7 +414,7 @@ namespace llvm {
/// @param Ty Function type. /// @param Ty Function type.
/// @param isLocalToUnit True if this function is not externally visible.. /// @param isLocalToUnit True if this function is not externally visible..
/// @param isDefinition True if this is a function definition. /// @param isDefinition True if this is a function definition.
/// @param Virtuality Attributes describing virutallness. e.g. pure /// @param Virtuality Attributes describing virtualness. e.g. pure
/// virtual function. /// virtual function.
/// @param VTableIndex Index no of this method in virtual table. /// @param VTableIndex Index no of this method in virtual table.
/// @param VTableHolder Type that holds vtable. /// @param VTableHolder Type that holds vtable.
@ -390,6 +422,7 @@ namespace llvm {
/// This flags are used to emit dwarf attributes. /// This flags are used to emit dwarf attributes.
/// @param isOptimized True if optimization is ON. /// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer. /// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
DISubprogram createMethod(DIDescriptor Scope, StringRef Name, DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
StringRef LinkageName, StringRef LinkageName,
DIFile File, unsigned LineNo, DIFile File, unsigned LineNo,
@ -399,7 +432,8 @@ namespace llvm {
MDNode *VTableHolder = 0, MDNode *VTableHolder = 0,
unsigned Flags = 0, unsigned Flags = 0,
bool isOptimized = false, bool isOptimized = false,
Function *Fn = 0); Function *Fn = 0,
MDNode *TParam = 0);
/// createNameSpace - This creates new descriptor for a namespace /// createNameSpace - This creates new descriptor for a namespace
/// with the specified parent scope. /// with the specified parent scope.

View File

@ -332,6 +332,32 @@ namespace llvm {
/// return base type size. /// return base type size.
uint64_t getOriginalTypeSize() const; uint64_t getOriginalTypeSize() const;
StringRef getObjCPropertyName() const { return getStringField(10); }
StringRef getObjCPropertyGetterName() const {
return getStringField(11);
}
StringRef getObjCPropertySetterName() const {
return getStringField(12);
}
bool isReadOnlyObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
}
bool isReadWriteObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
}
bool isAssignObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
}
bool isRetainObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
}
bool isCopyObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
}
bool isNonAtomicObjCProperty() {
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
}
/// Verify - Verify that a derived type descriptor is well formed. /// Verify - Verify that a derived type descriptor is well formed.
bool Verify() const; bool Verify() const;
@ -511,6 +537,10 @@ namespace llvm {
bool describes(const Function *F); bool describes(const Function *F);
Function *getFunction() const { return getFunctionField(16); } Function *getFunction() const { return getFunctionField(16); }
DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
DISubprogram getFunctionDeclaration() const {
return getFieldAs<DISubprogram>(18);
}
}; };
/// DIGlobalVariable - This is a wrapper for a global variable. /// DIGlobalVariable - This is a wrapper for a global variable.
@ -564,7 +594,13 @@ namespace llvm {
DIFile F = getFieldAs<DIFile>(3); DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit(); return F.getCompileUnit();
} }
unsigned getLineNumber() const { return getUnsignedField(4); } unsigned getLineNumber() const {
return (getUnsignedField(4) << 8) >> 8;
}
unsigned getArgNumber() const {
unsigned L = getUnsignedField(4);
return L >> 24;
}
DIType getType() const { return getFieldAs<DIType>(5); } DIType getType() const { return getFieldAs<DIType>(5); }
/// isArtificial - Return true if this variable is marked as "artificial". /// isArtificial - Return true if this variable is marked as "artificial".
@ -586,7 +622,9 @@ namespace llvm {
unsigned getNumAddrElements() const; unsigned getNumAddrElements() const;
uint64_t getAddrElement(unsigned Idx) const { uint64_t getAddrElement(unsigned Idx) const {
return getUInt64Field(Idx+6); if (getVersion() <= llvm::LLVMDebugVersion8)
return getUInt64Field(Idx+6);
return getUInt64Field(Idx+7);
} }
/// isBlockByrefVariable - Return true if the variable was declared as /// isBlockByrefVariable - Return true if the variable was declared as
@ -660,214 +698,6 @@ namespace llvm {
bool Verify() const; bool Verify() const;
}; };
/// DIFactory - This object assists with the construction of the various
/// descriptors.
class DIFactory {
Module &M;
LLVMContext& VMContext;
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
DIFactory(const DIFactory &); // DO NOT IMPLEMENT
void operator=(const DIFactory&); // DO NOT IMPLEMENT
public:
enum ComplexAddrKind { OpPlus=1, OpDeref };
explicit DIFactory(Module &m);
/// GetOrCreateArray - Create an descriptor for an array of descriptors.
/// This implicitly uniques the arrays created.
DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
/// GetOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned.
DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi);
/// CreateUnspecifiedParameter - Create unspeicified type descriptor
/// for a subroutine type.
DIDescriptor CreateUnspecifiedParameter();
/// CreateCompileUnit - Create a new descriptor for the specified compile
/// unit.
DICompileUnit CreateCompileUnit(unsigned LangID,
StringRef Filename,
StringRef Directory,
StringRef Producer,
bool isMain = false,
bool isOptimized = false,
StringRef Flags = "",
unsigned RunTimeVer = 0);
/// CreateFile - Create a new descriptor for the specified file.
DIFile CreateFile(StringRef Filename, StringRef Directory,
DICompileUnit CU);
/// CreateEnumerator - Create a single enumerator value.
DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
DIFile F, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
unsigned Encoding);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
DIFile F, unsigned LineNumber,
Constant *SizeInBits, Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
unsigned Encoding);
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom);
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
unsigned RunTimeLang = 0,
MDNode *ContainingType = 0);
/// CreateTemporaryType - Create a temporary forward-declared type.
DIType CreateTemporaryType();
DIType CreateTemporaryType(DIFile F);
/// CreateArtificialType - Create a new DIType with "artificial" flag set.
DIType CreateArtificialType(DIType Ty);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
Constant *OffsetInBits,
unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
unsigned RunTimeLang = 0,
MDNode *ContainingType = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DIFile F, unsigned LineNo,
DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
DIType ContainingType = DIType(),
unsigned Flags = 0,
bool isOptimized = false,
Function *Fn = 0);
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
/// given declaration.
DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration);
/// CreateGlobalVariable - Create a new descriptor for the specified global.
DIGlobalVariable
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DIFile F,
unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
/// CreateGlobalVariable - Create a new descriptor for the specified constant.
DIGlobalVariable
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DIFile F,
unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::Constant *C);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DIFile F, unsigned LineNo,
DIType Ty, bool AlwaysPreserve = false,
unsigned Flags = 0);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
StringRef Name, DIFile F, unsigned LineNo,
DIType Ty, Value *const *Addr,
unsigned NumAddr);
/// CreateLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
unsigned Line = 0, unsigned Col = 0);
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
DIFile F, unsigned LineNo);
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
DIScope S, DILocation OrigLoc);
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
DIScope S, MDNode *OrigLoc = 0);
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
BasicBlock *InsertAtEnd);
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
Instruction *InsertBefore);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
DIVariable D, BasicBlock *InsertAtEnd);
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
DIVariable D, Instruction *InsertBefore);
// RecordType - Record DIType in a module such that it is not lost even if
// it is not referenced through debug info anchors.
void RecordType(DIType T);
private:
Constant *GetTagConstant(unsigned TAG);
};
/// getDISubprogram - Find subprogram that is enclosing this scope. /// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope); DISubprogram getDISubprogram(const MDNode *Scope);

View File

@ -28,6 +28,7 @@ class IVUsers;
class ScalarEvolution; class ScalarEvolution;
class SCEV; class SCEV;
class IVUsers; class IVUsers;
class TargetData;
/// IVStrideUse - Keep track of one use of a strided induction variable. /// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user /// The Expr member keeps track of the expression, User is the actual user
@ -122,6 +123,7 @@ class IVUsers : public LoopPass {
LoopInfo *LI; LoopInfo *LI;
DominatorTree *DT; DominatorTree *DT;
ScalarEvolution *SE; ScalarEvolution *SE;
TargetData *TD;
SmallPtrSet<Instruction*,16> Processed; SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions /// IVUses - A list of all tracked IV uses of induction variable expressions

View File

@ -43,7 +43,7 @@ namespace llvm {
/// InlineCost - Represent the cost of inlining a function. This /// InlineCost - Represent the cost of inlining a function. This
/// supports special values for functions which should "always" or /// supports special values for functions which should "always" or
/// "never" be inlined. Otherwise, the cost represents a unitless /// "never" be inlined. Otherwise, the cost represents a unitless
/// amount; smaller values increase the likelyhood of the function /// amount; smaller values increase the likelihood of the function
/// being inlined. /// being inlined.
class InlineCost { class InlineCost {
enum Kind { enum Kind {

View File

@ -55,6 +55,21 @@ namespace llvm {
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0, Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0); const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can /// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null. /// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,

View File

@ -20,8 +20,6 @@
#ifndef LLVM_ANALYSIS_LINT_H #ifndef LLVM_ANALYSIS_LINT_H
#define LLVM_ANALYSIS_LINT_H #define LLVM_ANALYSIS_LINT_H
#include <string>
namespace llvm { namespace llvm {
class FunctionPass; class FunctionPass;

View File

@ -1,99 +0,0 @@
//===- LiveValues.h - Liveness information for LLVM IR Values. ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for the LLVM IR Value liveness
// analysis pass.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LIVEVALUES_H
#define LLVM_ANALYSIS_LIVEVALUES_H
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
class DominatorTree;
class LoopInfo;
class Value;
/// LiveValues - Analysis that provides liveness information for
/// LLVM IR Values.
///
class LiveValues : public FunctionPass {
DominatorTree *DT;
LoopInfo *LI;
/// Memo - A bunch of state to be associated with a value.
///
struct Memo {
/// Used - The set of blocks which contain a use of the value.
///
SmallPtrSet<const BasicBlock *, 4> Used;
/// LiveThrough - A conservative approximation of the set of blocks in
/// which the value is live-through, meaning blocks properly dominated
/// by the definition, and from which blocks containing uses of the
/// value are reachable.
///
SmallPtrSet<const BasicBlock *, 4> LiveThrough;
/// Killed - A conservative approximation of the set of blocks in which
/// the value is used and not live-out.
///
SmallPtrSet<const BasicBlock *, 4> Killed;
};
/// Memos - Remembers the Memo for each Value. This is populated on
/// demand.
///
DenseMap<const Value *, Memo> Memos;
/// getMemo - Retrieve an existing Memo for the given value if one
/// is available, otherwise compute a new one.
///
Memo &getMemo(const Value *V);
/// compute - Compute a new Memo for the given value.
///
Memo &compute(const Value *V);
public:
static char ID;
LiveValues();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
/// isUsedInBlock - Test if the given value is used in the given block.
///
bool isUsedInBlock(const Value *V, const BasicBlock *BB);
/// isLiveThroughBlock - Test if the given value is known to be
/// live-through the given block, meaning that the block is properly
/// dominated by the value's definition, and there exists a block
/// reachable from it that contains a use. This uses a conservative
/// approximation that errs on the side of returning false.
///
bool isLiveThroughBlock(const Value *V, const BasicBlock *BB);
/// isKilledInBlock - Test if the given value is known to be killed in
/// the given block, meaning that the block contains a use of the value,
/// and no blocks reachable from the block contain a use. This uses a
/// conservative approximation that errs on the side of returning false.
///
bool isKilledInBlock(const Value *V, const BasicBlock *BB);
};
} // end namespace llvm
#endif

View File

@ -48,6 +48,11 @@ namespace llvm {
/// this occurs when we see a may-aliased store to the memory location we /// this occurs when we see a may-aliased store to the memory location we
/// care about. /// care about.
/// ///
/// There are several cases that may be interesting here:
/// 1. Loads are clobbered by may-alias stores.
/// 2. Loads are considered clobbered by partially-aliased loads. The
/// client may choose to analyze deeper into these cases.
///
/// A dependence query on the first instruction of the entry block will /// A dependence query on the first instruction of the entry block will
/// return a clobber(self) result. /// return a clobber(self) result.
Clobber, Clobber,
@ -350,6 +355,20 @@ namespace llvm {
BasicBlock::iterator ScanIt, BasicBlock::iterator ScanIt,
BasicBlock *BB); BasicBlock *BB);
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
/// looks at a memory location for a load (specified by MemLocBase, Offs,
/// and Size) and compares it against a load. If the specified load could
/// be safely widened to a larger integer load that is 1) still efficient,
/// 2) safe for the target, and 3) would provide the specified memory
/// location value, then this function returns the size in bytes of the
/// load width to use. If not, this returns zero.
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
const TargetData &TD);
private: private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt, BasicBlock::iterator ScanIt,

View File

@ -157,12 +157,6 @@ namespace llvm {
// //
ModulePass *createSteensgaardPass(); ModulePass *createSteensgaardPass();
//===--------------------------------------------------------------------===//
//
// createLiveValuesPass - This creates an instance of the LiveValues pass.
//
FunctionPass *createLiveValuesPass();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
/// createLazyValueInfoPass - This creates an instance of the LazyValueInfo /// createLazyValueInfoPass - This creates an instance of the LazyValueInfo

View File

@ -16,7 +16,6 @@
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "llvm/Analysis/PathNumbering.h" #include "llvm/Analysis/PathNumbering.h"
#include <stack>
namespace llvm { namespace llvm {

View File

@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H #ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
#define LLVM_ANALYSIS_POST_DOMINATORS_H #define LLVM_ANALYSIS_POST_DOMINATORS_H
#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/Dominators.h"
namespace llvm { namespace llvm {
@ -101,37 +101,6 @@ template <> struct GraphTraits<PostDominatorTree*>
} }
}; };
/// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
/// used to compute the a post-dominance frontier.
///
struct PostDominanceFrontier : public DominanceFrontierBase {
static char ID;
PostDominanceFrontier()
: DominanceFrontierBase(ID, true) {
initializePostDominanceFrontierPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnFunction(Function &) {
Frontiers.clear();
PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
Roots = DT.getRoots();
if (const DomTreeNode *Root = DT.getRootNode())
calculate(DT, Root);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<PostDominatorTree>();
}
private:
const DomSetType &calculate(const PostDominatorTree &DT,
const DomTreeNode *Node);
};
FunctionPass* createPostDomFrontier();
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -28,9 +28,10 @@
#define LLVM_ANALYSIS_REGION_INFO_H #define LLVM_ANALYSIS_REGION_INFO_H
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include <map>
namespace llvm { namespace llvm {
@ -145,7 +146,7 @@ inline Region* RegionNode::getNodeAs<Region>() const {
/// two connections to the remaining graph. It can be used to analyze or /// two connections to the remaining graph. It can be used to analyze or
/// optimize parts of the control flow graph. /// optimize parts of the control flow graph.
/// ///
/// A <em> simple Region </em> is connected to the remaing graph by just two /// A <em> simple Region </em> is connected to the remaining graph by just two
/// edges. One edge entering the Region and another one leaving the Region. /// edges. One edge entering the Region and another one leaving the Region.
/// ///
/// An <em> extended Region </em> (or just Region) is a subgraph that can be /// An <em> extended Region </em> (or just Region) is a subgraph that can be
@ -335,12 +336,16 @@ class Region : public RegionNode {
return RI; return RI;
} }
/// PrintStyle - Print region in difference ways.
enum PrintStyle { PrintNone, PrintBB, PrintRN };
/// @brief Print the region. /// @brief Print the region.
/// ///
/// @param OS The output stream the Region is printed to. /// @param OS The output stream the Region is printed to.
/// @param printTree Print also the tree of subregions. /// @param printTree Print also the tree of subregions.
/// @param level The indentation level used for printing. /// @param level The indentation level used for printing.
void print(raw_ostream& OS, bool printTree = true, unsigned level = 0) const; void print(raw_ostream& OS, bool printTree = true, unsigned level = 0,
enum PrintStyle Style = PrintNone) const;
/// @brief Print the region to stderr. /// @brief Print the region to stderr.
void dump() const; void dump() const;
@ -438,7 +443,7 @@ class Region : public RegionNode {
/// @brief Move all direct child nodes of this Region to another Region. /// @brief Move all direct child nodes of this Region to another Region.
/// ///
/// @param To The Region the child nodes will be transfered to. /// @param To The Region the child nodes will be transferred to.
void transferChildrenTo(Region *To); void transferChildrenTo(Region *To);
/// @brief Verify if the region is a correct region. /// @brief Verify if the region is a correct region.

View File

@ -20,7 +20,7 @@
namespace llvm { namespace llvm {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// @brief Hierachical RegionNode successor iterator. /// @brief Hierarchical RegionNode successor iterator.
/// ///
/// This iterator iterates over all successors of a RegionNode. /// This iterator iterates over all successors of a RegionNode.
/// ///

View File

@ -54,7 +54,7 @@ class RegionPass : public Pass {
/// @brief Get a pass to print the LLVM IR in the region. /// @brief Get a pass to print the LLVM IR in the region.
/// ///
/// @param O The ouput stream to print the Region. /// @param O The ouput stream to print the Region.
/// @param Banner The banner to seperate different printed passes. /// @param Banner The banner to separate different printed passes.
/// ///
/// @return The pass to print the LLVM IR in the region. /// @return The pass to print the LLVM IR in the region.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;

View File

@ -24,6 +24,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Operator.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h" #include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
@ -72,6 +73,29 @@ namespace llvm {
void operator=(const SCEV &); // DO NOT IMPLEMENT void operator=(const SCEV &); // DO NOT IMPLEMENT
public: public:
/// NoWrapFlags are bitfield indices into SubclassData.
///
/// Add and Mul expressions may have no-unsigned-wrap <NUW> or
/// no-signed-wrap <NSW> properties, which are derived from the IR
/// operator. NSW is a misnomer that we use to mean no signed overflow or
/// underflow.
///
/// AddRec expression may have a no-self-wraparound <NW> property if the
/// result can never reach the start value. This property is independent of
/// the actual start value and step direction. Self-wraparound is defined
/// purely in terms of the recurrence's loop, step size, and
/// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
/// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
///
/// Note that NUW and NSW are also valid properties of a recurrence, and
/// either implies NW. For convenience, NW will be set for a recurrence
/// whenever either NUW or NSW are set.
enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee.
FlagNW = (1 << 0), // No self-wrap.
FlagNUW = (1 << 1), // No unsigned wrap.
FlagNSW = (1 << 2), // No signed wrap.
NoWrapMask = (1 << 3) -1 };
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) : explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {} FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
@ -159,6 +183,20 @@ namespace llvm {
ProperlyDominatesBlock ///< The SCEV properly dominates the block. ProperlyDominatesBlock ///< The SCEV properly dominates the block.
}; };
/// Convenient NoWrapFlags manipulation that hides enum casts and is
/// visible in the ScalarEvolution name space.
static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) {
return (SCEV::NoWrapFlags)(Flags & Mask);
}
static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OnFlags) {
return (SCEV::NoWrapFlags)(Flags | OnFlags);
}
static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OffFlags) {
return (SCEV::NoWrapFlags)(Flags & ~OffFlags);
}
private: private:
/// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
/// notified whenever a Value is deleted. /// notified whenever a Value is deleted.
@ -465,44 +503,41 @@ namespace llvm {
const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops, const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW = false, bool HasNSW = false); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 2> Ops; SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS); Ops.push_back(LHS);
Ops.push_back(RHS); Ops.push_back(RHS);
return getAddExpr(Ops, HasNUW, HasNSW); return getAddExpr(Ops, Flags);
} }
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
const SCEV *Op2, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
bool HasNUW = false, bool HasNSW = false) {
SmallVector<const SCEV *, 3> Ops; SmallVector<const SCEV *, 3> Ops;
Ops.push_back(Op0); Ops.push_back(Op0);
Ops.push_back(Op1); Ops.push_back(Op1);
Ops.push_back(Op2); Ops.push_back(Op2);
return getAddExpr(Ops, HasNUW, HasNSW); return getAddExpr(Ops, Flags);
} }
const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops, const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW = false, bool HasNSW = false); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap)
{
SmallVector<const SCEV *, 2> Ops; SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS); Ops.push_back(LHS);
Ops.push_back(RHS); Ops.push_back(RHS);
return getMulExpr(Ops, HasNUW, HasNSW); return getMulExpr(Ops, Flags);
} }
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
const Loop *L, const Loop *L, SCEV::NoWrapFlags Flags);
bool HasNUW = false, bool HasNSW = false);
const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
const Loop *L, const Loop *L, SCEV::NoWrapFlags Flags);
bool HasNUW = false, bool HasNSW = false);
const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands, const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands,
const Loop *L, const Loop *L, SCEV::NoWrapFlags Flags) {
bool HasNUW = false, bool HasNSW = false) {
SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end()); SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, HasNUW, HasNSW); return getAddRecExpr(NewOp, L, Flags);
} }
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands); const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
@ -537,11 +572,9 @@ namespace llvm {
/// ///
const SCEV *getNotSCEV(const SCEV *V); const SCEV *getNotSCEV(const SCEV *V);
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1, /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
/// and thus the HasNUW and HasNSW bits apply to the resultant add, not
/// whether the sub would have overflowed.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be /// of the input value to the specified type. If the type must be
@ -586,6 +619,12 @@ namespace llvm {
const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS,
const SCEV *RHS); const SCEV *RHS);
/// getPointerBase - Transitively follow the chain of pointer-type operands
/// until reaching a SCEV that does not have a single pointer operand. This
/// returns a SCEVUnknown pointer for well-formed pointer-type expressions,
/// but corner cases do exist.
const SCEV *getPointerBase(const SCEV *V);
/// getSCEVAtScope - Return a SCEV expression for the specified value /// getSCEVAtScope - Return a SCEV expression for the specified value
/// at the specified scope in the program. The L value specifies a loop /// at the specified scope in the program. The L value specifies a loop
/// nest to evaluate the expression at, where null is the top-level or a /// nest to evaluate the expression at, where null is the top-level or a

View File

@ -160,13 +160,8 @@ namespace llvm {
const Type *getType() const { return getOperand(0)->getType(); } const Type *getType() const { return getOperand(0)->getType(); }
bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); } NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
void setHasNoUnsignedWrap(bool B) { return (NoWrapFlags)(SubclassData & Mask);
SubclassData = (SubclassData & ~(1 << 0)) | (B << 0);
}
bool hasNoSignedWrap() const { return SubclassData & (1 << 1); }
void setHasNoSignedWrap(bool B) {
SubclassData = (SubclassData & ~(1 << 1)) | (B << 1);
} }
/// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -199,6 +194,11 @@ namespace llvm {
S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scSMaxExpr ||
S->getSCEVType() == scUMaxExpr; S->getSCEVType() == scUMaxExpr;
} }
/// Set flags for a non-recurrence without clearing previously set flags.
void setNoWrapFlags(NoWrapFlags Flags) {
SubclassData |= Flags;
}
}; };
@ -305,11 +305,12 @@ namespace llvm {
/// getStepRecurrence - This method constructs and returns the recurrence /// getStepRecurrence - This method constructs and returns the recurrence
/// indicating how much this expression steps by. If this is a polynomial /// indicating how much this expression steps by. If this is a polynomial
/// of degree N, it returns a chrec of degree N-1. /// of degree N, it returns a chrec of degree N-1.
/// We cannot determine whether the step recurrence has self-wraparound.
const SCEV *getStepRecurrence(ScalarEvolution &SE) const { const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
if (isAffine()) return getOperand(1); if (isAffine()) return getOperand(1);
return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1, return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
op_end()), op_end()),
getLoop()); getLoop(), FlagAnyWrap);
} }
/// isAffine - Return true if this is an affine AddRec (i.e., it represents /// isAffine - Return true if this is an affine AddRec (i.e., it represents
@ -327,6 +328,15 @@ namespace llvm {
return getNumOperands() == 3; return getNumOperands() == 3;
} }
/// Set flags for a recurrence without clearing any previously set flags.
/// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
/// to make it easier to propagate flags.
void setNoWrapFlags(NoWrapFlags Flags) {
if (Flags & (FlagNUW | FlagNSW))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= Flags;
}
/// evaluateAtIteration - Return the value of this chain of recurrences at /// evaluateAtIteration - Return the value of this chain of recurrences at
/// the specified iteration number. /// the specified iteration number.
const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const; const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
@ -364,8 +374,7 @@ namespace llvm {
const SCEV *const *O, size_t N) const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scSMaxExpr, O, N) { : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
// Max never overflows. // Max never overflows.
setHasNoUnsignedWrap(true); setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
setHasNoSignedWrap(true);
} }
public: public:
@ -387,8 +396,7 @@ namespace llvm {
const SCEV *const *O, size_t N) const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scUMaxExpr, O, N) { : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
// Max never overflows. // Max never overflows.
setHasNoUnsignedWrap(true); setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
setHasNoSignedWrap(true);
} }
public: public:

View File

@ -25,7 +25,6 @@
namespace llvm { namespace llvm {
class MemoryBuffer; class MemoryBuffer;
class raw_ostream;
// Forward declare classes // Forward declare classes
class Module; // From VMCore class Module; // From VMCore
@ -436,7 +435,7 @@ class Archive {
/// to determine just enough information to create an ArchiveMember object /// to determine just enough information to create an ArchiveMember object
/// which is then inserted into the Archive object's ilist at the location /// which is then inserted into the Archive object's ilist at the location
/// given by \p where. /// given by \p where.
/// @returns true if an error occured, false otherwise /// @returns true if an error occurred, false otherwise
/// @brief Add a file to the archive. /// @brief Add a file to the archive.
bool addFileBefore( bool addFileBefore(
const sys::Path& filename, ///< The file to be added const sys::Path& filename, ///< The file to be added
@ -483,7 +482,7 @@ class Archive {
bool loadSymbolTable(std::string* ErrMessage); bool loadSymbolTable(std::string* ErrMessage);
/// @brief Write the symbol table to an ofstream. /// @brief Write the symbol table to an ofstream.
void writeSymbolTable(raw_ostream& ARFile); void writeSymbolTable(std::ofstream& ARFile);
/// Writes one ArchiveMember to an ofstream. If an error occurs, returns /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
/// false, otherwise true. If an error occurs and error is non-null then /// false, otherwise true. If an error occurs and error is non-null then
@ -492,7 +491,7 @@ class Archive {
/// @returns true Writing member failed, \p error set to error message /// @returns true Writing member failed, \p error set to error message
bool writeMember( bool writeMember(
const ArchiveMember& member, ///< The member to be written const ArchiveMember& member, ///< The member to be written
raw_ostream& ARFile, ///< The file to write member onto std::ofstream& ARFile, ///< The file to write member onto
bool CreateSymbolTable, ///< Should symbol table be created? bool CreateSymbolTable, ///< Should symbol table be created?
bool TruncateNames, ///< Should names be truncated to 11 chars? bool TruncateNames, ///< Should names be truncated to 11 chars?
bool ShouldCompress, ///< Should the member be compressed? bool ShouldCompress, ///< Should the member be compressed?

View File

@ -183,6 +183,10 @@ namespace llvm {
/// function. /// function.
void EmitFunctionBody(); void EmitFunctionBody();
void emitPrologLabel(const MachineInstr &MI);
bool needsCFIMoves();
/// EmitConstantPool - Print to the current output stream assembly /// EmitConstantPool - Print to the current output stream assembly
/// representations of the constants in the constant pool MCP. This is /// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by /// used to print out constants which have been "spilled to memory" by
@ -377,10 +381,17 @@ namespace llvm {
/// operands. /// operands.
virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
/// getDwarfRegOpSize - get size required to emit given machine location
/// using dwarf encoding.
virtual unsigned getDwarfRegOpSize(const MachineLocation &MLoc) const;
/// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa
/// encoding specified. /// encoding specified.
virtual unsigned getISAEncoding() { return 0; } virtual unsigned getISAEncoding() { return 0; }
/// EmitDwarfRegOp - Emit dwarf register operation.
virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Dwarf Lowering Routines // Dwarf Lowering Routines
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
@ -389,6 +400,7 @@ namespace llvm {
/// frame. /// frame.
void EmitFrameMoves(const std::vector<MachineMove> &Moves, void EmitFrameMoves(const std::vector<MachineMove> &Moves,
MCSymbol *BaseLabel, bool isEH) const; MCSymbol *BaseLabel, bool isEH) const;
void EmitCFIFrameMove(const MachineMove &Move) const;
void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const; void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//

View File

@ -11,7 +11,7 @@
#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
namespace llvm { namespace llvm {
@ -29,28 +29,25 @@ namespace llvm {
/// @param Size Size of live interval as returnexd by getSize() /// @param Size Size of live interval as returnexd by getSize()
/// ///
static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) { static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) {
// The magic constant 200 corresponds to approx. 25 instructions since // The constant 25 instructions is added to avoid depending too much on
// SlotIndexes allocate 8 slots per instruction. // accidental SlotIndex gaps for small intervals. The effect is that small
// // intervals have a spill weight that is mostly proportional to the number
// The constant is added to avoid depending too much on accidental SlotIndex // of uses, while large intervals get a spill weight that is closer to a use
// gaps for small intervals. The effect is that small intervals have a spill // density.
// weight that is mostly proportional to the number of uses, while large return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
// intervals get a spill weight that is closer to a use density.
//
return UseDefFreq / (Size + 200);
} }
/// VirtRegAuxInfo - Calculate auxiliary information for a virtual /// VirtRegAuxInfo - Calculate auxiliary information for a virtual
/// register such as its spill weight and allocation hint. /// register such as its spill weight and allocation hint.
class VirtRegAuxInfo { class VirtRegAuxInfo {
MachineFunction &mf_; MachineFunction &MF;
LiveIntervals &lis_; LiveIntervals &LIS;
const MachineLoopInfo &loops_; const MachineLoopInfo &Loops;
DenseMap<unsigned, float> hint_; DenseMap<unsigned, float> Hint;
public: public:
VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis, VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
const MachineLoopInfo &loops) : const MachineLoopInfo &loops) :
mf_(mf), lis_(lis), loops_(loops) {} MF(mf), LIS(lis), Loops(loops) {}
/// CalculateRegClass - recompute the register class for reg from its uses. /// CalculateRegClass - recompute the register class for reg from its uses.
/// Since the register class can affect the allocation hint, this function /// Since the register class can affect the allocation hint, this function

View File

@ -141,6 +141,8 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT,
MVT &LocVT, CCValAssign::LocInfo &LocInfo, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State); ISD::ArgFlagsTy &ArgFlags, CCState &State);
typedef enum { Invalid, Prologue, Call } ParmContext;
/// CCState - This class holds information needed while lowering arguments and /// CCState - This class holds information needed while lowering arguments and
/// return values. It captures which registers are already assigned and which /// return values. It captures which registers are already assigned and which
/// stack slots are used. It provides accessors to allocate these values. /// stack slots are used. It provides accessors to allocate these values.
@ -154,6 +156,9 @@ class CCState {
unsigned StackOffset; unsigned StackOffset;
SmallVector<uint32_t, 16> UsedRegs; SmallVector<uint32_t, 16> UsedRegs;
unsigned FirstByValReg;
bool FirstByValRegValid;
ParmContext CallOrPrologue;
public: public:
CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM,
SmallVector<CCValAssign, 16> &locs, LLVMContext &C); SmallVector<CCValAssign, 16> &locs, LLVMContext &C);
@ -288,6 +293,16 @@ class CCState {
MVT LocVT, CCValAssign::LocInfo LocInfo, MVT LocVT, CCValAssign::LocInfo LocInfo,
int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
// First GPR that carries part of a byval aggregate that's split
// between registers and memory.
unsigned getFirstByValReg() { return FirstByValRegValid ? FirstByValReg : 0; }
void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; }
void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; }
bool isFirstByValRegValid() { return FirstByValRegValid; }
ParmContext getCallOrPrologue() { return CallOrPrologue; }
void setCallOrPrologue(ParmContext pc) { CallOrPrologue = pc; }
private: private:
/// MarkAllocated - Mark a register and all of its aliases as allocated. /// MarkAllocated - Mark a register and all of its aliases as allocated.
void MarkAllocated(unsigned Reg); void MarkAllocated(unsigned Reg);

View File

@ -16,6 +16,7 @@
#ifndef LLVM_CODEGEN_EDGEBUNDLES_H #ifndef LLVM_CODEGEN_EDGEBUNDLES_H
#define LLVM_CODEGEN_EDGEBUNDLES_H #define LLVM_CODEGEN_EDGEBUNDLES_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntEqClasses.h" #include "llvm/ADT/IntEqClasses.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
@ -29,6 +30,9 @@ class EdgeBundles : public MachineFunctionPass {
/// 2*BB->getNumber()+1 -> Outgoing bundle. /// 2*BB->getNumber()+1 -> Outgoing bundle.
IntEqClasses EC; IntEqClasses EC;
/// Blocks - Map each bundle to a list of basic block numbers.
SmallVector<SmallVector<unsigned, 8>, 4> Blocks;
public: public:
static char ID; static char ID;
EdgeBundles() : MachineFunctionPass(ID) {} EdgeBundles() : MachineFunctionPass(ID) {}
@ -40,6 +44,9 @@ class EdgeBundles : public MachineFunctionPass {
/// getNumBundles - Return the total number of bundles in the CFG. /// getNumBundles - Return the total number of bundles in the CFG.
unsigned getNumBundles() const { return EC.getNumClasses(); } unsigned getNumBundles() const { return EC.getNumClasses(); }
/// getBlocks - Return an array of blocks that are connected to Bundle.
ArrayRef<unsigned> getBlocks(unsigned Bundle) { return Blocks[Bundle]; }
/// getMachineFunction - Return the last machine function computed. /// getMachineFunction - Return the last machine function computed.
const MachineFunction *getMachineFunction() const { return MF; } const MachineFunction *getMachineFunction() const { return MF; }

View File

@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines the FastISel class. // This file defines the FastISel class.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_FASTISEL_H #ifndef LLVM_CODEGEN_FASTISEL_H
#define LLVM_CODEGEN_FASTISEL_H #define LLVM_CODEGEN_FASTISEL_H
@ -108,7 +108,7 @@ class FastISel {
const LoadInst * /*LI*/) { const LoadInst * /*LI*/) {
return false; return false;
} }
/// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions
/// into the current block. /// into the current block.
void recomputeInsertPt(); void recomputeInsertPt();
@ -203,16 +203,7 @@ class FastISel {
unsigned Opcode, unsigned Opcode,
unsigned Op0, bool Op0IsKill, unsigned Op0, bool Op0IsKill,
uint64_t Imm, MVT ImmType); uint64_t Imm, MVT ImmType);
/// FastEmit_rf_ - This method is a wrapper of FastEmit_rf. It first tries
/// to emit an instruction with an immediate operand using FastEmit_rf.
/// If that fails, it materializes the immediate into a register and try
/// FastEmit_rr instead.
unsigned FastEmit_rf_(MVT VT,
unsigned Opcode,
unsigned Op0, bool Op0IsKill,
const ConstantFP *FPImm, MVT ImmType);
/// FastEmit_i - This method is called by target-independent code /// FastEmit_i - This method is called by target-independent code
/// to request that an instruction with the given type, opcode, and /// to request that an instruction with the given type, opcode, and
/// immediate operand be emitted. /// immediate operand be emitted.
@ -250,14 +241,22 @@ class FastISel {
unsigned Op0, bool Op0IsKill, unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill); unsigned Op1, bool Op1IsKill);
/// FastEmitInst_ri - Emit a MachineInstr with two register operands /// FastEmitInst_ri - Emit a MachineInstr with a register operand,
/// and a result register in the given register class. /// an immediate, and a result register in the given register class.
/// ///
unsigned FastEmitInst_ri(unsigned MachineInstOpcode, unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill, unsigned Op0, bool Op0IsKill,
uint64_t Imm); uint64_t Imm);
/// FastEmitInst_rii - Emit a MachineInstr with one register operand
/// and two immediate operands.
///
unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill,
uint64_t Imm1, uint64_t Imm2);
/// FastEmitInst_rf - Emit a MachineInstr with two register operands /// FastEmitInst_rf - Emit a MachineInstr with two register operands
/// and a result register in the given register class. /// and a result register in the given register class.
/// ///
@ -274,13 +273,18 @@ class FastISel {
unsigned Op0, bool Op0IsKill, unsigned Op0, bool Op0IsKill,
unsigned Op1, bool Op1IsKill, unsigned Op1, bool Op1IsKill,
uint64_t Imm); uint64_t Imm);
/// FastEmitInst_i - Emit a MachineInstr with a single immediate /// FastEmitInst_i - Emit a MachineInstr with a single immediate
/// operand, and a result register in the given register class. /// operand, and a result register in the given register class.
unsigned FastEmitInst_i(unsigned MachineInstrOpcode, unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC, const TargetRegisterClass *RC,
uint64_t Imm); uint64_t Imm);
/// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands.
unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
const TargetRegisterClass *RC,
uint64_t Imm1, uint64_t Imm2);
/// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
/// from a specified index of a superregister to a specified type. /// from a specified index of a superregister to a specified type.
unsigned FastEmitInst_extractsubreg(MVT RetVT, unsigned FastEmitInst_extractsubreg(MVT RetVT,
@ -300,8 +304,8 @@ class FastISel {
unsigned UpdateValueMap(const Value* I, unsigned Reg); unsigned UpdateValueMap(const Value* I, unsigned Reg);
unsigned createResultReg(const TargetRegisterClass *RC); unsigned createResultReg(const TargetRegisterClass *RC);
/// TargetMaterializeConstant - Emit a constant in a register using /// TargetMaterializeConstant - Emit a constant in a register using
/// target-specific logic, such as constant pool loads. /// target-specific logic, such as constant pool loads.
virtual unsigned TargetMaterializeConstant(const Constant* C) { virtual unsigned TargetMaterializeConstant(const Constant* C) {
return 0; return 0;
@ -313,6 +317,10 @@ class FastISel {
return 0; return 0;
} }
virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) {
return 0;
}
private: private:
bool SelectBinaryOp(const User *I, unsigned ISDOpcode); bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
@ -323,7 +331,7 @@ class FastISel {
bool SelectCall(const User *I); bool SelectCall(const User *I);
bool SelectBitCast(const User *I); bool SelectBitCast(const User *I);
bool SelectCast(const User *I, unsigned Opcode); bool SelectCast(const User *I, unsigned Opcode);
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.

View File

@ -187,7 +187,12 @@ class FunctionLoweringInfo {
/// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be
/// called when a block is visited before all of its predecessors. /// called when a block is visited before all of its predecessors.
void InvalidatePHILiveOutRegInfo(const PHINode *PN) { void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
unsigned Reg = ValueMap[PN]; // PHIs with no uses have no ValueMap entry.
DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN);
if (It == ValueMap.end())
return;
unsigned Reg = It->second;
LiveOutRegInfo.grow(Reg); LiveOutRegInfo.grow(Reg);
LiveOutRegInfo[Reg].IsValid = false; LiveOutRegInfo[Reg].IsValid = false;
} }
@ -209,8 +214,9 @@ class FunctionLoweringInfo {
void AddCatchInfo(const CallInst &I, void AddCatchInfo(const CallInst &I,
MachineModuleInfo *MMI, MachineBasicBlock *MBB); MachineModuleInfo *MMI, MachineBasicBlock *MBB);
/// CopyCatchInfo - Copy catch information from DestBB to SrcBB. /// CopyCatchInfo - Copy catch information from SuccBB (or one of its
void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB, /// successors) to LPad.
void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad,
MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); MachineModuleInfo *MMI, FunctionLoweringInfo &FLI);
} // end namespace llvm } // end namespace llvm

View File

@ -219,7 +219,7 @@ namespace ISD {
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
// These nodes take two operands: the normal LHS and RHS to the add. They // These nodes take two operands: the normal LHS and RHS to the add. They
// produce two results: the normal result of the add, and a boolean that // produce two results: the normal result of the add, and a boolean that
// indicates if an overflow occured (*not* a flag, because it may be stored // indicates if an overflow occurred (*not* a flag, because it may be stored
// to memory, etc.). If the type of the boolean is not i1 then the high // to memory, etc.). If the type of the boolean is not i1 then the high
// bits conform to getBooleanContents. // bits conform to getBooleanContents.
// These nodes are generated from the llvm.[su]add.with.overflow intrinsics. // These nodes are generated from the llvm.[su]add.with.overflow intrinsics.

View File

@ -23,8 +23,6 @@
#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
using namespace std;
namespace llvm { namespace llvm {
class MachineBasicBlock; class MachineBasicBlock;
@ -38,7 +36,7 @@ class GlobalValue;
class Function; class Function;
/// JITCodeEmitter - This class defines two sorts of methods: those for /// JITCodeEmitter - This class defines two sorts of methods: those for
/// emitting the actual bytes of machine code, and those for emitting auxillary /// emitting the actual bytes of machine code, and those for emitting auxiliary
/// structures, such as jump tables, relocations, etc. /// structures, such as jump tables, relocations, etc.
/// ///
/// Emission of machine code is complicated by the fact that we don't (in /// Emission of machine code is complicated by the fact that we don't (in

View File

@ -286,6 +286,11 @@ namespace llvm {
return valnos[ValNo]; return valnos[ValNo];
} }
/// containsValue - Returns true if VNI belongs to this interval.
bool containsValue(const VNInfo *VNI) const {
return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id);
}
/// getNextValue - Create a new value number and return it. MIIdx specifies /// getNextValue - Create a new value number and return it. MIIdx specifies
/// the instruction that defines the value number. /// the instruction that defines the value number.
VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI, VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI,
@ -447,6 +452,11 @@ namespace llvm {
addRangeFrom(LR, ranges.begin()); addRangeFrom(LR, ranges.begin());
} }
/// extendInBlock - If this interval is live before UseIdx in the basic
/// block that starts at StartIdx, extend it to be live at UseIdx and return
/// the value. If there is no live range before UseIdx, return NULL.
VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx);
/// join - Join two live intervals (this, and other) together. This applies /// join - Join two live intervals (this, and other) together. This applies
/// mappings to the value numbers in the LHS/RHS intervals as specified. If /// mappings to the value numbers in the LHS/RHS intervals as specified. If
/// the intervals are not joinable, this aborts. /// the intervals are not joinable, this aborts.
@ -543,8 +553,8 @@ namespace llvm {
/// } /// }
class ConnectedVNInfoEqClasses { class ConnectedVNInfoEqClasses {
LiveIntervals &lis_; LiveIntervals &LIS;
IntEqClasses eqClass_; IntEqClasses EqClass;
// Note that values a and b are connected. // Note that values a and b are connected.
void Connect(unsigned a, unsigned b); void Connect(unsigned a, unsigned b);
@ -552,7 +562,7 @@ namespace llvm {
unsigned Renumber(); unsigned Renumber();
public: public:
explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {} explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {}
/// Classify - Classify the values in LI into connected components. /// Classify - Classify the values in LI into connected components.
/// Return the number of connected components. /// Return the number of connected components.
@ -560,12 +570,13 @@ namespace llvm {
/// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// getEqClass - Classify creates equivalence classes numbered 0..N. Return
/// the equivalence class assigned the VNI. /// the equivalence class assigned the VNI.
unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; } unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; }
/// Distribute - Distribute values in LIV[0] into a separate LiveInterval /// Distribute - Distribute values in LIV[0] into a separate LiveInterval
/// for each connected component. LIV must have a LiveInterval for each /// for each connected component. LIV must have a LiveInterval for each
/// connected component. The LiveIntervals in Liv[1..] must be empty. /// connected component. The LiveIntervals in Liv[1..] must be empty.
void Distribute(LiveInterval *LIV[]); /// Instructions using LIV[0] are rewritten.
void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI);
}; };

View File

@ -159,7 +159,11 @@ namespace llvm {
/// range to just the remaining uses. This method does not compute reaching /// range to just the remaining uses. This method does not compute reaching
/// defs for new uses, and it doesn't remove dead defs. /// defs for new uses, and it doesn't remove dead defs.
/// Dead PHIDef values are marked as unused. /// Dead PHIDef values are marked as unused.
void shrinkToUses(LiveInterval *li); /// New dead machine instructions are added to the dead vector.
/// Return true if the interval may have been separated into multiple
/// connected components.
bool shrinkToUses(LiveInterval *li,
SmallVectorImpl<MachineInstr*> *dead = 0);
// Interval removal // Interval removal
@ -272,7 +276,7 @@ namespace llvm {
/// (if any is created) by reference. This is temporary. /// (if any is created) by reference. This is temporary.
std::vector<LiveInterval*> std::vector<LiveInterval*>
addIntervalsForSpills(const LiveInterval& i, addIntervalsForSpills(const LiveInterval& i,
const SmallVectorImpl<LiveInterval*> &SpillIs, const SmallVectorImpl<LiveInterval*> *SpillIs,
const MachineLoopInfo *loopInfo, VirtRegMap& vrm); const MachineLoopInfo *loopInfo, VirtRegMap& vrm);
/// spillPhysRegAroundRegDefsUses - Spill the specified physical register /// spillPhysRegAroundRegDefsUses - Spill the specified physical register
@ -285,7 +289,7 @@ namespace llvm {
/// val# of the specified interval is re-materializable. Also returns true /// val# of the specified interval is re-materializable. Also returns true
/// by reference if all of the defs are load instructions. /// by reference if all of the defs are load instructions.
bool isReMaterializable(const LiveInterval &li, bool isReMaterializable(const LiveInterval &li,
const SmallVectorImpl<LiveInterval*> &SpillIs, const SmallVectorImpl<LiveInterval*> *SpillIs,
bool &isLoad); bool &isLoad);
/// isReMaterializable - Returns true if the definition MI of the specified /// isReMaterializable - Returns true if the definition MI of the specified
@ -372,7 +376,7 @@ namespace llvm {
/// by reference if the def is a load. /// by reference if the def is a load.
bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo, bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
MachineInstr *MI, MachineInstr *MI,
const SmallVectorImpl<LiveInterval*> &SpillIs, const SmallVectorImpl<LiveInterval*> *SpillIs,
bool &isLoad); bool &isLoad);
/// tryFoldMemoryOperand - Attempts to fold either a spill / restore from /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from

View File

@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include <functional>
namespace llvm { namespace llvm {
@ -304,10 +305,18 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
/// it returns end() /// it returns end()
iterator getFirstTerminator(); iterator getFirstTerminator();
const_iterator getFirstTerminator() const {
return const_cast<MachineBasicBlock*>(this)->getFirstTerminator();
}
/// getLastNonDebugInstr - returns an iterator to the last non-debug /// getLastNonDebugInstr - returns an iterator to the last non-debug
/// instruction in the basic block, or end() /// instruction in the basic block, or end()
iterator getLastNonDebugInstr(); iterator getLastNonDebugInstr();
const_iterator getLastNonDebugInstr() const {
return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
}
/// SplitCriticalEdge - Split the critical edge from this block to the /// SplitCriticalEdge - Split the critical edge from this block to the
/// given successor block, and return the newly created block, or null /// given successor block, and return the newly created block, or null
/// if splitting is not possible. /// if splitting is not possible.
@ -411,6 +420,14 @@ raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t); void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t);
// This is useful when building IndexedMaps keyed on basic block pointers.
struct MBB2NumberFunctor :
public std::unary_function<const MachineBasicBlock*, unsigned> {
unsigned operator()(const MachineBasicBlock *MBB) const {
return MBB->getNumber();
}
};
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// GraphTraits specializations for machine basic block graphs (machine-CFGs) // GraphTraits specializations for machine basic block graphs (machine-CFGs)
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -34,7 +34,7 @@ class Function;
class MCSymbol; class MCSymbol;
/// MachineCodeEmitter - This class defines two sorts of methods: those for /// MachineCodeEmitter - This class defines two sorts of methods: those for
/// emitting the actual bytes of machine code, and those for emitting auxillary /// emitting the actual bytes of machine code, and those for emitting auxiliary
/// structures, such as jump tables, relocations, etc. /// structures, such as jump tables, relocations, etc.
/// ///
/// Emission of machine code is complicated by the fact that we don't (in /// Emission of machine code is complicated by the fact that we don't (in
@ -54,7 +54,7 @@ class MachineCodeEmitter {
/// allocated for this code buffer. /// allocated for this code buffer.
uint8_t *BufferBegin, *BufferEnd; uint8_t *BufferBegin, *BufferEnd;
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If /// code. This is guaranteed to be in the range [BufferBegin,BufferEnd]. If
/// this pointer is at BufferEnd, it will never move due to code emission, and /// this pointer is at BufferEnd, it will never move due to code emission, and
/// all code emission requests will be ignored (this is the buffer overflow /// all code emission requests will be ignored (this is the buffer overflow
/// condition). /// condition).

View File

@ -80,7 +80,7 @@ class MachineConstantPoolEntry {
} Val; } Val;
/// The required alignment for this entry. The top bit is set when Val is /// The required alignment for this entry. The top bit is set when Val is
/// a MachineConstantPoolValue. /// a target specific MachineConstantPoolValue.
unsigned Alignment; unsigned Alignment;
MachineConstantPoolEntry(const Constant *V, unsigned A) MachineConstantPoolEntry(const Constant *V, unsigned A)
@ -93,6 +93,9 @@ class MachineConstantPoolEntry {
Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1); Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1);
} }
/// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry
/// is indeed a target specific constantpool entry, not a wrapper over a
/// Constant.
bool isMachineConstantPoolEntry() const { bool isMachineConstantPoolEntry() const {
return (int)Alignment < 0; return (int)Alignment < 0;
} }

View File

@ -15,7 +15,6 @@
#define LLVM_CODEGEN_MACHINEFRAMEINFO_H #define LLVM_CODEGEN_MACHINEFRAMEINFO_H
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
//#include "llvm/ADT/IndexedMap.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <cassert> #include <cassert>
#include <vector> #include <vector>

View File

@ -50,13 +50,22 @@ class MachineInstr : public ilist_node<MachineInstr> {
enum CommentFlag { enum CommentFlag {
ReloadReuse = 0x1 ReloadReuse = 0x1
}; };
enum MIFlag {
NoFlags = 0,
FrameSetup = 1 << 0 // Instruction is used as a part of
// function frame setup code.
};
private: private:
const TargetInstrDesc *TID; // Instruction descriptor. const TargetInstrDesc *TID; // Instruction descriptor.
unsigned short NumImplicitOps; // Number of implicit operands (which uint16_t NumImplicitOps; // Number of implicit operands (which
// are determined at construction time). // are determined at construction time).
unsigned short AsmPrinterFlags; // Various bits of information used by uint8_t Flags; // Various bits of additional
// information about machine
// instruction.
uint8_t AsmPrinterFlags; // Various bits of information used by
// the AsmPrinter to emit helpful // the AsmPrinter to emit helpful
// comments. This is *not* semantic // comments. This is *not* semantic
// information. Do not use this for // information. Do not use this for
@ -105,13 +114,13 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// MachineInstr ctor - This constructor create a MachineInstr and add the /// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by /// implicit operands. It reserves space for number of operands specified by
/// TargetInstrDesc. An explicit DebugLoc is supplied. /// TargetInstrDesc. An explicit DebugLoc is supplied.
explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl,
bool NoImp = false); bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that /// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic /// the MachineInstr is created and added to the end of the specified basic
/// block. /// block.
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
const TargetInstrDesc &TID); const TargetInstrDesc &TID);
~MachineInstr(); ~MachineInstr();
@ -125,12 +134,12 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// getAsmPrinterFlags - Return the asm printer flags bitvector. /// getAsmPrinterFlags - Return the asm printer flags bitvector.
/// ///
unsigned short getAsmPrinterFlags() const { return AsmPrinterFlags; } uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; }
/// clearAsmPrinterFlags - clear the AsmPrinter bitvector /// clearAsmPrinterFlags - clear the AsmPrinter bitvector
/// ///
void clearAsmPrinterFlags() { AsmPrinterFlags = 0; } void clearAsmPrinterFlags() { AsmPrinterFlags = 0; }
/// getAsmPrinterFlag - Return whether an AsmPrinter flag is set. /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
/// ///
bool getAsmPrinterFlag(CommentFlag Flag) const { bool getAsmPrinterFlag(CommentFlag Flag) const {
@ -140,9 +149,28 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// setAsmPrinterFlag - Set a flag for the AsmPrinter. /// setAsmPrinterFlag - Set a flag for the AsmPrinter.
/// ///
void setAsmPrinterFlag(CommentFlag Flag) { void setAsmPrinterFlag(CommentFlag Flag) {
AsmPrinterFlags |= (unsigned short)Flag; AsmPrinterFlags |= (uint8_t)Flag;
} }
/// getFlags - Return the MI flags bitvector.
uint8_t getFlags() const {
return Flags;
}
/// getFlag - Return whether an MI flag is set.
bool getFlag(MIFlag Flag) const {
return Flags & Flag;
}
/// setFlag - Set a MI flag.
void setFlag(MIFlag Flag) {
Flags |= (uint8_t)Flag;
}
void setFlags(unsigned flags) {
Flags = flags;
}
/// clearAsmPrinterFlag - clear specific AsmPrinter flags /// clearAsmPrinterFlag - clear specific AsmPrinter flags
/// ///
void clearAsmPrinterFlag(CommentFlag Flag) { void clearAsmPrinterFlag(CommentFlag Flag) {
@ -152,7 +180,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// getDebugLoc - Returns the debug location id of this MachineInstr. /// getDebugLoc - Returns the debug location id of this MachineInstr.
/// ///
DebugLoc getDebugLoc() const { return debugLoc; } DebugLoc getDebugLoc() const { return debugLoc; }
/// getDesc - Returns the target instruction descriptor of this /// getDesc - Returns the target instruction descriptor of this
/// MachineInstr. /// MachineInstr.
const TargetInstrDesc &getDesc() const { return *TID; } const TargetInstrDesc &getDesc() const { return *TID; }
@ -213,7 +241,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// removeFromParent - This method unlinks 'this' from the containing basic /// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it. /// block, and returns it, but does not delete it.
MachineInstr *removeFromParent(); MachineInstr *removeFromParent();
/// eraseFromParent - This method unlinks 'this' from the containing basic /// eraseFromParent - This method unlinks 'this' from the containing basic
/// block and deletes it. /// block and deletes it.
void eraseFromParent(); void eraseFromParent();
@ -225,14 +253,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
getOpcode() == TargetOpcode::EH_LABEL || getOpcode() == TargetOpcode::EH_LABEL ||
getOpcode() == TargetOpcode::GC_LABEL; getOpcode() == TargetOpcode::GC_LABEL;
} }
bool isPrologLabel() const { bool isPrologLabel() const {
return getOpcode() == TargetOpcode::PROLOG_LABEL; return getOpcode() == TargetOpcode::PROLOG_LABEL;
} }
bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
@ -329,7 +357,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI);
return (Idx == -1) ? NULL : &getOperand(Idx); return (Idx == -1) ? NULL : &getOperand(Idx);
} }
/// findRegisterDefOperandIdx() - Returns the operand index that is a def of /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
/// the specified register or -1 if it is not found. If isDead is true, defs /// the specified register or -1 if it is not found. If isDead is true, defs
/// that are not dead are skipped. If Overlap is true, then it also looks for /// that are not dead are skipped. If Overlap is true, then it also looks for
@ -351,7 +379,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// operand list that is used to represent the predicate. It returns -1 if /// operand list that is used to represent the predicate. It returns -1 if
/// none is found. /// none is found.
int findFirstPredOperandIdx() const; int findFirstPredOperandIdx() const;
/// isRegTiedToUseOperand - Given the index of a register def operand, /// isRegTiedToUseOperand - Given the index of a register def operand,
/// check if the register def is tied to a source operand, due to either /// check if the register def is tied to a source operand, due to either
/// two-address elimination or inline assembly constraints. Returns the /// two-address elimination or inline assembly constraints. Returns the
@ -399,8 +427,8 @@ class MachineInstr : public ilist_node<MachineInstr> {
void addRegisterDefined(unsigned IncomingReg, void addRegisterDefined(unsigned IncomingReg,
const TargetRegisterInfo *RegInfo = 0); const TargetRegisterInfo *RegInfo = 0);
/// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as
/// except those in the UsedRegs list. /// dead except those in the UsedRegs list.
void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs, void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs,
const TargetRegisterInfo &TRI); const TargetRegisterInfo &TRI);
@ -462,9 +490,9 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// addOperand - Add the specified operand to the instruction. If it is an /// addOperand - Add the specified operand to the instruction. If it is an
/// implicit operand, it is added to the end of the operand list. If it is /// implicit operand, it is added to the end of the operand list. If it is
/// an explicit operand it is added at the end of the explicit operand list /// an explicit operand it is added at the end of the explicit operand list
/// (before the first implicit operand). /// (before the first implicit operand).
void addOperand(const MachineOperand &Op); void addOperand(const MachineOperand &Op);
/// setDesc - Replace the instruction descriptor (thus opcode) of /// setDesc - Replace the instruction descriptor (thus opcode) of
/// the current instruction with a new one. /// the current instruction with a new one.
/// ///
@ -501,12 +529,12 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// addImplicitDefUseOperands - Add all implicit def and use operands to /// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction. /// this instruction.
void addImplicitDefUseOperands(); void addImplicitDefUseOperands();
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the /// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists. /// operands already be on their use lists.
void RemoveRegOperandsFromUseLists(); void RemoveRegOperandsFromUseLists();
/// AddRegOperandsToUseLists - Add all of the register operands in /// AddRegOperandsToUseLists - Add all of the register operands in
/// this instruction from their respective use lists. This requires that the /// this instruction from their respective use lists. This requires that the
/// operands not be on their use lists yet. /// operands not be on their use lists yet.

View File

@ -48,6 +48,7 @@ class MachineInstrBuilder {
/// Allow automatic conversion to the machine instruction we are working on. /// Allow automatic conversion to the machine instruction we are working on.
/// ///
operator MachineInstr*() const { return MI; } operator MachineInstr*() const { return MI; }
MachineInstr *operator->() const { return MI; }
operator MachineBasicBlock::iterator() const { return MI; } operator MachineBasicBlock::iterator() const { return MI; }
/// addReg - Add a new virtual register operand... /// addReg - Add a new virtual register operand...
@ -145,6 +146,16 @@ class MachineInstrBuilder {
return *this; return *this;
} }
const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
MI->setFlags(Flags);
return *this;
}
const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
MI->setFlag(Flag);
return *this;
}
// Add a displacement from an existing MachineOperand with an added offset. // Add a displacement from an existing MachineOperand with an added offset.
const MachineInstrBuilder &addDisp(const MachineOperand &Disp, const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
int64_t off) const { int64_t off) const {

View File

@ -18,7 +18,6 @@
#include "Math.h" #include "Math.h"
#include <list> #include <list>
#include <vector>
#include <map> #include <map>
namespace PBQP { namespace PBQP {

View File

@ -21,7 +21,6 @@
#include "../HeuristicSolver.h" #include "../HeuristicSolver.h"
#include "../HeuristicBase.h" #include "../HeuristicBase.h"
#include <set>
#include <limits> #include <limits>
namespace PBQP { namespace PBQP {

View File

@ -18,14 +18,20 @@ namespace llvm {
class MachineInstr; class MachineInstr;
class TargetInstrInfo; class TargetInstrInfo;
class TargetRegisterInfo;
class MachineRegisterInfo;
class LiveVariables;
/// Process IMPLICIT_DEF instructions and make sure there is one implicit_def /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def
/// for each use. Add isUndef marker to implicit_def defs and their uses. /// for each use. Add isUndef marker to implicit_def defs and their uses.
class ProcessImplicitDefs : public MachineFunctionPass { class ProcessImplicitDefs : public MachineFunctionPass {
private: const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MachineRegisterInfo *MRI;
LiveVariables *LV;
bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
unsigned OpIdx, const TargetInstrInfo *tii_, unsigned OpIdx,
SmallSet<unsigned, 8> &ImpDefRegs); SmallSet<unsigned, 8> &ImpDefRegs);
public: public:

View File

@ -100,7 +100,7 @@ class RegScavenger {
/// getRegsAvailable - Return all available registers in the register class /// getRegsAvailable - Return all available registers in the register class
/// in Mask. /// in Mask.
void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask); BitVector getRegsAvailable(const TargetRegisterClass *RC);
/// FindUnusedReg - Find a unused register of the specified register class. /// FindUnusedReg - Find a unused register of the specified register class.
/// Return 0 if none is found. /// Return 0 if none is found.

View File

@ -66,6 +66,16 @@ namespace RTLIB {
UREM_I32, UREM_I32,
UREM_I64, UREM_I64,
UREM_I128, UREM_I128,
SDIVREM_I8,
SDIVREM_I16,
SDIVREM_I32,
SDIVREM_I64,
SDIVREM_I128,
UDIVREM_I8,
UDIVREM_I16,
UDIVREM_I32,
UDIVREM_I64,
UDIVREM_I128,
NEG_I32, NEG_I32,
NEG_I64, NEG_I64,

View File

@ -250,7 +250,9 @@ namespace llvm {
unsigned NumSuccsLeft; // # of succs not scheduled. unsigned NumSuccsLeft; // # of succs not scheduled.
unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use. unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use.
unsigned short Latency; // Node latency. unsigned short Latency; // Node latency.
bool isVRegCycle : 1; // May use and def the same vreg.
bool isCall : 1; // Is a function call. bool isCall : 1; // Is a function call.
bool isCallOp : 1; // Is a function call operand.
bool isTwoAddress : 1; // Is a two-address instruction. bool isTwoAddress : 1; // Is a two-address instruction.
bool isCommutable : 1; // Is a commutable instruction. bool isCommutable : 1; // Is a commutable instruction.
bool hasPhysRegDefs : 1; // Has physreg defs that are being used. bool hasPhysRegDefs : 1; // Has physreg defs that are being used.
@ -259,6 +261,7 @@ namespace llvm {
bool isAvailable : 1; // True once available. bool isAvailable : 1; // True once available.
bool isScheduled : 1; // True once scheduled. bool isScheduled : 1; // True once scheduled.
bool isScheduleHigh : 1; // True if preferable to schedule high. bool isScheduleHigh : 1; // True if preferable to schedule high.
bool isScheduleLow : 1; // True if preferable to schedule low.
bool isCloned : 1; // True if this node has been cloned. bool isCloned : 1; // True if this node has been cloned.
Sched::Preference SchedulingPref; // Scheduling preference. Sched::Preference SchedulingPref; // Scheduling preference.
@ -278,10 +281,10 @@ namespace llvm {
: Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false), isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false), isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {} CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -292,10 +295,10 @@ namespace llvm {
: Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false), isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false), isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {} CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -305,10 +308,10 @@ namespace llvm {
: Node(0), Instr(0), OrigNode(0), NodeNum(~0u), : Node(0), Instr(0), OrigNode(0), NodeNum(~0u),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
isCall(false), isTwoAddress(false), isCommutable(false), isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false), isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false), isScheduleHigh(false), isScheduleLow(false), isCloned(false),
SchedulingPref(Sched::None), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {} CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -356,7 +359,7 @@ namespace llvm {
void removePred(const SDep &D); void removePred(const SDep &D);
/// getDepth - Return the depth of this node, which is the length of the /// getDepth - Return the depth of this node, which is the length of the
/// maximum path up to any node with has no predecessors. /// maximum path up to any node which has no predecessors.
unsigned getDepth() const { unsigned getDepth() const {
if (!isDepthCurrent) if (!isDepthCurrent)
const_cast<SUnit *>(this)->ComputeDepth(); const_cast<SUnit *>(this)->ComputeDepth();
@ -364,7 +367,7 @@ namespace llvm {
} }
/// getHeight - Return the height of this node, which is the length of the /// getHeight - Return the height of this node, which is the length of the
/// maximum path down to any node with has no successors. /// maximum path down to any node which has no successors.
unsigned getHeight() const { unsigned getHeight() const {
if (!isHeightCurrent) if (!isHeightCurrent)
const_cast<SUnit *>(this)->ComputeHeight(); const_cast<SUnit *>(this)->ComputeHeight();
@ -690,11 +693,11 @@ namespace llvm {
/// will create a cycle. /// will create a cycle.
bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); bool WillCreateCycle(SUnit *SU, SUnit *TargetSU);
/// AddPred - Updates the topological ordering to accomodate an edge /// AddPred - Updates the topological ordering to accommodate an edge
/// to be added from SUnit X to SUnit Y. /// to be added from SUnit X to SUnit Y.
void AddPred(SUnit *Y, SUnit *X); void AddPred(SUnit *Y, SUnit *X);
/// RemovePred - Updates the topological ordering to accomodate an /// RemovePred - Updates the topological ordering to accommodate an
/// an edge to be removed from the specified node N from the predecessors /// an edge to be removed from the specified node N from the predecessors
/// of the current node M. /// of the current node M.
void RemovePred(SUnit *M, SUnit *N); void RemovePred(SUnit *M, SUnit *N);

View File

@ -21,7 +21,6 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <string>
namespace llvm { namespace llvm {

View File

@ -438,12 +438,12 @@ class SelectionDAG {
SDValue getConvertRndSat(EVT VT, DebugLoc dl, SDValue Val, SDValue DTy, SDValue getConvertRndSat(EVT VT, DebugLoc dl, SDValue Val, SDValue DTy,
SDValue STy, SDValue STy,
SDValue Rnd, SDValue Sat, ISD::CvtCode Code); SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
/// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of
/// elements in VT, which must be a vector type, must match the number of /// elements in VT, which must be a vector type, must match the number of
/// mask elements NumElts. A integer mask element equal to -1 is treated as /// mask elements NumElts. A integer mask element equal to -1 is treated as
/// undefined. /// undefined.
SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
const int *MaskElts); const int *MaskElts);
/// getSExtOrTrunc - Convert Op, which must be of integer type, to the /// getSExtOrTrunc - Convert Op, which must be of integer type, to the
@ -671,10 +671,10 @@ class SelectionDAG {
/// getMDNode - Return an MDNodeSDNode which holds an MDNode. /// getMDNode - Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD); SDValue getMDNode(const MDNode *MD);
/// getShiftAmountOperand - Return the specified value casted to /// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type. /// the target's desired shift amount type.
SDValue getShiftAmountOperand(SDValue Op); SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
/// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
/// specified operands. If the resultant node already exists in the DAG, /// specified operands. If the resultant node already exists in the DAG,
@ -829,7 +829,7 @@ class SelectionDAG {
/// These functions only replace all existing uses. It's possible that as /// These functions only replace all existing uses. It's possible that as
/// these replacements are being performed, CSE may cause the From node /// these replacements are being performed, CSE may cause the From node
/// to be given new uses. These new uses of From are left in place, and /// to be given new uses. These new uses of From are left in place, and
/// not automatically transfered to To. /// not automatically transferred to To.
/// ///
void ReplaceAllUsesWith(SDValue From, SDValue Op, void ReplaceAllUsesWith(SDValue From, SDValue Op,
DAGUpdateListener *UpdateListener = 0); DAGUpdateListener *UpdateListener = 0);
@ -901,7 +901,7 @@ class SelectionDAG {
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
return DbgInfo->getSDDbgValues(SD); return DbgInfo->getSDDbgValues(SD);
} }
/// TransferDbgValues - Transfer SDDbgValues. /// TransferDbgValues - Transfer SDDbgValues.
void TransferDbgValues(SDValue From, SDValue To); void TransferDbgValues(SDValue From, SDValue To);
@ -911,11 +911,11 @@ class SelectionDAG {
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); } SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); } SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
SDDbgInfo::DbgIterator ByvalParmDbgBegin() { SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
return DbgInfo->ByvalParmDbgBegin(); return DbgInfo->ByvalParmDbgBegin();
} }
SDDbgInfo::DbgIterator ByvalParmDbgEnd() { SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
return DbgInfo->ByvalParmDbgEnd(); return DbgInfo->ByvalParmDbgEnd();
} }
void dump() const; void dump() const;
@ -972,7 +972,7 @@ class SelectionDAG {
/// semantics as an ADD. This handles the equivalence: /// semantics as an ADD. This handles the equivalence:
/// X|Cst == X+Cst iff X&Cst = 0. /// X|Cst == X+Cst iff X&Cst = 0.
bool isBaseWithConstantOffset(SDValue Op) const; bool isBaseWithConstantOffset(SDValue Op) const;
/// isKnownNeverNan - Test whether the given SDValue is known to never be NaN. /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
bool isKnownNeverNaN(SDValue Op) const; bool isKnownNeverNaN(SDValue Op) const;
@ -997,8 +997,8 @@ class SelectionDAG {
/// vector op and fill the end of the resulting vector with UNDEFS. /// vector op and fill the end of the resulting vector with UNDEFS.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
/// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
/// location that is 'Dist' units away from the location that the 'Base' load /// location that is 'Dist' units away from the location that the 'Base' load
/// is loading from. /// is loading from.
bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,
unsigned Bytes, int Dist) const; unsigned Bytes, int Dist) const;
@ -1032,7 +1032,7 @@ class SelectionDAG {
std::vector<SDNode*> ValueTypeNodes; std::vector<SDNode*> ValueTypeNodes;
std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes; std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes;
StringMap<SDNode*> ExternalSymbols; StringMap<SDNode*> ExternalSymbols;
std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols; std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
}; };

View File

@ -127,6 +127,7 @@ class SelectionDAGISel : public MachineFunctionPass {
OPC_EmitInteger, OPC_EmitInteger,
OPC_EmitRegister, OPC_EmitRegister,
OPC_EmitRegister2,
OPC_EmitConvertToTarget, OPC_EmitConvertToTarget,
OPC_EmitMergeInputChains, OPC_EmitMergeInputChains,
OPC_EmitMergeInputChains1_0, OPC_EmitMergeInputChains1_0,
@ -257,7 +258,7 @@ class SelectionDAGISel : public MachineFunctionPass {
} }
virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
assert(0 && "Tblgen shoudl generate this!"); assert(0 && "Tblgen should generate this!");
return SDValue(); return SDValue();
} }
@ -279,7 +280,8 @@ class SelectionDAGISel : public MachineFunctionPass {
void PrepareEHLandingPad(); void PrepareEHLandingPad();
void SelectAllBasicBlocks(const Function &Fn); void SelectAllBasicBlocks(const Function &Fn);
bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS); bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst,
FastISel *FastIS);
void FinishBasicBlock(); void FinishBasicBlock();
void SelectBasicBlock(BasicBlock::const_iterator Begin, void SelectBasicBlock(BasicBlock::const_iterator Begin,

View File

@ -838,7 +838,7 @@ class TernarySDNode : public SDNode {
/// HandleSDNode - This class is used to form a handle around another node that /// HandleSDNode - This class is used to form a handle around another node that
/// is persistant and is updated across invocations of replaceAllUsesWith on its /// is persistent and is updated across invocations of replaceAllUsesWith on its
/// operand. This node should be directly created by end-users and not added to /// operand. This node should be directly created by end-users and not added to
/// the AllNodes list. /// the AllNodes list.
class HandleSDNode : public SDNode { class HandleSDNode : public SDNode {

View File

@ -34,77 +34,35 @@ namespace llvm {
/// SlotIndex & SlotIndexes classes for the public interface to this /// SlotIndex & SlotIndexes classes for the public interface to this
/// information. /// information.
class IndexListEntry { class IndexListEntry {
static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U,
TOMBSTONE_KEY_INDEX = ~0U & ~7U;
IndexListEntry *next, *prev; IndexListEntry *next, *prev;
MachineInstr *mi; MachineInstr *mi;
unsigned index; unsigned index;
protected:
typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType;
// This constructor is only to be used by getEmptyKeyEntry
// & getTombstoneKeyEntry. It sets index to the given
// value and mi to zero.
IndexListEntry(ReservedEntryType r) : mi(0) {
switch(r) {
case EMPTY_KEY: index = EMPTY_KEY_INDEX; break;
case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break;
default: assert(false && "Invalid value for constructor.");
}
next = this;
prev = this;
}
public: public:
IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) { IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
"Attempt to create invalid index. "
"Available indexes may have been exhausted?.");
}
bool isValid() const {
return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX);
}
MachineInstr* getInstr() const { return mi; } MachineInstr* getInstr() const { return mi; }
void setInstr(MachineInstr *mi) { void setInstr(MachineInstr *mi) {
assert(isValid() && "Attempt to modify reserved index.");
this->mi = mi; this->mi = mi;
} }
unsigned getIndex() const { return index; } unsigned getIndex() const { return index; }
void setIndex(unsigned index) { void setIndex(unsigned index) {
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
"Attempt to set index to invalid value.");
assert(isValid() && "Attempt to reset reserved index value.");
this->index = index; this->index = index;
} }
IndexListEntry* getNext() { return next; } IndexListEntry* getNext() { return next; }
const IndexListEntry* getNext() const { return next; } const IndexListEntry* getNext() const { return next; }
void setNext(IndexListEntry *next) { void setNext(IndexListEntry *next) {
assert(isValid() && "Attempt to modify reserved index.");
this->next = next; this->next = next;
} }
IndexListEntry* getPrev() { return prev; } IndexListEntry* getPrev() { return prev; }
const IndexListEntry* getPrev() const { return prev; } const IndexListEntry* getPrev() const { return prev; }
void setPrev(IndexListEntry *prev) { void setPrev(IndexListEntry *prev) {
assert(isValid() && "Attempt to modify reserved index.");
this->prev = prev; this->prev = prev;
} }
// This function returns the index list entry that is to be used for empty
// SlotIndex keys.
static IndexListEntry* getEmptyKeyEntry();
// This function returns the index list entry that is to be used for
// tombstone SlotIndex keys.
static IndexListEntry* getTombstoneKeyEntry();
}; };
// Specialize PointerLikeTypeTraits for IndexListEntry. // Specialize PointerLikeTypeTraits for IndexListEntry.
@ -130,11 +88,10 @@ namespace llvm {
PointerIntPair<IndexListEntry*, 2, unsigned> lie; PointerIntPair<IndexListEntry*, 2, unsigned> lie;
SlotIndex(IndexListEntry *entry, unsigned slot) SlotIndex(IndexListEntry *entry, unsigned slot)
: lie(entry, slot) { : lie(entry, slot) {}
assert(entry != 0 && "Attempt to construct index with 0 pointer.");
}
IndexListEntry& entry() const { IndexListEntry& entry() const {
assert(isValid() && "Attempt to compare reserved index.");
return *lie.getPointer(); return *lie.getPointer();
} }
@ -148,22 +105,27 @@ namespace llvm {
} }
static inline unsigned getHashValue(const SlotIndex &v) { static inline unsigned getHashValue(const SlotIndex &v) {
IndexListEntry *ptrVal = &v.entry(); void *ptrVal = v.lie.getOpaqueValue();
return (unsigned((intptr_t)ptrVal) >> 4) ^ return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9);
(unsigned((intptr_t)ptrVal) >> 9);
} }
public: public:
enum {
/// The default distance between instructions as returned by distance().
/// This may vary as instructions are inserted and removed.
InstrDist = 4*NUM
};
static inline SlotIndex getEmptyKey() { static inline SlotIndex getEmptyKey() {
return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); return SlotIndex(0, 1);
} }
static inline SlotIndex getTombstoneKey() { static inline SlotIndex getTombstoneKey() {
return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0); return SlotIndex(0, 2);
} }
/// Construct an invalid index. /// Construct an invalid index.
SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {} SlotIndex() : lie(0, 0) {}
// Construct a new slot index from the given one, and set the slot. // Construct a new slot index from the given one, and set the slot.
SlotIndex(const SlotIndex &li, Slot s) SlotIndex(const SlotIndex &li, Slot s)
@ -175,8 +137,7 @@ namespace llvm {
/// Returns true if this is a valid index. Invalid indicies do /// Returns true if this is a valid index. Invalid indicies do
/// not point into an index table, and cannot be compared. /// not point into an index table, and cannot be compared.
bool isValid() const { bool isValid() const {
IndexListEntry *entry = lie.getPointer(); return lie.getPointer();
return ((entry!= 0) && (entry->isValid()));
} }
/// Print this index to the given raw_ostream. /// Print this index to the given raw_ostream.
@ -187,11 +148,11 @@ namespace llvm {
/// Compare two SlotIndex objects for equality. /// Compare two SlotIndex objects for equality.
bool operator==(SlotIndex other) const { bool operator==(SlotIndex other) const {
return getIndex() == other.getIndex(); return lie == other.lie;
} }
/// Compare two SlotIndex objects for inequality. /// Compare two SlotIndex objects for inequality.
bool operator!=(SlotIndex other) const { bool operator!=(SlotIndex other) const {
return getIndex() != other.getIndex(); return lie != other.lie;
} }
/// Compare two SlotIndex objects. Return true if the first index /// Compare two SlotIndex objects. Return true if the first index
@ -217,6 +178,11 @@ namespace llvm {
return getIndex() >= other.getIndex(); return getIndex() >= other.getIndex();
} }
/// isSameInstr - Return true if A and B refer to the same instruction.
static bool isSameInstr(SlotIndex A, SlotIndex B) {
return A.lie.getPointer() == B.lie.getPointer();
}
/// Return the distance from this index to the given one. /// Return the distance from this index to the given one.
int distance(SlotIndex other) const { int distance(SlotIndex other) const {
return other.getIndex() - getIndex(); return other.getIndex() - getIndex();
@ -376,15 +342,12 @@ namespace llvm {
typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
Mi2IndexMap mi2iMap; Mi2IndexMap mi2iMap;
/// MBB2IdxMap - The indexes of the first and last instructions in the /// MBBRanges - Map MBB number to (start, stop) indexes.
/// specified basic block. SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges;
typedef DenseMap<const MachineBasicBlock*,
std::pair<SlotIndex, SlotIndex> > MBB2IdxMap;
MBB2IdxMap mbb2IdxMap;
/// Idx2MBBMap - Sorted list of pairs of index of first instruction /// Idx2MBBMap - Sorted list of pairs of index of first instruction
/// and MBB id. /// and MBB id.
std::vector<IdxMBBPair> idx2MBBMap; SmallVector<IdxMBBPair, 8> idx2MBBMap;
// IndexListEntry allocator. // IndexListEntry allocator.
BumpPtrAllocator ileAllocator; BumpPtrAllocator ileAllocator;
@ -466,6 +429,9 @@ namespace llvm {
insert(getTail(), val); insert(getTail(), val);
} }
/// Renumber locally after inserting newEntry.
void renumberIndexes(IndexListEntry *newEntry);
public: public:
static char ID; static char ID;
@ -530,7 +496,7 @@ namespace llvm {
/// Returns the instruction for the given index, or null if the given /// Returns the instruction for the given index, or null if the given
/// index has no instruction associated with it. /// index has no instruction associated with it.
MachineInstr* getInstructionFromIndex(SlotIndex index) const { MachineInstr* getInstructionFromIndex(SlotIndex index) const {
return index.entry().getInstr(); return index.isValid() ? index.entry().getInstr() : 0;
} }
/// Returns the next non-null index. /// Returns the next non-null index.
@ -545,12 +511,55 @@ namespace llvm {
return nextNonNull; return nextNonNull;
} }
/// getIndexBefore - Returns the index of the last indexed instruction
/// before MI, or the the start index of its basic block.
/// MI is not required to have an index.
SlotIndex getIndexBefore(const MachineInstr *MI) const {
const MachineBasicBlock *MBB = MI->getParent();
assert(MBB && "MI must be inserted inna basic block");
MachineBasicBlock::const_iterator I = MI, B = MBB->begin();
for (;;) {
if (I == B)
return getMBBStartIdx(MBB);
--I;
Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
if (MapItr != mi2iMap.end())
return MapItr->second;
}
}
/// getIndexAfter - Returns the index of the first indexed instruction
/// after MI, or the end index of its basic block.
/// MI is not required to have an index.
SlotIndex getIndexAfter(const MachineInstr *MI) const {
const MachineBasicBlock *MBB = MI->getParent();
assert(MBB && "MI must be inserted inna basic block");
MachineBasicBlock::const_iterator I = MI, E = MBB->end();
for (;;) {
++I;
if (I == E)
return getMBBEndIdx(MBB);
Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
if (MapItr != mi2iMap.end())
return MapItr->second;
}
}
/// Return the (start,end) range of the given basic block number.
const std::pair<SlotIndex, SlotIndex> &
getMBBRange(unsigned Num) const {
return MBBRanges[Num];
}
/// Return the (start,end) range of the given basic block. /// Return the (start,end) range of the given basic block.
const std::pair<SlotIndex, SlotIndex> & const std::pair<SlotIndex, SlotIndex> &
getMBBRange(const MachineBasicBlock *mbb) const { getMBBRange(const MachineBasicBlock *MBB) const {
MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); return getMBBRange(MBB->getNumber());
assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); }
return itr->second;
/// Returns the first index in the given basic block number.
SlotIndex getMBBStartIdx(unsigned Num) const {
return getMBBRange(Num).first;
} }
/// Returns the first index in the given basic block. /// Returns the first index in the given basic block.
@ -558,6 +567,11 @@ namespace llvm {
return getMBBRange(mbb).first; return getMBBRange(mbb).first;
} }
/// Returns the last index in the given basic block number.
SlotIndex getMBBEndIdx(unsigned Num) const {
return getMBBRange(Num).second;
}
/// Returns the last index in the given basic block. /// Returns the last index in the given basic block.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
return getMBBRange(mbb).second; return getMBBRange(mbb).second;
@ -565,10 +579,12 @@ namespace llvm {
/// Returns the basic block which the given index falls in. /// Returns the basic block which the given index falls in.
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
std::vector<IdxMBBPair>::const_iterator I = if (MachineInstr *MI = getInstructionFromIndex(index))
return MI->getParent();
SmallVectorImpl<IdxMBBPair>::const_iterator I =
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index);
// Take the pair containing the index // Take the pair containing the index
std::vector<IdxMBBPair>::const_iterator J = SmallVectorImpl<IdxMBBPair>::const_iterator J =
((I != idx2MBBMap.end() && I->first > index) || ((I != idx2MBBMap.end() && I->first > index) ||
(I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I;
@ -580,7 +596,7 @@ namespace llvm {
bool findLiveInMBBs(SlotIndex start, SlotIndex end, bool findLiveInMBBs(SlotIndex start, SlotIndex end,
SmallVectorImpl<MachineBasicBlock*> &mbbs) const { SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
std::vector<IdxMBBPair>::const_iterator itr = SmallVectorImpl<IdxMBBPair>::const_iterator itr =
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
bool resVal = false; bool resVal = false;
@ -600,7 +616,7 @@ namespace llvm {
assert(start < end && "Backwards ranges not allowed."); assert(start < end && "Backwards ranges not allowed.");
std::vector<IdxMBBPair>::const_iterator itr = SmallVectorImpl<IdxMBBPair>::const_iterator itr =
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
if (itr == idx2MBBMap.end()) { if (itr == idx2MBBMap.end()) {
@ -622,95 +638,47 @@ namespace llvm {
/// Insert the given machine instruction into the mapping. Returns the /// Insert the given machine instruction into the mapping. Returns the
/// assigned index. /// assigned index.
SlotIndex insertMachineInstrInMaps(MachineInstr *mi, /// If Late is set and there are null indexes between mi's neighboring
bool *deferredRenumber = 0) { /// instructions, create the new index after the null indexes instead of
/// before them.
SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late = false) {
assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed."); assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed.");
// Numbering DBG_VALUE instructions could cause code generation to be // Numbering DBG_VALUE instructions could cause code generation to be
// affected by debug information. // affected by debug information.
assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions."); assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions.");
MachineBasicBlock *mbb = mi->getParent(); assert(mi->getParent() != 0 && "Instr must be added to function.");
assert(mbb != 0 && "Instr must be added to function."); // Get the entries where mi should be inserted.
IndexListEntry *prevEntry, *nextEntry;
MBB2IdxMap::iterator mbbRangeItr = mbb2IdxMap.find(mbb); if (Late) {
// Insert mi's index immediately before the following instruction.
assert(mbbRangeItr != mbb2IdxMap.end() && nextEntry = &getIndexAfter(mi).entry();
"Instruction's parent MBB has not been added to SlotIndexes."); prevEntry = nextEntry->getPrev();
} else {
MachineBasicBlock::iterator miItr(mi); // Insert mi's index immediately after the preceeding instruction.
bool needRenumber = false; prevEntry = &getIndexBefore(mi).entry();
IndexListEntry *newEntry; nextEntry = prevEntry->getNext();
// Get previous index, considering that not all instructions are indexed.
IndexListEntry *prevEntry;
for (;;) {
// If mi is at the mbb beginning, get the prev index from the mbb.
if (miItr == mbb->begin()) {
prevEntry = &mbbRangeItr->second.first.entry();
break;
}
// Otherwise rewind until we find a mapped instruction.
Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr);
if (itr != mi2iMap.end()) {
prevEntry = &itr->second.entry();
break;
}
} }
// Get next entry from previous entry.
IndexListEntry *nextEntry = prevEntry->getNext();
// Get a number for the new instr, or 0 if there's no room currently. // Get a number for the new instr, or 0 if there's no room currently.
// In the latter case we'll force a renumber later. // In the latter case we'll force a renumber later.
unsigned dist = nextEntry->getIndex() - prevEntry->getIndex(); unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u;
unsigned newNumber = dist > SlotIndex::NUM ? unsigned newNumber = prevEntry->getIndex() + dist;
prevEntry->getIndex() + ((dist >> 1) & ~3U) : 0;
if (newNumber == 0) {
needRenumber = true;
}
// Insert a new list entry for mi. // Insert a new list entry for mi.
newEntry = createEntry(mi, newNumber); IndexListEntry *newEntry = createEntry(mi, newNumber);
insert(nextEntry, newEntry); insert(nextEntry, newEntry);
// Renumber locally if we need to.
if (dist == 0)
renumberIndexes(newEntry);
SlotIndex newIndex(newEntry, SlotIndex::LOAD); SlotIndex newIndex(newEntry, SlotIndex::LOAD);
mi2iMap.insert(std::make_pair(mi, newIndex)); mi2iMap.insert(std::make_pair(mi, newIndex));
if (miItr == mbb->end()) {
// If this is the last instr in the MBB then we need to fix up the bb
// range:
mbbRangeItr->second.second = SlotIndex(newEntry, SlotIndex::STORE);
}
// Renumber if we need to.
if (needRenumber) {
if (deferredRenumber == 0)
renumberIndexes();
else
*deferredRenumber = true;
}
return newIndex; return newIndex;
} }
/// Add all instructions in the vector to the index list. This method will
/// defer renumbering until all instrs have been added, and should be
/// preferred when adding multiple instrs.
void insertMachineInstrsInMaps(SmallVectorImpl<MachineInstr*> &mis) {
bool renumber = false;
for (SmallVectorImpl<MachineInstr*>::iterator
miItr = mis.begin(), miEnd = mis.end();
miItr != miEnd; ++miItr) {
insertMachineInstrInMaps(*miItr, &renumber);
}
if (renumber)
renumberIndexes();
}
/// Remove the given machine instruction from the mapping. /// Remove the given machine instruction from the mapping.
void removeMachineInstrFromMaps(MachineInstr *mi) { void removeMachineInstrFromMaps(MachineInstr *mi) {
// remove index -> MachineInstr and // remove index -> MachineInstr and
@ -760,21 +728,14 @@ namespace llvm {
SlotIndex startIdx(startEntry, SlotIndex::LOAD); SlotIndex startIdx(startEntry, SlotIndex::LOAD);
SlotIndex endIdx(nextEntry, SlotIndex::LOAD); SlotIndex endIdx(nextEntry, SlotIndex::LOAD);
mbb2IdxMap.insert( assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&
std::make_pair(mbb, std::make_pair(startIdx, endIdx))); "Blocks must be added in order");
MBBRanges.push_back(std::make_pair(startIdx, endIdx));
idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) {
// Have to update the end index of the previous block.
MachineBasicBlock *priorMBB =
llvm::prior(MachineFunction::iterator(mbb));
mbb2IdxMap[priorMBB].second = startIdx;
}
renumberIndexes(); renumberIndexes();
std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
} }
}; };

View File

@ -59,6 +59,10 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
virtual const MCSection *getEHFrameSection() const; virtual const MCSection *getEHFrameSection() const;
virtual void emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
const MCSymbol *Sym) const;
const MCSection *getDataRelSection() const { return DataRelSection; } const MCSection *getDataRelSection() const { return DataRelSection; }
/// getSectionForConstant - Given a constant with the SectionKind, return a /// getSectionForConstant - Given a constant with the SectionKind, return a
@ -81,6 +85,11 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfo *MMI, unsigned Encoding, MachineModuleInfo *MMI, unsigned Encoding,
MCStreamer &Streamer) const; MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfo *MMI) const;
}; };
@ -94,7 +103,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
/// ///
const MCSection *TLSBSSSection; // Defaults to ".tbss". const MCSection *TLSBSSSection; // Defaults to ".tbss".
/// TLSTLVSection - Section for thread local structure infomation. /// TLSTLVSection - Section for thread local structure information.
/// Contains the source code name of the variable, visibility and a pointer /// Contains the source code name of the variable, visibility and a pointer
/// to the initial value (.tdata or .tbss). /// to the initial value (.tdata or .tbss).
const MCSection *TLSTLVSection; // Defaults to ".tlv". const MCSection *TLSTLVSection; // Defaults to ".tlv".
@ -172,9 +181,14 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
MachineModuleInfo *MMI, unsigned Encoding, MachineModuleInfo *MMI, unsigned Encoding,
MCStreamer &Streamer) const; MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfo *MMI) const;
virtual unsigned getPersonalityEncoding() const; virtual unsigned getPersonalityEncoding() const;
virtual unsigned getLSDAEncoding() const; virtual unsigned getLSDAEncoding() const;
virtual unsigned getFDEEncoding() const; virtual unsigned getFDEEncoding(bool CFI) const;
virtual unsigned getTTypeEncoding() const; virtual unsigned getTTypeEncoding() const;
}; };

View File

@ -40,7 +40,7 @@ namespace llvmc {
}; };
/// Edge - Represents an edge of the compilation graph. /// Edge - Represents an edge of the compilation graph.
class Edge : public llvm::RefCountedBaseVPTR<Edge> { class Edge : public llvm::RefCountedBaseVPTR {
public: public:
Edge(const std::string& T) : ToolName_(T) {} Edge(const std::string& T) : ToolName_(T) {}
virtual ~Edge() {} virtual ~Edge() {}

View File

@ -33,7 +33,7 @@ namespace llvmc {
typedef llvm::StringSet<> InputLanguagesSet; typedef llvm::StringSet<> InputLanguagesSet;
/// Tool - Represents a single tool. /// Tool - Represents a single tool.
class Tool : public llvm::RefCountedBaseVPTR<Tool> { class Tool : public llvm::RefCountedBaseVPTR {
public: public:
virtual ~Tool() {} virtual ~Tool() {}

View File

@ -47,10 +47,6 @@ class Constant : public User {
: User(ty, vty, Ops, NumOps) {} : User(ty, vty, Ops, NumOps) {}
void destroyConstantImpl(); void destroyConstantImpl();
void setOperand(unsigned i, Value *V) {
User::setOperand(i, V);
}
public: public:
/// isNullValue - Return true if this is the value that would be returned by /// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. /// getNullValue.
@ -90,15 +86,6 @@ class Constant : public User {
/// FIXME: This really should not be in VMCore. /// FIXME: This really should not be in VMCore.
PossibleRelocationsTy getRelocationInfo() const; PossibleRelocationsTy getRelocationInfo() const;
// Specialize get/setOperand for Users as their operands are always
// constants or BasicBlocks as well.
User *getOperand(unsigned i) {
return static_cast<User*>(User::getOperand(i));
}
const User *getOperand(unsigned i) const {
return static_cast<const User*>(User::getOperand(i));
}
/// getVectorElements - This method, which is only valid on constant of vector /// getVectorElements - This method, which is only valid on constant of vector
/// type, returns the elements of the vector in the specified smallvector. /// type, returns the elements of the vector in the specified smallvector.
/// This handles breaking down a vector undef into undef elements, etc. For /// This handles breaking down a vector undef into undef elements, etc. For

View File

@ -57,6 +57,8 @@ class ConstantInt : public Constant {
public: public:
static ConstantInt *getTrue(LLVMContext &Context); static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context); static ConstantInt *getFalse(LLVMContext &Context);
static Constant *getTrue(const Type *Ty);
static Constant *getFalse(const Type *Ty);
/// If Ty is a vector type, return a Constant with a splat of the given /// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value. /// value. Otherwise return a ConstantInt for the given value.
@ -425,6 +427,8 @@ class ConstantStruct : public Constant {
const std::vector<Constant*> &V, bool Packed); const std::vector<Constant*> &V, bool Packed);
static Constant *get(LLVMContext &Context, static Constant *get(LLVMContext &Context,
Constant *const *Vals, unsigned NumVals, bool Packed); Constant *const *Vals, unsigned NumVals, bool Packed);
static Constant *get(LLVMContext &Context, bool Packed,
Constant * Val, ...) END_WITH_NULL;
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
@ -599,6 +603,7 @@ struct OperandTraits<BlockAddress> :
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value) DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// ConstantExpr - a constant value that is initialized with an expression using /// ConstantExpr - a constant value that is initialized with an expression using
/// other constant values. /// other constant values.
@ -836,7 +841,7 @@ class ConstantExpr : public Constant {
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS); static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS); static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
/// Getelementptr form. std::vector<Value*> is only accepted for convenience: /// Getelementptr form. Value* is only accepted for convenience;
/// all elements must be Constant's. /// all elements must be Constant's.
/// ///
static Constant *getGetElementPtr(Constant *C, static Constant *getGetElementPtr(Constant *C,
@ -880,7 +885,7 @@ class ConstantExpr : public Constant {
/// getIndices - Assert that this is an insertvalue or exactvalue /// getIndices - Assert that this is an insertvalue or exactvalue
/// expression and return the list of indices. /// expression and return the list of indices.
const SmallVector<unsigned, 4> &getIndices() const; ArrayRef<unsigned> getIndices() const;
/// getOpcodeName - Return a string representation for an opcode. /// getOpcodeName - Return a string representation for an opcode.
const char *getOpcodeName() const; const char *getOpcodeName() const;
@ -892,10 +897,7 @@ class ConstantExpr : public Constant {
/// getWithOperands - This returns the current constant expression with the /// getWithOperands - This returns the current constant expression with the
/// operands replaced with the specified values. The specified operands must /// operands replaced with the specified values. The specified operands must
/// match count and type with the existing ones. /// match count and type with the existing ones.
Constant *getWithOperands(const std::vector<Constant*> &Ops) const { Constant *getWithOperands(ArrayRef<Constant*> Ops) const;
return getWithOperands(&Ops[0], (unsigned)Ops.size());
}
Constant *getWithOperands(Constant *const *Ops, unsigned NumOps) const;
virtual void destroyConstant(); virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);

View File

@ -0,0 +1,67 @@
//===-- DebugInfoProbe.h - DebugInfo Probe ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a probe, DebugInfoProbe, that can be used by pass
// manager to analyze how optimizer is treating debugging information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H
#define LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H
#include "llvm/ADT/StringMap.h"
namespace llvm {
class Function;
class Pass;
class DebugInfoProbeImpl;
/// DebugInfoProbe - This class provides a interface to monitor
/// how an optimization pass is preserving debugging information.
class DebugInfoProbe {
public:
DebugInfoProbe();
~DebugInfoProbe();
/// initialize - Collect information before running an optimization pass.
void initialize(StringRef PName, Function &F);
/// finalize - Collect information after running an optimization pass. This
/// must be used after initialization.
void finalize(Function &F);
/// report - Report findings. This should be invoked after finalize.
void report();
private:
DebugInfoProbeImpl *pImpl;
};
/// DebugInfoProbeInfo - This class provides an interface that a pass manager
/// can use to manage debug info probes.
class DebugInfoProbeInfo {
StringMap<DebugInfoProbe *> Probes;
public:
DebugInfoProbeInfo() {}
/// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
/// them.
~DebugInfoProbeInfo();
/// initialize - Collect information before running an optimization pass.
void initialize(Pass *P, Function &F);
/// finalize - Collect information after running an optimization pass. This
/// must be used after initialization.
void finalize(Pass *P, Function &F);
};
} // End llvm namespace
#endif

View File

@ -19,6 +19,7 @@
#define LLVM_DERIVED_TYPES_H #define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm { namespace llvm {
@ -147,7 +148,7 @@ class FunctionType : public DerivedType {
FunctionType(const FunctionType &); // Do not implement FunctionType(const FunctionType &); // Do not implement
const FunctionType &operator=(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement
FunctionType(const Type *Result, const std::vector<const Type*> &Params, FunctionType(const Type *Result, ArrayRef<const Type*> Params,
bool IsVarArgs); bool IsVarArgs);
public: public:
@ -156,7 +157,7 @@ class FunctionType : public DerivedType {
/// ///
static FunctionType *get( static FunctionType *get(
const Type *Result, ///< The result type const Type *Result, ///< The result type
const std::vector<const Type*> &Params, ///< The types of the parameters ArrayRef<const Type*> Params, ///< The types of the parameters
bool isVarArg ///< Whether this is a variable argument length function bool isVarArg ///< Whether this is a variable argument length function
); );
@ -166,7 +167,7 @@ class FunctionType : public DerivedType {
const Type *Result, ///< The result type const Type *Result, ///< The result type
bool isVarArg ///< Whether this is a variable argument length function bool isVarArg ///< Whether this is a variable argument length function
) { ) {
return get(Result, std::vector<const Type *>(), isVarArg); return get(Result, ArrayRef<const Type *>(), isVarArg);
} }
/// isValidReturnType - Return true if the specified type is valid as a return /// isValidReturnType - Return true if the specified type is valid as a return
@ -237,20 +238,19 @@ class StructType : public CompositeType {
friend class TypeMap<StructValType, StructType>; friend class TypeMap<StructValType, StructType>;
StructType(const StructType &); // Do not implement StructType(const StructType &); // Do not implement
const StructType &operator=(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement
StructType(LLVMContext &C, StructType(LLVMContext &C, ArrayRef<const Type*> Types, bool isPacked);
const std::vector<const Type*> &Types, bool isPacked);
public: public:
/// StructType::get - This static method is the primary way to create a /// StructType::get - This static method is the primary way to create a
/// StructType. /// StructType.
/// ///
static StructType *get(LLVMContext &Context, static StructType *get(LLVMContext &Context,
const std::vector<const Type*> &Params, ArrayRef<const Type*> Params,
bool isPacked=false); bool isPacked=false);
/// StructType::get - Create an empty structure type. /// StructType::get - Create an empty structure type.
/// ///
static StructType *get(LLVMContext &Context, bool isPacked=false) { static StructType *get(LLVMContext &Context, bool isPacked=false) {
return get(Context, std::vector<const Type*>(), isPacked); return get(Context, llvm::ArrayRef<const Type*>(), isPacked);
} }
/// StructType::get - This static method is a convenience method for /// StructType::get - This static method is a convenience method for

View File

@ -21,6 +21,7 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/ValueMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h" #include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Mutex.h" #include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -117,11 +118,11 @@ class ExecutionEngine {
/// The list of Modules that we are JIT'ing from. We use a SmallVector to /// The list of Modules that we are JIT'ing from. We use a SmallVector to
/// optimize for the case where there is only one module. /// optimize for the case where there is only one module.
SmallVector<Module*, 1> Modules; SmallVector<Module*, 1> Modules;
void setTargetData(const TargetData *td) { void setTargetData(const TargetData *td) {
TD = td; TD = td;
} }
/// getMemoryforGV - Allocate memory for a global variable. /// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV); virtual char *getMemoryForGV(const GlobalVariable *GV);
@ -155,13 +156,15 @@ class ExecutionEngine {
/// pointer is invoked to create it. If this returns null, the JIT will /// pointer is invoked to create it. If this returns null, the JIT will
/// abort. /// abort.
void *(*LazyFunctionCreator)(const std::string &); void *(*LazyFunctionCreator)(const std::string &);
/// ExceptionTableRegister - If Exception Handling is set, the JIT will /// ExceptionTableRegister - If Exception Handling is set, the JIT will
/// register dwarf tables with this function. /// register dwarf tables with this function.
typedef void (*EERegisterFn)(void*); typedef void (*EERegisterFn)(void*);
EERegisterFn ExceptionTableRegister; EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableDeregister; EERegisterFn ExceptionTableDeregister;
std::vector<void*> AllExceptionTables; /// This maps functions to their exception tables frames.
DenseMap<const Function*, void*> AllExceptionTables;
public: public:
/// lock - This lock protects the ExecutionEngine, JIT, JITResolver and /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and
@ -182,7 +185,7 @@ class ExecutionEngine {
/// \param GVsWithCode - Allocating globals with code breaks /// \param GVsWithCode - Allocating globals with code breaks
/// freeMachineCodeForFunction and is probably unsafe and bad for performance. /// freeMachineCodeForFunction and is probably unsafe and bad for performance.
/// However, we have clients who depend on this behavior, so we must support /// However, we have clients who depend on this behavior, so we must support
/// it. Eventually, when we're willing to break some backwards compatability, /// it. Eventually, when we're willing to break some backwards compatibility,
/// this flag should be flipped to false, so that by default /// this flag should be flipped to false, so that by default
/// freeMachineCodeForFunction works. /// freeMachineCodeForFunction works.
static ExecutionEngine *create(Module *M, static ExecutionEngine *create(Module *M,
@ -213,7 +216,7 @@ class ExecutionEngine {
virtual void addModule(Module *M) { virtual void addModule(Module *M) {
Modules.push_back(M); Modules.push_back(M);
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
const TargetData *getTargetData() const { return TD; } const TargetData *getTargetData() const { return TD; }
@ -226,7 +229,7 @@ class ExecutionEngine {
/// defines FnName. This is very slow operation and shouldn't be used for /// defines FnName. This is very slow operation and shouldn't be used for
/// general code. /// general code.
Function *FindFunctionNamed(const char *FnName); Function *FindFunctionNamed(const char *FnName);
/// runFunction - Execute the specified function with the specified arguments, /// runFunction - Execute the specified function with the specified arguments,
/// and return the result. /// and return the result.
virtual GenericValue runFunction(Function *F, virtual GenericValue runFunction(Function *F,
@ -243,8 +246,8 @@ class ExecutionEngine {
/// ///
/// \param isDtors - Run the destructors instead of constructors. /// \param isDtors - Run the destructors instead of constructors.
void runStaticConstructorsDestructors(Module *module, bool isDtors); void runStaticConstructorsDestructors(Module *module, bool isDtors);
/// runFunctionAsMain - This is a helper function which wraps runFunction to /// runFunctionAsMain - This is a helper function which wraps runFunction to
/// handle the common task of starting up main with the specified argc, argv, /// handle the common task of starting up main with the specified argc, argv,
/// and envp parameters. /// and envp parameters.
@ -259,21 +262,21 @@ class ExecutionEngine {
/// existing data in memory. Mappings are automatically removed when their /// existing data in memory. Mappings are automatically removed when their
/// GlobalValue is destroyed. /// GlobalValue is destroyed.
void addGlobalMapping(const GlobalValue *GV, void *Addr); void addGlobalMapping(const GlobalValue *GV, void *Addr);
/// clearAllGlobalMappings - Clear all global mappings and start over again, /// clearAllGlobalMappings - Clear all global mappings and start over again,
/// for use in dynamic compilation scenarios to move globals. /// for use in dynamic compilation scenarios to move globals.
void clearAllGlobalMappings(); void clearAllGlobalMappings();
/// clearGlobalMappingsFromModule - Clear all global mappings that came from a /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
/// particular module, because it has been removed from the JIT. /// particular module, because it has been removed from the JIT.
void clearGlobalMappingsFromModule(Module *M); void clearGlobalMappingsFromModule(Module *M);
/// updateGlobalMapping - Replace an existing mapping for GV with a new /// updateGlobalMapping - Replace an existing mapping for GV with a new
/// address. This updates both maps as required. If "Addr" is null, the /// address. This updates both maps as required. If "Addr" is null, the
/// entry for the global is removed from the mappings. This returns the old /// entry for the global is removed from the mappings. This returns the old
/// value of the pointer, or null if it was not in the map. /// value of the pointer, or null if it was not in the map.
void *updateGlobalMapping(const GlobalValue *GV, void *Addr); void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
/// getPointerToGlobalIfAvailable - This returns the address of the specified /// getPointerToGlobalIfAvailable - This returns the address of the specified
/// global value if it is has already been codegen'd, otherwise it returns /// global value if it is has already been codegen'd, otherwise it returns
/// null. /// null.
@ -294,7 +297,7 @@ class ExecutionEngine {
/// different ways. Return the representation for a blockaddress of the /// different ways. Return the representation for a blockaddress of the
/// specified block. /// specified block.
virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
/// getPointerToFunctionOrStub - If the specified function has been /// getPointerToFunctionOrStub - If the specified function has been
/// code-gen'd, return a pointer to the function. If not, compile it, or use /// code-gen'd, return a pointer to the function. If not, compile it, or use
/// a stub to implement lazy compilation if available. See /// a stub to implement lazy compilation if available. See
@ -398,7 +401,7 @@ class ExecutionEngine {
void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
LazyFunctionCreator = P; LazyFunctionCreator = P;
} }
/// InstallExceptionTableRegister - The JIT will use the given function /// InstallExceptionTableRegister - The JIT will use the given function
/// to register the exception tables it generates. /// to register the exception tables it generates.
void InstallExceptionTableRegister(EERegisterFn F) { void InstallExceptionTableRegister(EERegisterFn F) {
@ -407,13 +410,26 @@ class ExecutionEngine {
void InstallExceptionTableDeregister(EERegisterFn F) { void InstallExceptionTableDeregister(EERegisterFn F) {
ExceptionTableDeregister = F; ExceptionTableDeregister = F;
} }
/// RegisterTable - Registers the given pointer as an exception table. It /// RegisterTable - Registers the given pointer as an exception table. It
/// uses the ExceptionTableRegister function. /// uses the ExceptionTableRegister function.
void RegisterTable(void* res) { void RegisterTable(const Function *fn, void* res) {
if (ExceptionTableRegister) { if (ExceptionTableRegister) {
ExceptionTableRegister(res); ExceptionTableRegister(res);
AllExceptionTables.push_back(res); AllExceptionTables[fn] = res;
}
}
/// DeregisterTable - Deregisters the exception frame previously registered
/// for the given function.
void DeregisterTable(const Function *Fn) {
if (ExceptionTableDeregister) {
DenseMap<const Function*, void*>::iterator frame =
AllExceptionTables.find(Fn);
if(frame != AllExceptionTables.end()) {
ExceptionTableDeregister(frame->second);
AllExceptionTables.erase(frame);
}
} }
} }
@ -429,7 +445,7 @@ class ExecutionEngine {
void EmitGlobalVariable(const GlobalVariable *GV); void EmitGlobalVariable(const GlobalVariable *GV);
GenericValue getConstantValue(const Constant *C); GenericValue getConstantValue(const Constant *C);
void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
const Type *Ty); const Type *Ty);
}; };
@ -540,8 +556,9 @@ class EngineBuilder {
/// setUseMCJIT - Set whether the MC-JIT implementation should be used /// setUseMCJIT - Set whether the MC-JIT implementation should be used
/// (experimental). /// (experimental).
void setUseMCJIT(bool Value) { EngineBuilder &setUseMCJIT(bool Value) {
UseMCJIT = Value; UseMCJIT = Value;
return *this;
} }
/// setMAttrs - Set cpu-specific attributes. /// setMAttrs - Set cpu-specific attributes.

View File

@ -29,11 +29,11 @@ class JITMemoryManager {
public: public:
JITMemoryManager() : HasGOT(false) {} JITMemoryManager() : HasGOT(false) {}
virtual ~JITMemoryManager(); virtual ~JITMemoryManager();
/// CreateDefaultMemManager - This is used to create the default /// CreateDefaultMemManager - This is used to create the default
/// JIT Memory Manager if the client does not provide one to the JIT. /// JIT Memory Manager if the client does not provide one to the JIT.
static JITMemoryManager *CreateDefaultMemManager(); static JITMemoryManager *CreateDefaultMemManager();
/// setMemoryWritable - When code generation is in progress, /// setMemoryWritable - When code generation is in progress,
/// the code pages may need permissions changed. /// the code pages may need permissions changed.
virtual void setMemoryWritable() = 0; virtual void setMemoryWritable() = 0;
@ -55,16 +55,16 @@ class JITMemoryManager {
/// method is invoked to allocate it. This method is required to set HasGOT /// method is invoked to allocate it. This method is required to set HasGOT
/// to true. /// to true.
virtual void AllocateGOT() = 0; virtual void AllocateGOT() = 0;
/// isManagingGOT - Return true if the AllocateGOT method is called. /// isManagingGOT - Return true if the AllocateGOT method is called.
bool isManagingGOT() const { bool isManagingGOT() const {
return HasGOT; return HasGOT;
} }
/// getGOTBase - If this is managing a Global Offset Table, this method should /// getGOTBase - If this is managing a Global Offset Table, this method should
/// return a pointer to its base. /// return a pointer to its base.
virtual uint8_t *getGOTBase() const = 0; virtual uint8_t *getGOTBase() const = 0;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Main Allocation Functions // Main Allocation Functions
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -91,11 +91,11 @@ class JITMemoryManager {
/// startFunctionBody. /// startFunctionBody.
virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
unsigned Alignment) = 0; unsigned Alignment) = 0;
/// endFunctionBody - This method is called when the JIT is done codegen'ing /// endFunctionBody - This method is called when the JIT is done codegen'ing
/// the specified function. At this point we know the size of the JIT /// the specified function. At this point we know the size of the JIT
/// compiled function. This passes in FunctionStart (which was returned by /// compiled function. This passes in FunctionStart (which was returned by
/// the startFunctionBody method) and FunctionEnd which is a pointer to the /// the startFunctionBody method) and FunctionEnd which is a pointer to the
/// actual end of the function. This method should mark the space allocated /// actual end of the function. This method should mark the space allocated
/// and remember where it is in case the client wants to deallocate it. /// and remember where it is in case the client wants to deallocate it.
virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
@ -113,12 +113,12 @@ class JITMemoryManager {
/// been deallocated yet. This is never called when the JIT is currently /// been deallocated yet. This is never called when the JIT is currently
/// emitting a function. /// emitting a function.
virtual void deallocateFunctionBody(void *Body) = 0; virtual void deallocateFunctionBody(void *Body) = 0;
/// startExceptionTable - When we finished JITing the function, if exception /// startExceptionTable - When we finished JITing the function, if exception
/// handling is set, we emit the exception table. /// handling is set, we emit the exception table.
virtual uint8_t* startExceptionTable(const Function* F, virtual uint8_t* startExceptionTable(const Function* F,
uintptr_t &ActualSize) = 0; uintptr_t &ActualSize) = 0;
/// endExceptionTable - This method is called when the JIT is done emitting /// endExceptionTable - This method is called when the JIT is done emitting
/// the exception table. /// the exception table.
virtual void endExceptionTable(const Function *F, uint8_t *TableStart, virtual void endExceptionTable(const Function *F, uint8_t *TableStart,

View File

@ -0,0 +1,75 @@
//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Interface for the runtime dynamic linker facilities of the MC-JIT.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_RUNTIME_DYLD_H
#define LLVM_RUNTIME_DYLD_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Memory.h"
namespace llvm {
class RuntimeDyldImpl;
class MemoryBuffer;
// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is an abstraction layer
// over the JITMemoryManager, which references objects by their source
// representations in LLVM IR.
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
// for the varying types of objects to be allocated.
class RTDyldMemoryManager {
RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
public:
RTDyldMemoryManager() {}
virtual ~RTDyldMemoryManager();
// Allocate ActualSize bytes, or more, for the named function. Return
// a pointer to the allocated memory and update Size to reflect how much
// memory was acutally allocated.
virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0;
// Mark the end of the function, including how much of the allocated
// memory was actually used.
virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart,
uint8_t *FunctionEnd) = 0;
};
class RuntimeDyld {
RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
// interface.
RuntimeDyldImpl *Dyld;
public:
RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld();
bool loadObject(MemoryBuffer *InputBuffer);
// Get the address of our local copy of the symbol. This may or may not
// be the address used for relocation (clients can copy the data around
// and resolve relocatons based on where they put it).
void *getSymbolAddress(StringRef Name);
// Resolve the relocations for all symbols we currently know about.
void resolveRelocations();
// Change the address associated with a symbol when resolving relocations.
// Any relocations already associated with the symbol will be re-resolved.
void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
StringRef getErrorString();
};
} // end namespace llvm
#endif

View File

@ -12,7 +12,7 @@
// //
// Global variables are constant pointers that refer to hunks of space that are // Global variables are constant pointers that refer to hunks of space that are
// allocated by either the VM, or by the linker in a static compiler. A global // allocated by either the VM, or by the linker in a static compiler. A global
// variable may have an intial value, which is copied into the executables .data // variable may have an initial value, which is copied into the executables .data
// area. Global Constants are required to have initializers. // area. Global Constants are required to have initializers.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -94,12 +94,12 @@ void initializeDominatorTreePass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&); void initializeEdgeBundlesPass(PassRegistry&);
void initializeEdgeProfilerPass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&);
void initializePathProfilerPass(PassRegistry&); void initializePathProfilerPass(PassRegistry&);
void initializeGCOVProfilerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&);
void initializeFindUsedTypesPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&);
void initializeFunctionAttrsPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&);
void initializeGCModuleInfoPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&);
void initializeGEPSplitterPass(PassRegistry&);
void initializeGVNPass(PassRegistry&); void initializeGVNPass(PassRegistry&);
void initializeGlobalDCEPass(PassRegistry&); void initializeGlobalDCEPass(PassRegistry&);
void initializeGlobalOptPass(PassRegistry&); void initializeGlobalOptPass(PassRegistry&);
@ -123,7 +123,6 @@ void initializeLintPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&); void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&); void initializeLiveIntervalsPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&);
void initializeLiveValuesPass(PassRegistry&);
void initializeLiveVariablesPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&);
void initializeLoaderPassPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&);
void initializePathProfileLoaderPassPass(PassRegistry&); void initializePathProfileLoaderPassPass(PassRegistry&);
@ -170,7 +169,6 @@ void initializePostDomOnlyPrinterPass(PassRegistry&);
void initializePostDomOnlyViewerPass(PassRegistry&); void initializePostDomOnlyViewerPass(PassRegistry&);
void initializePostDomPrinterPass(PassRegistry&); void initializePostDomPrinterPass(PassRegistry&);
void initializePostDomViewerPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&);
void initializePostDominanceFrontierPass(PassRegistry&);
void initializePostDominatorTreePass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&);
void initializePreAllocSplittingPass(PassRegistry&); void initializePreAllocSplittingPass(PassRegistry&);
void initializePreVerifierPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&);
@ -196,14 +194,12 @@ void initializeRegionViewerPass(PassRegistry&);
void initializeRegisterCoalescerAnalysisGroup(PassRegistry&); void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
void initializeRenderMachineFunctionPass(PassRegistry&); void initializeRenderMachineFunctionPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&); void initializeSCCPPass(PassRegistry&);
void initializeSRETPromotionPass(PassRegistry&);
void initializeSROA_DTPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&);
void initializeSROA_SSAUpPass(PassRegistry&); void initializeSROA_SSAUpPass(PassRegistry&);
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
void initializeScalarEvolutionPass(PassRegistry&); void initializeScalarEvolutionPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&);
void initializeSimpleRegisterCoalescingPass(PassRegistry&); void initializeSimpleRegisterCoalescingPass(PassRegistry&);
void initializeSimplifyHalfPowrLibCallsPass(PassRegistry&);
void initializeSimplifyLibCallsPass(PassRegistry&); void initializeSimplifyLibCallsPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingPass(PassRegistry&); void initializeSinkingPass(PassRegistry&);

View File

@ -18,7 +18,6 @@
#include "llvm/Instruction.h" #include "llvm/Instruction.h"
#include "llvm/OperandTraits.h" #include "llvm/OperandTraits.h"
#include "llvm/Operator.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/ADT/Twine.h" #include "llvm/ADT/Twine.h"

View File

@ -584,7 +584,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
/// @brief Represent an integer comparison operator. /// @brief Represent an integer comparison operator.
class ICmpInst: public CmpInst { class ICmpInst: public CmpInst {
protected: protected:
/// @brief Clone an indentical ICmpInst /// @brief Clone an identical ICmpInst
virtual ICmpInst *clone_impl() const; virtual ICmpInst *clone_impl() const;
public: public:
/// @brief Constructor with insert-before-instruction semantics. /// @brief Constructor with insert-before-instruction semantics.
@ -735,7 +735,7 @@ class ICmpInst: public CmpInst {
/// @brief Represents a floating point comparison operator. /// @brief Represents a floating point comparison operator.
class FCmpInst: public CmpInst { class FCmpInst: public CmpInst {
protected: protected:
/// @brief Clone an indentical FCmpInst /// @brief Clone an identical FCmpInst
virtual FCmpInst *clone_impl() const; virtual FCmpInst *clone_impl() const;
public: public:
/// @brief Constructor with insert-before-instruction semantics. /// @brief Constructor with insert-before-instruction semantics.
@ -1811,39 +1811,37 @@ class PHINode : public Instruction {
void *operator new(size_t s) { void *operator new(size_t s) {
return User::operator new(s, 0); return User::operator new(s, 0);
} }
explicit PHINode(const Type *Ty, const Twine &NameStr = "", explicit PHINode(const Type *Ty, unsigned NumReservedValues,
Instruction *InsertBefore = 0) const Twine &NameStr = "", Instruction *InsertBefore = 0)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
ReservedSpace(0) { ReservedSpace(NumReservedValues * 2) {
setName(NameStr); setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace);
} }
PHINode(const Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd) PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
ReservedSpace(0) { ReservedSpace(NumReservedValues * 2) {
setName(NameStr); setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace);
} }
protected: protected:
virtual PHINode *clone_impl() const; virtual PHINode *clone_impl() const;
public: public:
static PHINode *Create(const Type *Ty, const Twine &NameStr = "", /// Constructors - NumReservedValues is a hint for the number of incoming
/// edges that this phi node will have (use 0 if you really have no idea).
static PHINode *Create(const Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) { Instruction *InsertBefore = 0) {
return new PHINode(Ty, NameStr, InsertBefore); return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
} }
static PHINode *Create(const Type *Ty, const Twine &NameStr, static PHINode *Create(const Type *Ty, unsigned NumReservedValues,
BasicBlock *InsertAtEnd) { const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new PHINode(Ty, NameStr, InsertAtEnd); return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
} }
~PHINode(); ~PHINode();
/// reserveOperandSpace - This method can be used to avoid repeated
/// reallocation of PHI operand lists by reserving space for the correct
/// number of operands before adding them. Unlike normal vector reserves,
/// this method can also be used to trim the operand space.
void reserveOperandSpace(unsigned NumValues) {
resizeOperands(NumValues*2);
}
/// Provide fast operand accessors /// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@ -1912,7 +1910,7 @@ class PHINode : public Instruction {
"All operands to PHI node must be the same type as the PHI node!"); "All operands to PHI node must be the same type as the PHI node!");
unsigned OpNo = NumOperands; unsigned OpNo = NumOperands;
if (OpNo+2 > ReservedSpace) if (OpNo+2 > ReservedSpace)
resizeOperands(0); // Get more space! growOperands(); // Get more space!
// Initialize some new operands. // Initialize some new operands.
NumOperands = OpNo+2; NumOperands = OpNo+2;
OperandList[OpNo] = V; OperandList[OpNo] = V;
@ -1962,7 +1960,7 @@ class PHINode : public Instruction {
return isa<Instruction>(V) && classof(cast<Instruction>(V)); return isa<Instruction>(V) && classof(cast<Instruction>(V));
} }
private: private:
void resizeOperands(unsigned NumOperands); void growOperands();
}; };
template <> template <>
@ -2154,7 +2152,7 @@ class SwitchInst : public TerminatorInst {
// Operand[2n+1] = BasicBlock to go to on match // Operand[2n+1] = BasicBlock to go to on match
SwitchInst(const SwitchInst &SI); SwitchInst(const SwitchInst &SI);
void init(Value *Value, BasicBlock *Default, unsigned NumReserved); void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
void resizeOperands(unsigned No); void growOperands();
// allocate space for exactly zero operands // allocate space for exactly zero operands
void *operator new(size_t s) { void *operator new(size_t s) {
return User::operator new(s, 0); return User::operator new(s, 0);
@ -2306,7 +2304,7 @@ class IndirectBrInst : public TerminatorInst {
// Operand[2n+1] = BasicBlock to go to on match // Operand[2n+1] = BasicBlock to go to on match
IndirectBrInst(const IndirectBrInst &IBI); IndirectBrInst(const IndirectBrInst &IBI);
void init(Value *Address, unsigned NumDests); void init(Value *Address, unsigned NumDests);
void resizeOperands(unsigned No); void growOperands();
// allocate space for exactly zero operands // allocate space for exactly zero operands
void *operator new(size_t s) { void *operator new(size_t s) {
return User::operator new(s, 0); return User::operator new(s, 0);

View File

@ -30,7 +30,7 @@ class IntrinsicProperty;
def IntrNoMem : IntrinsicProperty; def IntrNoMem : IntrinsicProperty;
// IntrReadArgMem - This intrinsic reads only from memory that one of its // IntrReadArgMem - This intrinsic reads only from memory that one of its
// arguments points to, but may read an unspecified amount. // pointer-typed arguments points to, but may read an unspecified amount.
def IntrReadArgMem : IntrinsicProperty; def IntrReadArgMem : IntrinsicProperty;
// IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be // IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be
@ -307,7 +307,7 @@ let Properties = [IntrNoMem] in {
def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>;
} }
def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_ptr_ty]>; def int_eh_sjlj_dispatch_setup : Intrinsic<[], []>;
def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>;
@ -490,3 +490,4 @@ include "llvm/IntrinsicsARM.td"
include "llvm/IntrinsicsCellSPU.td" include "llvm/IntrinsicsCellSPU.td"
include "llvm/IntrinsicsAlpha.td" include "llvm/IntrinsicsAlpha.td"
include "llvm/IntrinsicsXCore.td" include "llvm/IntrinsicsXCore.td"
include "llvm/IntrinsicsPTX.td"

View File

@ -1,10 +1,10 @@
//===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===// //===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines all of the ARM-specific intrinsics. // This file defines all of the ARM-specific intrinsics.
@ -129,8 +129,12 @@ let Properties = [IntrNoMem, Commutative] in {
def int_arm_neon_vmulp : Neon_2Arg_Intrinsic; def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic; def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic; def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
// Vector Multiply and Accumulate/Subtract.
def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic; def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic; def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;

View File

@ -0,0 +1,92 @@
//===- IntrinsicsPTX.td - Defines PTX intrinsics -----------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines all of the PTX-specific intrinsics.
//
//===----------------------------------------------------------------------===//
let TargetPrefix = "ptx" in {
multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> {
// FIXME: Do we need the 128-bit integer type version?
// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>;
// FIXME: Enable this once v4i32 support is enabled in back-end.
// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>;
def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
GCCBuiltin<!strconcat(prefix, "_x")>;
def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
GCCBuiltin<!strconcat(prefix, "_y")>;
def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
GCCBuiltin<!strconcat(prefix, "_z")>;
def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
GCCBuiltin<!strconcat(prefix, "_w")>;
}
class PTXReadSpecialRegisterIntrinsic_r32<string name>
: Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
GCCBuiltin<name>;
class PTXReadSpecialRegisterIntrinsic_r64<string name>
: Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>,
GCCBuiltin<name>;
}
defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32
<"__builtin_ptx_read_tid">;
defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32
<"__builtin_ptx_read_ntid">;
def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_laneid">;
def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_warpid">;
def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_nwarpid">;
defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32
<"__builtin_ptx_read_ctaid">;
defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32
<"__builtin_ptx_read_nctaid">;
def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_smid">;
def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_nsmid">;
def int_ptx_read_gridid : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_gridid">;
def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_lanemask_eq">;
def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_lanemask_le">;
def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_lanemask_lt">;
def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_lanemask_ge">;
def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_lanemask_gt">;
def int_ptx_read_clock : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_clock">;
def int_ptx_read_clock64 : PTXReadSpecialRegisterIntrinsic_r64
<"__builtin_ptx_read_clock64">;
def int_ptx_read_pm0 : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_pm0">;
def int_ptx_read_pm1 : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_pm1">;
def int_ptx_read_pm2 : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_pm2">;
def int_ptx_read_pm3 : PTXReadSpecialRegisterIntrinsic_r32
<"__builtin_ptx_read_pm3">;
let TargetPrefix = "ptx" in
def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>,
GCCBuiltin<"__builtin_ptx_bar_sync">;

View File

@ -17,6 +17,83 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_int : Intrinsic<[], [llvm_i8_ty]>; def int_x86_int : Intrinsic<[], [llvm_i8_ty]>;
} }
//===----------------------------------------------------------------------===//
// 3DNow!
let TargetPrefix = "x86" in {
def int_x86_3dnow_pavgusb : GCCBuiltin<"__builtin_ia32_pavgusb">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pf2id : GCCBuiltin<"__builtin_ia32_pf2id">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnow_pfacc : GCCBuiltin<"__builtin_ia32_pfacc">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfadd : GCCBuiltin<"__builtin_ia32_pfadd">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfcmpeq : GCCBuiltin<"__builtin_ia32_pfcmpeq">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfcmpge : GCCBuiltin<"__builtin_ia32_pfcmpge">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfcmpgt : GCCBuiltin<"__builtin_ia32_pfcmpgt">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfmax : GCCBuiltin<"__builtin_ia32_pfmax">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfmin : GCCBuiltin<"__builtin_ia32_pfmin">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfmul : GCCBuiltin<"__builtin_ia32_pfmul">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfrcp : GCCBuiltin<"__builtin_ia32_pfrcp">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnow_pfrcpit1 : GCCBuiltin<"__builtin_ia32_pfrcpit1">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfrcpit2 : GCCBuiltin<"__builtin_ia32_pfrcpit2">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfrsqrt : GCCBuiltin<"__builtin_ia32_pfrsqrt">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnow_pfrsqit1 : GCCBuiltin<"__builtin_ia32_pfrsqit1">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfsub : GCCBuiltin<"__builtin_ia32_pfsub">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pfsubr : GCCBuiltin<"__builtin_ia32_pfsubr">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnow_pi2fd : GCCBuiltin<"__builtin_ia32_pi2fd">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnow_pmulhrw : GCCBuiltin<"__builtin_ia32_pmulhrw">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
// 3DNow! extensions
let TargetPrefix = "x86" in {
def int_x86_3dnowa_pf2iw : GCCBuiltin<"__builtin_ia32_pf2iw">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnowa_pfnacc : GCCBuiltin<"__builtin_ia32_pfnacc">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnowa_pfpnacc : GCCBuiltin<"__builtin_ia32_pfpnacc">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
[IntrNoMem]>;
def int_x86_3dnowa_pi2fw : GCCBuiltin<"__builtin_ia32_pi2fw">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
def int_x86_3dnowa_pswapd :
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SSE1 // SSE1
@ -138,12 +215,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_x86mmx_ty], [IntrNoMem]>; llvm_x86mmx_ty], [IntrNoMem]>;
} }
// SIMD load ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse_loadu_ps : GCCBuiltin<"__builtin_ia32_loadups">,
Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
// SIMD store ops // SIMD store ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">, def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">,
@ -452,14 +523,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v2f64_ty], [llvm_x86mmx_ty], [IntrNoMem]>; Intrinsic<[llvm_v2f64_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
} }
// SIMD load ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse2_loadu_pd : GCCBuiltin<"__builtin_ia32_loadupd">,
Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty], [IntrReadMem]>;
def int_x86_sse2_loadu_dq : GCCBuiltin<"__builtin_ia32_loaddqu">,
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
// SIMD store ops // SIMD store ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">, def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">,
@ -921,68 +984,68 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// String/text processing ops. // String/text processing ops.
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">, def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">,
Intrinsic<[llvm_v16i8_ty], Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">, def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">, def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">, def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">, def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">, def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">, def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">, def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">,
Intrinsic<[llvm_v16i8_ty], Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">, def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">, def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">, def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">, def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">, def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">, def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">,
Intrinsic<[llvm_i32_ty], Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty], llvm_i8_ty],
[IntrNoMem]>; [IntrNoMem]>;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -1571,14 +1634,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[], [llvm_ptrx86mmx_ty, llvm_x86mmx_ty], []>; Intrinsic<[], [llvm_ptrx86mmx_ty, llvm_x86mmx_ty], []>;
def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">, def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>; llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">, def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">,
Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty], Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty],
[IntrNoMem]>; [IntrNoMem]>;
def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">, def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
} }

View File

@ -9,8 +9,13 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
// Miscellaneous instructions.
def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>; def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>;
def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>; def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>;
def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>;
def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>;
def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>;
def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>;
// Resource instructions. // Resource instructions.
def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>; def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>;
@ -48,8 +53,37 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty], def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>; [NoCapture<0>]>;
def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>; def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
[NoCapture<0>, NoCapture<1>]>;
def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
[NoCapture<0>, NoCapture<1>]>;
def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
[NoCapture<0>]>;
// Intrinsics for events. // Intrinsics for events.
def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>;
// If any of the resources owned by the thread are ready this returns the
// vector of one of the ready resources. If no resources owned by the thread
// are ready then the operand passed to the intrinsic is returned.
def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>;
def int_xcore_clre : Intrinsic<[],[],[]>; def int_xcore_clre : Intrinsic<[],[],[]>;
// Intrinsics for threads.
def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
[NoCapture<0>]>;
def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
def int_xcore_ssync : Intrinsic <[],[]>;
def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>;
def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>;
def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>;
def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>;
def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
[NoCapture<0>]>;
} }

View File

@ -49,7 +49,6 @@ namespace {
(void) llvm::createAliasAnalysisCounterPass(); (void) llvm::createAliasAnalysisCounterPass();
(void) llvm::createAliasDebugger(); (void) llvm::createAliasDebugger();
(void) llvm::createArgumentPromotionPass(); (void) llvm::createArgumentPromotionPass();
(void) llvm::createStructRetPromotionPass();
(void) llvm::createBasicAliasAnalysisPass(); (void) llvm::createBasicAliasAnalysisPass();
(void) llvm::createLibCallAliasAnalysisPass(0); (void) llvm::createLibCallAliasAnalysisPass(0);
(void) llvm::createScalarEvolutionAliasAnalysisPass(); (void) llvm::createScalarEvolutionAliasAnalysisPass();
@ -71,6 +70,7 @@ namespace {
(void) llvm::createEdgeProfilerPass(); (void) llvm::createEdgeProfilerPass();
(void) llvm::createOptimalEdgeProfilerPass(); (void) llvm::createOptimalEdgeProfilerPass();
(void) llvm::createPathProfilerPass(); (void) llvm::createPathProfilerPass();
(void) llvm::createGCOVProfilerPass(true, true);
(void) llvm::createFunctionInliningPass(); (void) llvm::createFunctionInliningPass();
(void) llvm::createAlwaysInlinerPass(); (void) llvm::createAlwaysInlinerPass();
(void) llvm::createGlobalDCEPass(); (void) llvm::createGlobalDCEPass();
@ -84,7 +84,6 @@ namespace {
(void) llvm::createLCSSAPass(); (void) llvm::createLCSSAPass();
(void) llvm::createLICMPass(); (void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass(); (void) llvm::createLazyValueInfoPass();
(void) llvm::createLiveValuesPass();
(void) llvm::createLoopDependenceAnalysisPass(); (void) llvm::createLoopDependenceAnalysisPass();
(void) llvm::createLoopExtractorPass(); (void) llvm::createLoopExtractorPass();
(void) llvm::createLoopSimplifyPass(); (void) llvm::createLoopSimplifyPass();
@ -119,7 +118,6 @@ namespace {
(void) llvm::createSCCPPass(); (void) llvm::createSCCPPass();
(void) llvm::createScalarReplAggregatesPass(); (void) llvm::createScalarReplAggregatesPass();
(void) llvm::createSimplifyLibCallsPass(); (void) llvm::createSimplifyLibCallsPass();
(void) llvm::createSimplifyHalfPowrLibCallsPass();
(void) llvm::createSingleLoopExtractorPass(); (void) llvm::createSingleLoopExtractorPass();
(void) llvm::createStripSymbolsPass(); (void) llvm::createStripSymbolsPass();
(void) llvm::createStripNonDebugSymbolsPass(); (void) llvm::createStripNonDebugSymbolsPass();
@ -136,7 +134,6 @@ namespace {
(void) llvm::createMemCpyOptPass(); (void) llvm::createMemCpyOptPass();
(void) llvm::createLoopDeletionPass(); (void) llvm::createLoopDeletionPass();
(void) llvm::createPostDomTree(); (void) llvm::createPostDomTree();
(void) llvm::createPostDomFrontier();
(void) llvm::createInstructionNamerPass(); (void) llvm::createInstructionNamerPass();
(void) llvm::createFunctionAttrsPass(); (void) llvm::createFunctionAttrsPass();
(void) llvm::createMergeFunctionsPass(); (void) llvm::createMergeFunctionsPass();
@ -145,7 +142,6 @@ namespace {
(void) llvm::createDbgInfoPrinterPass(); (void) llvm::createDbgInfoPrinterPass();
(void) llvm::createModuleDebugInfoPrinterPass(); (void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass(); (void) llvm::createPartialInliningPass();
(void) llvm::createGEPSplitterPass();
(void) llvm::createLintPass(); (void) llvm::createLintPass();
(void) llvm::createSinkingPass(); (void) llvm::createSinkingPass();
(void) llvm::createLowerAtomicPass(); (void) llvm::createLowerAtomicPass();

View File

@ -20,13 +20,16 @@
#include <cassert> #include <cassert>
namespace llvm { namespace llvm {
class MCExpr;
class MCSection; class MCSection;
class MCStreamer;
class MCSymbol;
class MCContext; class MCContext;
/// MCAsmInfo - This class is intended to be used as a base class for asm /// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target. /// properties and features specific to the target.
namespace ExceptionHandling { namespace ExceptionHandling {
enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj }; enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj, ARM };
} }
class MCAsmInfo { class MCAsmInfo {
@ -66,10 +69,9 @@ namespace llvm {
/// relative expressions. /// relative expressions.
const char *PCSymbol; // Defaults to "$". const char *PCSymbol; // Defaults to "$".
/// SeparatorChar - This character, if specified, is used to separate /// SeparatorString - This string, if specified, is used to separate
/// instructions from each other when on the same line. This is used to /// instructions from each other when on the same line.
/// measure inline asm instructions. const char *SeparatorString; // Defaults to ';'
char SeparatorChar; // Defaults to ';'
/// CommentColumn - This indicates the comment num (zero-based) at /// CommentColumn - This indicates the comment num (zero-based) at
/// which asm comments should be printed. /// which asm comments should be printed.
@ -322,6 +324,16 @@ namespace llvm {
return 0; return 0;
} }
virtual const MCExpr *
getExprForPersonalitySymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const;
const MCExpr *
getExprForFDESymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const;
bool usesSunStyleELFSectionSwitchSyntax() const { bool usesSunStyleELFSectionSwitchSyntax() const {
return SunStyleELFSectionSwitchSyntax; return SunStyleELFSectionSwitchSyntax;
} }
@ -350,8 +362,8 @@ namespace llvm {
const char *getPCSymbol() const { const char *getPCSymbol() const {
return PCSymbol; return PCSymbol;
} }
char getSeparatorChar() const { const char *getSeparatorString() const {
return SeparatorChar; return SeparatorString;
} }
unsigned getCommentColumn() const { unsigned getCommentColumn() const {
return CommentColumn; return CommentColumn;
@ -451,7 +463,8 @@ namespace llvm {
bool isExceptionHandlingDwarf() const { bool isExceptionHandlingDwarf() const {
return return
(ExceptionsType == ExceptionHandling::DwarfTable || (ExceptionsType == ExceptionHandling::DwarfTable ||
ExceptionsType == ExceptionHandling::DwarfCFI); ExceptionsType == ExceptionHandling::DwarfCFI ||
ExceptionsType == ExceptionHandling::ARM);
} }
bool doesDwarfRequireFrameSection() const { bool doesDwarfRequireFrameSection() const {

View File

@ -36,8 +36,8 @@ class MCAsmLayout {
/// List of sections in layout order. /// List of sections in layout order.
llvm::SmallVector<MCSectionData*, 16> SectionOrder; llvm::SmallVector<MCSectionData*, 16> SectionOrder;
/// The last fragment which was layed out, or 0 if nothing has been layed /// The last fragment which was laid out, or 0 if nothing has been laid
/// out. Fragments are always layed out in order, so all fragments with a /// out. Fragments are always laid out in order, so all fragments with a
/// lower ordinal will be up to date. /// lower ordinal will be up to date.
mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment;
@ -58,7 +58,7 @@ class MCAsmLayout {
void Invalidate(MCFragment *F); void Invalidate(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous /// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been layed out correctly, and the parent section has /// fragment has already been laid out correctly, and the parent section has
/// been initialized. /// been initialized.
void LayoutFragment(MCFragment *Fragment); void LayoutFragment(MCFragment *Fragment);

View File

@ -706,7 +706,7 @@ class MCAssembler {
/// \param DF The fragment the fixup is inside. /// \param DF The fragment the fixup is inside.
/// \param Target [out] On return, the relocatable expression the fixup /// \param Target [out] On return, the relocatable expression the fixup
/// evaluates to. /// evaluates to.
/// \param Value [out] On return, the value of the fixup as currently layed /// \param Value [out] On return, the value of the fixup as currently laid
/// out. /// out.
/// \return Whether the fixup value was fully resolved. This is true if the /// \return Whether the fixup value was fully resolved. This is true if the
/// \arg Value result is fixed, otherwise the value may change due to /// \arg Value result is fixed, otherwise the value may change due to
@ -745,7 +745,7 @@ class MCAssembler {
MCFragment &F, const MCFixup &Fixup); MCFragment &F, const MCFixup &Fixup);
public: public:
/// Compute the effective fragment size assuming it is layed out at the given /// Compute the effective fragment size assuming it is laid out at the given
/// \arg SectionAddress and \arg FragmentOffset. /// \arg SectionAddress and \arg FragmentOffset.
uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const;

View File

@ -45,12 +45,18 @@ namespace llvm {
const TargetAsmInfo *TAI; const TargetAsmInfo *TAI;
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
/// Symbols - Bindings of names to symbols. /// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*> Symbols; StringMap<MCSymbol*, BumpPtrAllocator&> Symbols;
/// UsedNames - Keeps tracks of names that were used both for used declared /// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols. /// and artificial symbols.
StringMap<bool> UsedNames; StringMap<bool, BumpPtrAllocator&> UsedNames;
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
/// symbol. /// symbol.
@ -84,6 +90,11 @@ namespace llvm {
MCDwarfLoc CurrentDwarfLoc; MCDwarfLoc CurrentDwarfLoc;
bool DwarfLocSeen; bool DwarfLocSeen;
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
bool AllowTemporaryLabels;
/// The dwarf line information from the .loc directives for the sections /// The dwarf line information from the .loc directives for the sections
/// with assembled machine instructions have after seeing .loc directives. /// with assembled machine instructions have after seeing .loc directives.
DenseMap<const MCSection *, MCLineSection *> MCLineSections; DenseMap<const MCSection *, MCLineSection *> MCLineSections;
@ -91,12 +102,6 @@ namespace llvm {
/// the elements were added. /// the elements were added.
std::vector<const MCSection *> MCLineSectionOrder; std::vector<const MCSection *> MCLineSectionOrder;
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
MCSymbol *CreateSymbol(StringRef Name); MCSymbol *CreateSymbol(StringRef Name);
@ -109,6 +114,8 @@ namespace llvm {
const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; }
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
/// @name Symbol Management /// @name Symbol Management
/// @{ /// @{

View File

@ -10,12 +10,14 @@
#define MCDISASSEMBLER_H #define MCDISASSEMBLER_H
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm-c/Disassembler.h"
namespace llvm { namespace llvm {
class MCInst; class MCInst;
class MemoryObject; class MemoryObject;
class raw_ostream; class raw_ostream;
class MCContext;
struct EDInstInfo; struct EDInstInfo;
@ -24,7 +26,7 @@ struct EDInstInfo;
class MCDisassembler { class MCDisassembler {
public: public:
/// Constructor - Performs initial setup for the disassembler. /// Constructor - Performs initial setup for the disassembler.
MCDisassembler() {} MCDisassembler() : GetOpInfo(0), DisInfo(0), Ctx(0) {}
virtual ~MCDisassembler(); virtual ~MCDisassembler();
@ -46,13 +48,37 @@ class MCDisassembler {
uint64_t address, uint64_t address,
raw_ostream &vStream) const = 0; raw_ostream &vStream) const = 0;
/// getEDInfo - Returns the enhanced insturction information corresponding to /// getEDInfo - Returns the enhanced instruction information corresponding to
/// the disassembler. /// the disassembler.
/// ///
/// @return - An array of instruction information, with one entry for /// @return - An array of instruction information, with one entry for
/// each MCInst opcode this disassembler returns. /// each MCInst opcode this disassembler returns.
/// NULL if there is no info for this target. /// NULL if there is no info for this target.
virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
private:
//
// Hooks for symbolic disassembly via the public 'C' interface.
//
// The function to get the symbolic information for operands.
LLVMOpInfoCallback GetOpInfo;
// The pointer to the block of symbolic information for above call back.
void *DisInfo;
// The assembly context for creating symbols and MCExprs in place of
// immediate operands when there is symbolic information.
MCContext *Ctx;
public:
void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
void *disInfo,
MCContext *ctx) {
GetOpInfo = getOpInfo;
DisInfo = disInfo;
Ctx = ctx;
}
LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
void *getDisInfoBlock() const { return DisInfo; }
MCContext *getMCContext() const { return Ctx; }
}; };
} // namespace llvm } // namespace llvm

View File

@ -23,6 +23,7 @@
#include <vector> #include <vector>
namespace llvm { namespace llvm {
class TargetAsmInfo;
class MachineMove; class MachineMove;
class MCContext; class MCContext;
class MCExpr; class MCExpr;
@ -230,7 +231,7 @@ namespace llvm {
class MCCFIInstruction { class MCCFIInstruction {
public: public:
enum OpType { Remember, Restore, Move }; enum OpType { SameValue, Remember, Restore, Move, RelMove };
private: private:
OpType Operation; OpType Operation;
MCSymbol *Label; MCSymbol *Label;
@ -242,10 +243,19 @@ namespace llvm {
: Operation(Op), Label(L) { : Operation(Op), Label(L) {
assert(Op == Remember || Op == Restore); assert(Op == Remember || Op == Restore);
} }
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
: Operation(Op), Label(L), Destination(Register) {
assert(Op == SameValue);
}
MCCFIInstruction(MCSymbol *L, const MachineLocation &D, MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
const MachineLocation &S) const MachineLocation &S)
: Operation(Move), Label(L), Destination(D), Source(S) { : Operation(Move), Label(L), Destination(D), Source(S) {
} }
MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
const MachineLocation &S)
: Operation(Op), Label(L), Destination(D), Source(S) {
assert(Op == RelMove);
}
OpType getOperation() const { return Operation; } OpType getOperation() const { return Operation; }
MCSymbol *getLabel() const { return Label; } MCSymbol *getLabel() const { return Label; }
const MachineLocation &getDestination() const { return Destination; } const MachineLocation &getDestination() const { return Destination; }
@ -254,12 +264,13 @@ namespace llvm {
struct MCDwarfFrameInfo { struct MCDwarfFrameInfo {
MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
Instructions(), PersonalityEncoding(0), Function(0), Instructions(), PersonalityEncoding(),
LsdaEncoding(0) {} LsdaEncoding(0) {}
MCSymbol *Begin; MCSymbol *Begin;
MCSymbol *End; MCSymbol *End;
const MCSymbol *Personality; const MCSymbol *Personality;
const MCSymbol *Lsda; const MCSymbol *Lsda;
const MCSymbol *Function;
std::vector<MCCFIInstruction> Instructions; std::vector<MCCFIInstruction> Instructions;
unsigned PersonalityEncoding; unsigned PersonalityEncoding;
unsigned LsdaEncoding; unsigned LsdaEncoding;
@ -270,9 +281,11 @@ namespace llvm {
// //
// This emits the frame info section. // This emits the frame info section.
// //
static void Emit(MCStreamer &streamer); static void Emit(MCStreamer &streamer, bool usingCFI);
static void EmitDarwin(MCStreamer &streamer, bool usingCFI);
static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS,
const TargetAsmInfo &AsmInfo);
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -19,6 +19,7 @@ class MCAsmInfo;
class MCAsmLayout; class MCAsmLayout;
class MCAssembler; class MCAssembler;
class MCContext; class MCContext;
class MCSection;
class MCSectionData; class MCSectionData;
class MCSymbol; class MCSymbol;
class MCValue; class MCValue;
@ -92,6 +93,12 @@ class MCExpr {
/// @result - True on success. /// @result - True on success.
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const; bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const;
/// FindAssociatedSection - Find the "associated section" for this expression,
/// which is currently defined as the absolute section for constants, or
/// otherwise the section associated with the first defined symbol in the
/// expression.
const MCSection *FindAssociatedSection() const;
/// @} /// @}
static bool classof(const MCExpr *) { return true; } static bool classof(const MCExpr *) { return true; }
@ -420,6 +427,7 @@ class MCTargetExpr : public MCExpr {
virtual bool EvaluateAsRelocatableImpl(MCValue &Res, virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const = 0; const MCAsmLayout *Layout) const = 0;
virtual void AddValueSymbols(MCAssembler *) const = 0; virtual void AddValueSymbols(MCAssembler *) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0;
static bool classof(const MCExpr *E) { static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target; return E->getKind() == MCExpr::Target;

View File

@ -25,9 +25,12 @@ class MCInstPrinter {
/// assembly emission is disable. /// assembly emission is disable.
raw_ostream *CommentStream; raw_ostream *CommentStream;
const MCAsmInfo &MAI; const MCAsmInfo &MAI;
/// The current set of available features.
unsigned AvailableFeatures;
public: public:
MCInstPrinter(const MCAsmInfo &mai) MCInstPrinter(const MCAsmInfo &mai)
: CommentStream(0), MAI(mai) {} : CommentStream(0), MAI(mai), AvailableFeatures(0) {}
virtual ~MCInstPrinter(); virtual ~MCInstPrinter();
@ -41,6 +44,12 @@ class MCInstPrinter {
/// getOpcodeName - Return the name of the specified opcode enum (e.g. /// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it. /// "MOV32ri") or empty if we can't resolve it.
virtual StringRef getOpcodeName(unsigned Opcode) const; virtual StringRef getOpcodeName(unsigned Opcode) const;
/// getRegName - Return the assembler register name.
virtual StringRef getRegName(unsigned RegNo) const;
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
}; };
} // namespace llvm } // namespace llvm

View File

@ -38,6 +38,9 @@ class MCObjectStreamer : public MCStreamer {
protected: protected:
MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter); raw_ostream &_OS, MCCodeEmitter *_Emitter);
MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter,
MCAssembler *_Assembler);
~MCObjectStreamer(); ~MCObjectStreamer();
MCSectionData *getCurrentSectionData() const { MCSectionData *getCurrentSectionData() const {
@ -60,9 +63,9 @@ class MCObjectStreamer : public MCStreamer {
virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
bool isPCRel, unsigned AddrSpace); unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); virtual void EmitULEB128Value(const MCExpr *Value);
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); virtual void EmitSLEB128Value(const MCExpr *Value);
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void ChangeSection(const MCSection *Section); virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst); virtual void EmitInstruction(const MCInst &Inst);

Some files were not shown because too many files have changed in this diff Show More