Upgrade our copy of llvm/clang to trunk r178860, in preparation of the
upcoming 3.3 release (branching and freezing expected in a few weeks). Preliminary release notes can be found at the usual location: <http://llvm.org/docs/ReleaseNotes.html> An MFC is planned once the actual 3.3 release is finished.
This commit is contained in:
commit
139f7f9bf5
@ -380,7 +380,7 @@ IMAKE_MTREE= MTREE_CMD="nmtree ${MTREEFLAGS}"
|
||||
|
||||
# kernel stage
|
||||
KMAKEENV= ${WMAKEENV}
|
||||
KMAKE= ${KMAKEENV} ${MAKE} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
|
||||
KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
|
||||
|
||||
#
|
||||
# buildworld
|
||||
|
@ -38,6 +38,37 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20130411: new clang import which bumps version from 3.2 to 3.3.
|
||||
OLD_FILES+=usr/include/clang/3.2/__wmmintrin_aes.h
|
||||
OLD_FILES+=usr/include/clang/3.2/__wmmintrin_pclmul.h
|
||||
OLD_FILES+=usr/include/clang/3.2/altivec.h
|
||||
OLD_FILES+=usr/include/clang/3.2/ammintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/avx2intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/avxintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/bmi2intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/bmiintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/cpuid.h
|
||||
OLD_FILES+=usr/include/clang/3.2/emmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/f16cintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/fma4intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/fmaintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/immintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/lzcntintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/mm3dnow.h
|
||||
OLD_FILES+=usr/include/clang/3.2/mm_malloc.h
|
||||
OLD_FILES+=usr/include/clang/3.2/mmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/module.map
|
||||
OLD_FILES+=usr/include/clang/3.2/nmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/pmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/popcntintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/rtmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/smmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/tmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/wmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/x86intrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/xmmintrin.h
|
||||
OLD_FILES+=usr/include/clang/3.2/xopintrin.h
|
||||
OLD_DIRS+=usr/include/clang/3.2
|
||||
# 20130404: legacy ATA stack removed
|
||||
OLD_FILES+=sbin/atacontrol
|
||||
OLD_FILES+=usr/share/man/man8/atacontrol.8.gz
|
||||
|
@ -4,7 +4,7 @@ LLVM Release License
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
@ -64,7 +64,7 @@ Program Directory
|
||||
Autoconf llvm/autoconf
|
||||
llvm/projects/ModuleMaker/autoconf
|
||||
llvm/projects/sample/autoconf
|
||||
CellSPU backend llvm/lib/Target/CellSPU/README.txt
|
||||
Google Test llvm/utils/unittest/googletest
|
||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
||||
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
|
||||
and 'unwrap' conversion functions. */
|
||||
#include "llvm/IRBuilder.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/PassRegistry.h"
|
||||
|
||||
extern "C" {
|
||||
@ -173,10 +173,11 @@ typedef enum {
|
||||
LLVMUWTable = 1 << 30,
|
||||
LLVMNonLazyBind = 1 << 31
|
||||
|
||||
/* FIXME: This attribute is currently not included in the C API as
|
||||
/* FIXME: These attributes are currently not included in the C API as
|
||||
a temporary measure until the API/ABI impact to the C API is understood
|
||||
and the path forward agreed upon.
|
||||
LLVMAddressSafety = 1ULL << 32
|
||||
LLVMAddressSafety = 1ULL << 32,
|
||||
LLVMStackProtectStrongAttribute = 1ULL<<33
|
||||
*/
|
||||
} LLVMAttribute;
|
||||
|
||||
@ -357,6 +358,11 @@ typedef enum {
|
||||
|
||||
void LLVMInitializeCore(LLVMPassRegistryRef R);
|
||||
|
||||
/** Deallocate and destroy all ManagedStatic variables.
|
||||
@see llvm::llvm_shutdown
|
||||
@see ManagedStatic */
|
||||
void LLVMShutdown();
|
||||
|
||||
|
||||
/*===-- Error handling ----------------------------------------------------===*/
|
||||
|
||||
@ -2547,6 +2553,13 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
||||
char **OutMessage);
|
||||
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData,
|
||||
size_t InputDataLength,
|
||||
const char *BufferName,
|
||||
LLVMBool RequiresNullTerminator);
|
||||
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData,
|
||||
size_t InputDataLength,
|
||||
const char *BufferName);
|
||||
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
|
||||
|
||||
/**
|
||||
@ -2614,6 +2627,34 @@ LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
|
||||
@see llvm::PassManagerBase::~PassManagerBase. */
|
||||
void LLVMDisposePassManager(LLVMPassManagerRef PM);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup LLVMCCoreThreading Threading
|
||||
*
|
||||
* Handle the structures needed to make LLVM safe for multithreading.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Allocate and initialize structures needed to make LLVM safe for
|
||||
multithreading. The return value indicates whether multithreaded
|
||||
initialization succeeded. Must be executed in isolation from all
|
||||
other LLVM api calls.
|
||||
@see llvm::llvm_start_multithreaded */
|
||||
LLVMBool LLVMStartMultithreaded();
|
||||
|
||||
/** Deallocate structures necessary to make LLVM safe for multithreading.
|
||||
Must be executed in isolation from all other LLVM api calls.
|
||||
@see llvm::llvm_stop_multithreaded */
|
||||
void LLVMStopMultithreaded();
|
||||
|
||||
/** Check whether LLVM is executing in thread-safe mode or not.
|
||||
@see llvm::llvm_is_multithreaded */
|
||||
LLVMBool LLVMIsMultithreaded();
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -139,12 +139,25 @@ extern "C" {
|
||||
* by passing a block of information in the DisInfo parameter and specifying the
|
||||
* TagType and callback functions as described above. These can all be passed
|
||||
* as NULL. If successful, this returns a disassembler context. If not, it
|
||||
* returns NULL.
|
||||
* returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU()
|
||||
* with an empty CPU name.
|
||||
*/
|
||||
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
|
||||
int TagType, LLVMOpInfoCallback GetOpInfo,
|
||||
LLVMSymbolLookupCallback SymbolLookUp);
|
||||
|
||||
/**
|
||||
* Create a disassembler for the TripleName and a specific CPU. Symbolic
|
||||
* disassembly is supported by passing a block of information in the DisInfo
|
||||
* parameter and specifying the TagType and callback functions as described
|
||||
* above. These can all be passed * as NULL. If successful, this returns a
|
||||
* disassembler context. If not, it returns NULL.
|
||||
*/
|
||||
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
|
||||
void *DisInfo, int TagType,
|
||||
LLVMOpInfoCallback GetOpInfo,
|
||||
LLVMSymbolLookupCallback SymbolLookUp);
|
||||
|
||||
/**
|
||||
* Set the disassembler's options. Returns 1 if it can set the Options and 0
|
||||
* otherwise.
|
||||
@ -153,6 +166,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
|
||||
|
||||
/* The option to produce marked up assembly. */
|
||||
#define LLVMDisassembler_Option_UseMarkup 1
|
||||
/* The option to print immediates as hex. */
|
||||
#define LLVMDisassembler_Option_PrintImmHex 2
|
||||
/* The option use the other assembler printer variant */
|
||||
#define LLVMDisassembler_Option_AsmPrinterVariant 4
|
||||
|
||||
/**
|
||||
* Dispose of a disassembler context.
|
||||
|
@ -1,530 +0,0 @@
|
||||
/*===-- llvm-c/EnhancedDisassembly.h - Disassembler C Interface ---*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to EnhancedDisassembly.so, which *|
|
||||
|* implements a disassembler with the ability to extract operand values and *|
|
||||
|* individual tokens from assembly instructions. *|
|
||||
|* *|
|
||||
|* The header declares additional interfaces if the host compiler supports *|
|
||||
|* the blocks API. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
#define LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup LLVMCEnhancedDisassembly Enhanced Disassembly
|
||||
* @ingroup LLVMC
|
||||
* @deprecated
|
||||
*
|
||||
* This module contains an interface to the Enhanced Disassembly (edis)
|
||||
* library. The edis library is deprecated and will likely disappear in
|
||||
* the near future. You should use the @ref LLVMCDisassembler interface
|
||||
* instead.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
@typedef EDByteReaderCallback
|
||||
Interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterReaderCallback
|
||||
Interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
void* arg);
|
||||
|
||||
/*!
|
||||
@typedef EDAssemblySyntax_t
|
||||
An assembly syntax for use in tokenizing instructions.
|
||||
*/
|
||||
enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1,
|
||||
kEDAssemblySyntaxARMUAL = 2
|
||||
};
|
||||
typedef unsigned EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
@typedef EDDisassemblerRef
|
||||
Encapsulates a disassembler for a single CPU architecture.
|
||||
*/
|
||||
typedef void *EDDisassemblerRef;
|
||||
|
||||
/*!
|
||||
@typedef EDInstRef
|
||||
Encapsulates a single disassembled instruction in one assembly syntax.
|
||||
*/
|
||||
typedef void *EDInstRef;
|
||||
|
||||
/*!
|
||||
@typedef EDTokenRef
|
||||
Encapsulates a token from the disassembly of an instruction.
|
||||
*/
|
||||
typedef void *EDTokenRef;
|
||||
|
||||
/*!
|
||||
@typedef EDOperandRef
|
||||
Encapsulates an operand of an instruction.
|
||||
*/
|
||||
typedef void *EDOperandRef;
|
||||
|
||||
/*!
|
||||
@functiongroup Getting a disassembler
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetDisassembler
|
||||
Gets the disassembler for a given target.
|
||||
@param disassembler A pointer whose target will be filled in with the
|
||||
disassembler.
|
||||
@param triple Identifies the target. Example: "x86_64-apple-darwin10"
|
||||
@param syntax The assembly syntax to use when decoding instructions.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetDisassembler(EDDisassemblerRef *disassembler,
|
||||
const char *triple,
|
||||
EDAssemblySyntax_t syntax);
|
||||
|
||||
/*!
|
||||
@functiongroup Generic architectural queries
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetRegisterName
|
||||
Gets the human-readable name for a given register.
|
||||
@param regName A pointer whose target will be pointed at the name of the
|
||||
register. The name does not need to be deallocated and will be
|
||||
@param disassembler The disassembler to query for the name.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetRegisterName(const char** regName,
|
||||
EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsStackPointer
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsProgramCounter
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying instructions
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDCreateInst
|
||||
Gets a set of contiguous instructions from a disassembler.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteReader The function to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@param arg An anonymous argument to be passed to byteReader.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDCreateInsts(EDInstRef *insts,
|
||||
unsigned int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg);
|
||||
|
||||
/*!
|
||||
@function EDReleaseInst
|
||||
Frees the memory for an instruction. The instruction can no longer be accessed
|
||||
after this call.
|
||||
@param inst The instruction to be freed.
|
||||
*/
|
||||
void EDReleaseInst(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstByteSize
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of bytes in the instruction's machine-code representation.
|
||||
*/
|
||||
int EDInstByteSize(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetInstString
|
||||
Gets the disassembled text equivalent of the instruction.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the instruction is released.)
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetInstString(const char **buf,
|
||||
EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstID
|
||||
@param instID A pointer whose target will be filled in with the LLVM identifier
|
||||
for the instruction.
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDInstID(unsigned *instID, EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsBranch
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a branch instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsBranch(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsMove
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a move instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsMove(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDBranchTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the branch target operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDBranchTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveSourceID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveSourceID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying tokens
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumTokens
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of tokens in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumTokens(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetToken
|
||||
Retrieves a token from an instruction. The token is valid until the
|
||||
instruction is released.
|
||||
@param token A pointer to be filled in with the token.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the token in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetToken(EDTokenRef *token,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDGetTokenString
|
||||
Gets the disassembled text for a token.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the token is released.)
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetTokenString(const char **buf,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDOperandIndexForToken
|
||||
Returns the index of the operand to which a token belongs.
|
||||
@param token The token to be queried.
|
||||
@result The operand index on success; -1 otherwise
|
||||
*/
|
||||
int EDOperandIndexForToken(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsWhitespace
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is whitespace; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsWhitespace(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsPunctuation
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is punctuation; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsPunctuation(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsOpcode
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is opcode; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsOpcode(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a numeric literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsRegister
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token identifies a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsRegister(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsNegativeLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a negative signed literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsNegativeLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDLiteralTokenAbsoluteValue
|
||||
@param value A pointer whose target will be filled in with the absolute value
|
||||
of the literal.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDLiteralTokenAbsoluteValue(uint64_t *value,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDRegisterTokenValue
|
||||
@param registerID A pointer whose target will be filled in with the LLVM
|
||||
register identifier for the token.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterTokenValue(unsigned *registerID,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying operands
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumOperands
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of operands in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumOperands(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetOperand
|
||||
Retrieves an operand from an instruction. The operand is valid until the
|
||||
instruction is released.
|
||||
@param operand A pointer to be filled in with the operand.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the operand in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetOperand(EDOperandRef *operand,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsRegister
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand names a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsRegister(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsImmediate
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies an immediate value; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsImmediate(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsMemory
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies a location in memory; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsMemory(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDRegisterOperandValue
|
||||
@param value A pointer whose target will be filled in with the LLVM register ID
|
||||
of the register named by the operand.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterOperandValue(unsigned *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDImmediateOperandValue
|
||||
@param value A pointer whose target will be filled in with the value of the
|
||||
immediate.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDImmediateOperandValue(uint64_t *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDEvaluateOperand
|
||||
Evaluates an operand using a client-supplied register state accessor. Register
|
||||
operands are evaluated by reading the value of the register; immediate operands
|
||||
are evaluated by reporting the immediate value; memory operands are evaluated
|
||||
by computing the target address (with only those relocations applied that were
|
||||
already applied to the original bytes).
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regReader The function to use when reading registers from the register
|
||||
state.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterReaderCallback regReader,
|
||||
void *arg);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
|
||||
/*!
|
||||
@typedef EDByteBlock_t
|
||||
Block-based interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterBlock_t
|
||||
Block-based interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
|
||||
|
||||
/*!
|
||||
@typedef EDTokenVisitor_t
|
||||
Block-based handler for individual tokens.
|
||||
@param token The current token being read.
|
||||
@result 0 to continue; 1 to stop normally; -1 on error.
|
||||
*/
|
||||
typedef int (^EDTokenVisitor_t)(EDTokenRef token);
|
||||
|
||||
/*! @functiongroup Block-based interfaces */
|
||||
|
||||
/*!
|
||||
@function EDBlockCreateInsts
|
||||
Gets a set of contiguous instructions from a disassembler, using a block to
|
||||
read memory.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteBlock The block to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDBlockCreateInsts(EDInstRef *insts,
|
||||
int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteBlock_t byteBlock,
|
||||
uint64_t address);
|
||||
|
||||
/*!
|
||||
@function EDBlockEvaluateOperand
|
||||
Evaluates an operand using a block to read registers.
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regBlock The block to use when reading registers from the register
|
||||
state.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDBlockEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterBlock_t regBlock);
|
||||
|
||||
/*!
|
||||
@function EDBlockVisitTokens
|
||||
Visits every token with a visitor.
|
||||
@param inst The instruction with the tokens to be visited.
|
||||
@param visitor The visitor.
|
||||
@result 0 if the visit ended normally; -1 if the visitor encountered an error
|
||||
or there was some other error.
|
||||
*/
|
||||
int EDBlockVisitTokens(EDInstRef inst,
|
||||
EDTokenVisitor_t visitor);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -34,6 +34,7 @@ extern "C" {
|
||||
void LLVMInitializeCore(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeVectorization(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
|
||||
void LLVMInitializeIPO(LLVMPassRegistryRef R);
|
||||
|
@ -13,8 +13,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __LTO_CAPI_H__
|
||||
#define __LTO_CAPI_H__
|
||||
#ifndef LLVM_C_LINKTIMEOPTIMIZER_H
|
||||
#define LLVM_C_LINKTIMEOPTIMIZER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define LLVM_C_TARGETMACHINE_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm-c/Target.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -11,8 +11,8 @@
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_PASSMANAGERBUILDER
|
||||
#define LLVM_C_PASSMANAGERBUILDER
|
||||
#ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
|
||||
#define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
@ -77,8 +77,8 @@ LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
|
||||
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
|
||||
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
|
||||
LLVMPassManagerRef PM,
|
||||
bool Internalize,
|
||||
bool RunInliner);
|
||||
LLVMBool Internalize,
|
||||
LLVMBool RunInliner);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -13,8 +13,8 @@
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LTO_H
|
||||
#define LTO_H 1
|
||||
#ifndef LLVM_C_LTO_H
|
||||
#define LLVM_C_LTO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -291,6 +291,13 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
|
||||
extern void
|
||||
lto_codegen_debug_options(lto_code_gen_t cg, const char *);
|
||||
|
||||
/**
|
||||
* Initializes LLVM disassemblers.
|
||||
* FIXME: This doesn't really belong here.
|
||||
*/
|
||||
extern void
|
||||
lto_initialize_disassembler(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -97,8 +97,8 @@
|
||||
nexttoward.
|
||||
*/
|
||||
|
||||
#ifndef LLVM_FLOAT_H
|
||||
#define LLVM_FLOAT_H
|
||||
#ifndef LLVM_ADT_APFLOAT_H
|
||||
#define LLVM_ADT_APFLOAT_H
|
||||
|
||||
// APInt contains static functions implementing bignum arithmetic.
|
||||
#include "llvm/ADT/APInt.h"
|
||||
@ -184,9 +184,9 @@ namespace llvm {
|
||||
APFloat(const fltSemantics &, integerPart);
|
||||
APFloat(const fltSemantics &, fltCategory, bool negative);
|
||||
APFloat(const fltSemantics &, uninitializedTag);
|
||||
APFloat(const fltSemantics &, const APInt &);
|
||||
explicit APFloat(double d);
|
||||
explicit APFloat(float f);
|
||||
explicit APFloat(const APInt &, bool isIEEE = false);
|
||||
APFloat(const APFloat &);
|
||||
~APFloat();
|
||||
|
||||
@ -300,7 +300,7 @@ namespace llvm {
|
||||
/* The definition of equality is not straightforward for floating point,
|
||||
so we won't use operator==. Use one of the following, or write
|
||||
whatever it is you really mean. */
|
||||
// bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
|
||||
bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION;
|
||||
|
||||
/* IEEE comparison with another floating point number (NaNs
|
||||
compare unordered, 0==-0). */
|
||||
@ -327,6 +327,7 @@ namespace llvm {
|
||||
bool isNegative() const { return sign; }
|
||||
bool isPosZero() const { return isZero() && !isNegative(); }
|
||||
bool isNegZero() const { return isZero() && isNegative(); }
|
||||
bool isDenormal() const;
|
||||
|
||||
APFloat& operator=(const APFloat &);
|
||||
|
||||
@ -422,7 +423,7 @@ namespace llvm {
|
||||
APInt convertQuadrupleAPFloatToAPInt() const;
|
||||
APInt convertF80LongDoubleAPFloatToAPInt() const;
|
||||
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
|
||||
void initFromAPInt(const APInt& api, bool isIEEE = false);
|
||||
void initFromAPInt(const fltSemantics *Sem, const APInt& api);
|
||||
void initFromHalfAPInt(const APInt& api);
|
||||
void initFromFloatAPInt(const APInt& api);
|
||||
void initFromDoubleAPInt(const APInt& api);
|
||||
@ -462,4 +463,4 @@ namespace llvm {
|
||||
hash_code hash_value(const APFloat &Arg);
|
||||
} /* namespace llvm */
|
||||
|
||||
#endif /* LLVM_FLOAT_H */
|
||||
#endif /* LLVM_ADT_APFLOAT_H */
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_APINT_H
|
||||
#define LLVM_APINT_H
|
||||
#ifndef LLVM_ADT_APINT_H
|
||||
#define LLVM_ADT_APINT_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
@ -274,7 +274,7 @@ class APInt {
|
||||
initSlowCase(that);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
/// @brief Move Constructor.
|
||||
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
|
||||
that.BitWidth = 0;
|
||||
@ -427,7 +427,7 @@ class APInt {
|
||||
/// @returns the all-ones value for an APInt of the specified bit-width.
|
||||
/// @brief Get the all-ones value.
|
||||
static APInt getAllOnesValue(unsigned numBits) {
|
||||
return APInt(numBits, -1ULL, true);
|
||||
return APInt(numBits, UINT64_MAX, true);
|
||||
}
|
||||
|
||||
/// @returns the '0' value for an APInt of the specified bit-width.
|
||||
@ -498,13 +498,24 @@ class APInt {
|
||||
if (loBitsSet == 0)
|
||||
return APInt(numBits, 0);
|
||||
if (loBitsSet == APINT_BITS_PER_WORD)
|
||||
return APInt(numBits, -1ULL);
|
||||
return APInt(numBits, UINT64_MAX);
|
||||
// For small values, return quickly.
|
||||
if (loBitsSet <= APINT_BITS_PER_WORD)
|
||||
return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet));
|
||||
return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet));
|
||||
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
|
||||
}
|
||||
|
||||
/// \brief Return a value containing V broadcasted over NewLen bits.
|
||||
static APInt getSplat(unsigned NewLen, const APInt &V) {
|
||||
assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
|
||||
|
||||
APInt Val = V.zextOrSelf(NewLen);
|
||||
for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
|
||||
Val |= Val << I;
|
||||
|
||||
return Val;
|
||||
}
|
||||
|
||||
/// \brief Determine if two APInts have the same value, after zero-extending
|
||||
/// one of them (if needed!) to ensure that the bit-widths match.
|
||||
static bool isSameValue(const APInt &I1, const APInt &I2) {
|
||||
@ -601,7 +612,7 @@ class APInt {
|
||||
return AssignSlowCase(RHS);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
/// @brief Move assignment operator.
|
||||
APInt& operator=(APInt&& that) {
|
||||
if (!isSingleWord())
|
||||
@ -799,16 +810,7 @@ class APInt {
|
||||
|
||||
/// Signed divide this APInt by APInt RHS.
|
||||
/// @brief Signed division function for APInt.
|
||||
APInt sdiv(const APInt &RHS) const {
|
||||
if (isNegative())
|
||||
if (RHS.isNegative())
|
||||
return (-(*this)).udiv(-RHS);
|
||||
else
|
||||
return -((-(*this)).udiv(RHS));
|
||||
else if (RHS.isNegative())
|
||||
return -(this->udiv(-RHS));
|
||||
return this->udiv(RHS);
|
||||
}
|
||||
APInt sdiv(const APInt &RHS) const;
|
||||
|
||||
/// Perform an unsigned remainder operation on this APInt with RHS being the
|
||||
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
|
||||
@ -821,16 +823,7 @@ class APInt {
|
||||
|
||||
/// Signed remainder operation on APInt.
|
||||
/// @brief Function for signed remainder operation.
|
||||
APInt srem(const APInt &RHS) const {
|
||||
if (isNegative())
|
||||
if (RHS.isNegative())
|
||||
return -((-(*this)).urem(-RHS));
|
||||
else
|
||||
return -((-(*this)).urem(RHS));
|
||||
else if (RHS.isNegative())
|
||||
return this->urem(-RHS);
|
||||
return this->urem(RHS);
|
||||
}
|
||||
APInt srem(const APInt &RHS) const;
|
||||
|
||||
/// Sometimes it is convenient to divide two APInt values and obtain both the
|
||||
/// quotient and remainder. This function does both operations in the same
|
||||
@ -842,24 +835,9 @@ class APInt {
|
||||
APInt &Quotient, APInt &Remainder);
|
||||
|
||||
static void sdivrem(const APInt &LHS, const APInt &RHS,
|
||||
APInt &Quotient, APInt &Remainder) {
|
||||
if (LHS.isNegative()) {
|
||||
if (RHS.isNegative())
|
||||
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
|
||||
else {
|
||||
APInt::udivrem(-LHS, RHS, Quotient, Remainder);
|
||||
Quotient = -Quotient;
|
||||
}
|
||||
Remainder = -Remainder;
|
||||
} else if (RHS.isNegative()) {
|
||||
APInt::udivrem(LHS, -RHS, Quotient, Remainder);
|
||||
Quotient = -Quotient;
|
||||
} else {
|
||||
APInt::udivrem(LHS, RHS, Quotient, Remainder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
APInt &Quotient, APInt &Remainder);
|
||||
|
||||
|
||||
// Operations that return overflow indicators.
|
||||
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
|
||||
APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
|
||||
@ -1113,11 +1091,11 @@ class APInt {
|
||||
/// @brief Set every bit to 1.
|
||||
void setAllBits() {
|
||||
if (isSingleWord())
|
||||
VAL = -1ULL;
|
||||
VAL = UINT64_MAX;
|
||||
else {
|
||||
// Set all the bits in all the words.
|
||||
for (unsigned i = 0; i < getNumWords(); ++i)
|
||||
pVal[i] = -1ULL;
|
||||
pVal[i] = UINT64_MAX;
|
||||
}
|
||||
// Clear the unused ones
|
||||
clearUnusedBits();
|
||||
@ -1142,10 +1120,10 @@ class APInt {
|
||||
/// @brief Toggle every bit to its opposite value.
|
||||
void flipAllBits() {
|
||||
if (isSingleWord())
|
||||
VAL ^= -1ULL;
|
||||
VAL ^= UINT64_MAX;
|
||||
else {
|
||||
for (unsigned i = 0; i < getNumWords(); ++i)
|
||||
pVal[i] ^= -1ULL;
|
||||
pVal[i] ^= UINT64_MAX;
|
||||
}
|
||||
clearUnusedBits();
|
||||
}
|
||||
@ -1191,7 +1169,8 @@ class APInt {
|
||||
/// APInt. This is used in conjunction with getActiveData to extract the raw
|
||||
/// value of the APInt.
|
||||
unsigned getActiveWords() const {
|
||||
return whichWord(getActiveBits()-1) + 1;
|
||||
unsigned numActiveBits = getActiveBits();
|
||||
return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
|
||||
}
|
||||
|
||||
/// Computes the minimum bit width for this APInt while considering it to be
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_APSINT_H
|
||||
#define LLVM_APSINT_H
|
||||
#ifndef LLVM_ADT_APSINT_H
|
||||
#define LLVM_ADT_APSINT_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
|
||||
@ -23,7 +23,7 @@ class APSInt : public APInt {
|
||||
bool IsUnsigned;
|
||||
public:
|
||||
/// Default constructor that creates an uninitialized APInt.
|
||||
explicit APSInt() {}
|
||||
explicit APSInt() : IsUnsigned(false) {}
|
||||
|
||||
/// APSInt ctor - Create an APSInt with the specified width, default to
|
||||
/// unsigned.
|
||||
@ -161,11 +161,11 @@ class APSInt : public APInt {
|
||||
}
|
||||
|
||||
APSInt& operator++() {
|
||||
static_cast<APInt&>(*this)++;
|
||||
++(static_cast<APInt&>(*this));
|
||||
return *this;
|
||||
}
|
||||
APSInt& operator--() {
|
||||
static_cast<APInt&>(*this)--;
|
||||
--(static_cast<APInt&>(*this));
|
||||
return *this;
|
||||
}
|
||||
APSInt operator++(int) {
|
||||
|
@ -33,6 +33,8 @@ namespace llvm {
|
||||
typedef const T *const_iterator;
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
private:
|
||||
/// The start of the array, in an external buffer.
|
||||
const T *Data;
|
||||
@ -84,6 +86,9 @@ namespace llvm {
|
||||
iterator begin() const { return Data; }
|
||||
iterator end() const { return Data + Length; }
|
||||
|
||||
reverse_iterator rbegin() const { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() const { return reverse_iterator(begin()); }
|
||||
|
||||
/// empty - Check if the array is empty.
|
||||
bool empty() const { return Length == 0; }
|
||||
|
||||
@ -171,41 +176,41 @@ namespace llvm {
|
||||
|
||||
/// Construct an empty ArrayRef.
|
||||
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
|
||||
|
||||
|
||||
/// Construct an MutableArrayRef from a single element.
|
||||
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
|
||||
|
||||
|
||||
/// Construct an MutableArrayRef from a pointer and length.
|
||||
/*implicit*/ MutableArrayRef(T *data, size_t length)
|
||||
: ArrayRef<T>(data, length) {}
|
||||
|
||||
|
||||
/// Construct an MutableArrayRef from a range.
|
||||
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
|
||||
|
||||
|
||||
/// Construct an MutableArrayRef from a SmallVector.
|
||||
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
|
||||
: ArrayRef<T>(Vec) {}
|
||||
|
||||
|
||||
/// Construct a MutableArrayRef from a std::vector.
|
||||
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
|
||||
: ArrayRef<T>(Vec) {}
|
||||
|
||||
|
||||
/// Construct an MutableArrayRef from a C array.
|
||||
template <size_t N>
|
||||
/*implicit*/ MutableArrayRef(T (&Arr)[N])
|
||||
: ArrayRef<T>(Arr) {}
|
||||
|
||||
|
||||
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
|
||||
|
||||
iterator begin() const { return data(); }
|
||||
iterator end() const { return data() + this->size(); }
|
||||
|
||||
|
||||
/// front - Get the first element.
|
||||
T &front() const {
|
||||
assert(!this->empty());
|
||||
return data()[0];
|
||||
}
|
||||
|
||||
|
||||
/// back - Get the last element.
|
||||
T &back() const {
|
||||
assert(!this->empty());
|
||||
@ -217,14 +222,14 @@ namespace llvm {
|
||||
assert(N <= this->size() && "Invalid specifier");
|
||||
return MutableArrayRef<T>(data()+N, this->size()-N);
|
||||
}
|
||||
|
||||
|
||||
/// slice(n, m) - Chop off the first N elements of the array, and keep M
|
||||
/// elements in the array.
|
||||
MutableArrayRef<T> slice(unsigned N, unsigned M) const {
|
||||
assert(N+M <= this->size() && "Invalid specifier");
|
||||
return MutableArrayRef<T>(data()+N, M);
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
/// @name Operator Overloads
|
||||
/// @{
|
||||
@ -301,5 +306,5 @@ namespace llvm {
|
||||
static const bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -98,7 +98,7 @@ class BitVector {
|
||||
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
BitVector(BitVector &&RHS)
|
||||
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
|
||||
RHS.Bits = 0;
|
||||
@ -452,7 +452,7 @@ class BitVector {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
const BitVector &operator=(BitVector &&RHS) {
|
||||
if (this == &RHS) return *this;
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
|
||||
#define LLVM_ADT_DAGDELTAALGORITHM_H
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
#ifndef LLVM_ADT_DELTAALGORITHM_H
|
||||
#define LLVM_ADT_DELTAALGORITHM_H
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -14,20 +14,20 @@
|
||||
#ifndef LLVM_ADT_DENSEMAP_H
|
||||
#define LLVM_ADT_DENSEMAP_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -75,7 +75,7 @@ class DenseMapBase {
|
||||
|
||||
void clear() {
|
||||
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
|
||||
|
||||
|
||||
// If the capacity of the array is huge, and the # elements used is small,
|
||||
// shrink the array.
|
||||
if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
|
||||
@ -159,6 +159,24 @@ class DenseMapBase {
|
||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
|
||||
}
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
// Inserts key,value pair into the map if the key isn't already in the map.
|
||||
// If the key is already in the map, it returns false and doesn't update the
|
||||
// value.
|
||||
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(KV.first, TheBucket))
|
||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
|
||||
false); // Already in map.
|
||||
|
||||
// Otherwise, insert the new element.
|
||||
TheBucket = InsertIntoBucket(std::move(KV.first),
|
||||
std::move(KV.second),
|
||||
TheBucket);
|
||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// insert - Range insertion of pairs.
|
||||
template<typename InputIt>
|
||||
void insert(InputIt I, InputIt E) {
|
||||
@ -198,7 +216,7 @@ class DenseMapBase {
|
||||
return FindAndConstruct(Key).second;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
value_type& FindAndConstruct(KeyT &&Key) {
|
||||
BucketT *TheBucket;
|
||||
if (LookupBucketFor(Key, TheBucket))
|
||||
@ -383,7 +401,7 @@ class DenseMapBase {
|
||||
return TheBucket;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
|
||||
BucketT *TheBucket) {
|
||||
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
|
||||
@ -430,7 +448,8 @@ class DenseMapBase {
|
||||
incrementNumEntries();
|
||||
|
||||
// If we are writing over a tombstone, remember this.
|
||||
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
|
||||
const KeyT EmptyKey = getEmptyKey();
|
||||
if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
|
||||
decrementNumTombstones();
|
||||
|
||||
return TheBucket;
|
||||
@ -474,7 +493,6 @@ class DenseMapBase {
|
||||
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
|
||||
// If we've already seen a tombstone while probing, fill it in instead
|
||||
// of the empty bucket we eventually probed to.
|
||||
if (FoundTombstone) ThisBucket = FoundTombstone;
|
||||
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
|
||||
return false;
|
||||
}
|
||||
@ -531,13 +549,13 @@ class DenseMap
|
||||
init(NumInitBuckets);
|
||||
}
|
||||
|
||||
DenseMap(const DenseMap &other) {
|
||||
DenseMap(const DenseMap &other) : BaseT() {
|
||||
init(0);
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
DenseMap(DenseMap &&other) {
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
DenseMap(DenseMap &&other) : BaseT() {
|
||||
init(0);
|
||||
swap(other);
|
||||
}
|
||||
@ -566,7 +584,7 @@ class DenseMap
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
DenseMap& operator=(DenseMap &&other) {
|
||||
this->destroyAll();
|
||||
operator delete(Buckets);
|
||||
@ -700,7 +718,7 @@ class SmallDenseMap
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
SmallDenseMap(SmallDenseMap &&other) {
|
||||
init(0);
|
||||
swap(other);
|
||||
@ -795,7 +813,7 @@ class SmallDenseMap
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
SmallDenseMap& operator=(SmallDenseMap &&other) {
|
||||
this->destroyAll();
|
||||
deallocateBuckets();
|
||||
@ -1027,7 +1045,7 @@ class DenseMapIterator {
|
||||
++Ptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename KeyT, typename ValueT, typename KeyInfoT>
|
||||
static inline size_t
|
||||
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
|
||||
|
@ -32,8 +32,10 @@ class DenseSet {
|
||||
|
||||
bool empty() const { return TheMap.empty(); }
|
||||
unsigned size() const { return TheMap.size(); }
|
||||
size_t getMemorySize() const { return TheMap.getMemorySize(); }
|
||||
|
||||
/// Grow the denseset so that it has at least Size buckets. Does not shrink
|
||||
/// Grow the DenseSet so that it has at least Size buckets. Will not shrink
|
||||
/// the Size of the set.
|
||||
void resize(size_t Size) { TheMap.resize(Size); }
|
||||
|
||||
void clear() {
|
||||
|
@ -34,8 +34,8 @@
|
||||
#define LLVM_ADT_DEPTHFIRSTITERATOR_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
#ifndef LLVM_ADT_FOLDINGSET_H
|
||||
#define LLVM_ADT_FOLDINGSET_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class APFloat;
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
|
||||
#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
|
||||
#ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H
|
||||
#define LLVM_ADT_IMMUTABLEINTERVALMAP_H
|
||||
|
||||
#include "llvm/ADT/ImmutableMap.h"
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_IMLIST_H
|
||||
#define LLVM_ADT_IMLIST_H
|
||||
#ifndef LLVM_ADT_IMMUTABLELIST_H
|
||||
#define LLVM_ADT_IMMUTABLELIST_H
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_IMMAP_H
|
||||
#define LLVM_ADT_IMMAP_H
|
||||
#ifndef LLVM_ADT_IMMUTABLEMAP_H
|
||||
#define LLVM_ADT_IMMUTABLEMAP_H
|
||||
|
||||
#include "llvm/ADT/ImmutableSet.h"
|
||||
|
||||
@ -211,17 +211,22 @@ class ImmutableMap {
|
||||
friend class ImmutableMap;
|
||||
|
||||
public:
|
||||
value_type_ref operator*() const { return itr->getValue(); }
|
||||
value_type* operator->() const { return &itr->getValue(); }
|
||||
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type;
|
||||
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference;
|
||||
typedef typename iterator::value_type *pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typename iterator::reference operator*() const { return itr->getValue(); }
|
||||
typename iterator::pointer operator->() const { return &itr->getValue(); }
|
||||
|
||||
key_type_ref getKey() const { return itr->getValue().first; }
|
||||
data_type_ref getData() const { return itr->getValue().second; }
|
||||
|
||||
|
||||
iterator& operator++() { ++itr; return *this; }
|
||||
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
||||
iterator& operator--() { --itr; return *this; }
|
||||
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
|
||||
|
||||
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
|
||||
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
|
||||
};
|
||||
@ -288,6 +293,13 @@ class ImmutableMapRef {
|
||||
Factory(F) {
|
||||
if (Root) { Root->retain(); }
|
||||
}
|
||||
|
||||
explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
|
||||
typename ImmutableMap<KeyT, ValT>::Factory &F)
|
||||
: Root(X.getRootWithoutRetain()),
|
||||
Factory(F.getTreeFactory()) {
|
||||
if (Root) { Root->retain(); }
|
||||
}
|
||||
|
||||
ImmutableMapRef(const ImmutableMapRef &X)
|
||||
: Root(X.Root),
|
||||
@ -318,12 +330,20 @@ class ImmutableMapRef {
|
||||
return ImmutableMapRef(0, F);
|
||||
}
|
||||
|
||||
ImmutableMapRef add(key_type_ref K, data_type_ref D) {
|
||||
void manualRetain() {
|
||||
if (Root) Root->retain();
|
||||
}
|
||||
|
||||
void manualRelease() {
|
||||
if (Root) Root->release();
|
||||
}
|
||||
|
||||
ImmutableMapRef add(key_type_ref K, data_type_ref D) const {
|
||||
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
|
||||
return ImmutableMapRef(NewT, Factory);
|
||||
}
|
||||
|
||||
ImmutableMapRef remove(key_type_ref K) {
|
||||
ImmutableMapRef remove(key_type_ref K) const {
|
||||
TreeTy *NewT = Factory->remove(Root, K);
|
||||
return ImmutableMapRef(NewT, Factory);
|
||||
}
|
||||
|
@ -11,12 +11,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_IMSET_H
|
||||
#define LLVM_ADT_IMSET_H
|
||||
#ifndef LLVM_ADT_IMMUTABLESET_H
|
||||
#define LLVM_ADT_IMMUTABLESET_H
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
@ -1054,18 +1054,27 @@ class ImmutableSet {
|
||||
|
||||
class iterator {
|
||||
typename TreeTy::iterator itr;
|
||||
|
||||
iterator() {}
|
||||
iterator(TreeTy* t) : itr(t) {}
|
||||
friend class ImmutableSet<ValT,ValInfo>;
|
||||
|
||||
public:
|
||||
iterator() {}
|
||||
inline value_type_ref operator*() const { return itr->getValue(); }
|
||||
inline iterator& operator++() { ++itr; return *this; }
|
||||
inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
||||
inline iterator& operator--() { --itr; return *this; }
|
||||
inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
|
||||
inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
|
||||
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
|
||||
inline value_type *operator->() const { return &(operator*()); }
|
||||
typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type;
|
||||
typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference;
|
||||
typedef typename iterator::value_type *pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typename iterator::reference operator*() const { return itr->getValue(); }
|
||||
typename iterator::pointer operator->() const { return &(operator*()); }
|
||||
|
||||
iterator& operator++() { ++itr; return *this; }
|
||||
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
||||
iterator& operator--() { --itr; return *this; }
|
||||
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
|
||||
|
||||
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
|
||||
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
|
||||
};
|
||||
|
||||
iterator begin() const { return iterator(Root); }
|
||||
|
@ -99,8 +99,8 @@
|
||||
#ifndef LLVM_ADT_INTERVALMAP_H
|
||||
#define LLVM_ADT_INTERVALMAP_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/RecyclingAllocator.h"
|
||||
#include <iterator>
|
||||
@ -151,6 +151,26 @@ struct IntervalMapInfo {
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IntervalMapHalfOpenInfo {
|
||||
|
||||
/// startLess - Return true if x is not in [a;b).
|
||||
static inline bool startLess(const T &x, const T &a) {
|
||||
return x < a;
|
||||
}
|
||||
|
||||
/// stopLess - Return true if x is not in [a;b).
|
||||
static inline bool stopLess(const T &b, const T &x) {
|
||||
return b <= x;
|
||||
}
|
||||
|
||||
/// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
|
||||
static inline bool adjacent(const T &a, const T &b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
|
||||
/// It should be considered private to the implementation.
|
||||
namespace IntervalMapImpl {
|
||||
|
@ -18,8 +18,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
|
||||
#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
|
||||
#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
|
||||
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
|
||||
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
@ -123,7 +123,7 @@ namespace llvm {
|
||||
retain();
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
|
||||
S.Obj = 0;
|
||||
}
|
||||
@ -226,13 +226,13 @@ namespace llvm {
|
||||
|
||||
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
|
||||
typedef T* SimpleType;
|
||||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
|
||||
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
|
||||
return Val.getPtr();
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
|
||||
typedef T* SimpleType;
|
||||
typedef /*const*/ T* SimpleType;
|
||||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
|
||||
return Val.getPtr();
|
||||
}
|
||||
@ -240,4 +240,4 @@ namespace llvm {
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
|
||||
#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@ -63,6 +64,11 @@ class MapVector {
|
||||
return Vector.empty();
|
||||
}
|
||||
|
||||
std::pair<KeyT, ValueT> &front() { return Vector.front(); }
|
||||
const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
|
||||
std::pair<KeyT, ValueT> &back() { return Vector.back(); }
|
||||
const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
|
||||
|
||||
void clear() {
|
||||
Map.clear();
|
||||
Vector.clear();
|
||||
@ -79,10 +85,46 @@ class MapVector {
|
||||
return Vector[I].second;
|
||||
}
|
||||
|
||||
ValueT lookup(const KeyT &Key) const {
|
||||
typename MapType::const_iterator Pos = Map.find(Key);
|
||||
return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
|
||||
}
|
||||
|
||||
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
|
||||
std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
|
||||
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
|
||||
unsigned &I = Result.first->second;
|
||||
if (Result.second) {
|
||||
Vector.push_back(std::make_pair(KV.first, KV.second));
|
||||
I = Vector.size() - 1;
|
||||
return std::make_pair(llvm::prior(end()), true);
|
||||
}
|
||||
return std::make_pair(begin() + I, false);
|
||||
}
|
||||
|
||||
unsigned count(const KeyT &Key) const {
|
||||
typename MapType::const_iterator Pos = Map.find(Key);
|
||||
return Pos == Map.end()? 0 : 1;
|
||||
}
|
||||
|
||||
iterator find(const KeyT &Key) {
|
||||
typename MapType::const_iterator Pos = Map.find(Key);
|
||||
return Pos == Map.end()? Vector.end() :
|
||||
(Vector.begin() + Pos->second);
|
||||
}
|
||||
|
||||
const_iterator find(const KeyT &Key) const {
|
||||
typename MapType::const_iterator Pos = Map.find(Key);
|
||||
return Pos == Map.end()? Vector.end() :
|
||||
(Vector.begin() + Pos->second);
|
||||
}
|
||||
|
||||
/// \brief Remove the last element from the vector.
|
||||
void pop_back() {
|
||||
typename MapType::iterator Pos = Map.find(Vector.back().first);
|
||||
Map.erase(Pos);
|
||||
Vector.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
27
contrib/llvm/include/llvm/ADT/None.h
Normal file
27
contrib/llvm/include/llvm/ADT/None.h
Normal file
@ -0,0 +1,27 @@
|
||||
//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides None, an enumerator for use in implicit constructors
|
||||
// of various (usually templated) types to make such construction more
|
||||
// terse.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_NONE_H
|
||||
#define LLVM_ADT_NONE_H
|
||||
|
||||
namespace llvm {
|
||||
/// \brief A simple null object to allow implicit construction of Optional<T>
|
||||
/// and similar types without having to spell out the specialization's name.
|
||||
enum NoneType {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_NULLABLE_PTR_H
|
||||
#define LLVM_ADT_NULLABLE_PTR_H
|
||||
#ifndef LLVM_ADT_NULLABLEPTR_H
|
||||
#define LLVM_ADT_NULLABLEPTR_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
@ -13,13 +13,15 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_OPTIONAL
|
||||
#define LLVM_ADT_OPTIONAL
|
||||
#ifndef LLVM_ADT_OPTIONAL_H
|
||||
#define LLVM_ADT_OPTIONAL_H
|
||||
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include <cassert>
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
@ -27,54 +29,116 @@ namespace llvm {
|
||||
|
||||
template<typename T>
|
||||
class Optional {
|
||||
T x;
|
||||
unsigned hasVal : 1;
|
||||
AlignedCharArrayUnion<T> storage;
|
||||
bool hasVal;
|
||||
public:
|
||||
explicit Optional() : x(), hasVal(false) {}
|
||||
Optional(const T &y) : x(y), hasVal(true) {}
|
||||
Optional(NoneType) : hasVal(false) {}
|
||||
explicit Optional() : hasVal(false) {}
|
||||
Optional(const T &y) : hasVal(true) {
|
||||
new (storage.buffer) T(y);
|
||||
}
|
||||
Optional(const Optional &O) : hasVal(O.hasVal) {
|
||||
if (hasVal)
|
||||
new (storage.buffer) T(*O);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
Optional(T &&y) : hasVal(true) {
|
||||
new (storage.buffer) T(std::forward<T>(y));
|
||||
}
|
||||
Optional(Optional<T> &&O) : hasVal(O) {
|
||||
if (O) {
|
||||
new (storage.buffer) T(std::move(*O));
|
||||
O.reset();
|
||||
}
|
||||
}
|
||||
Optional &operator=(T &&y) {
|
||||
if (hasVal)
|
||||
**this = std::move(y);
|
||||
else {
|
||||
new (storage.buffer) T(std::move(y));
|
||||
hasVal = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Optional &operator=(Optional &&O) {
|
||||
if (!O)
|
||||
reset();
|
||||
else {
|
||||
*this = std::move(*O);
|
||||
O.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline Optional create(const T* y) {
|
||||
return y ? Optional(*y) : Optional();
|
||||
}
|
||||
|
||||
// FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
|
||||
// could be made more efficient by passing by value, possibly unifying them
|
||||
// with the rvalue versions above - but this could place a different set of
|
||||
// requirements (notably: the existence of a default ctor) when implemented
|
||||
// in that way. Careful SFINAE to avoid such pitfalls would be required.
|
||||
Optional &operator=(const T &y) {
|
||||
x = y;
|
||||
hasVal = true;
|
||||
if (hasVal)
|
||||
**this = y;
|
||||
else {
|
||||
new (storage.buffer) T(y);
|
||||
hasVal = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T* getPointer() const { assert(hasVal); return &x; }
|
||||
const T& getValue() const { assert(hasVal); return x; }
|
||||
|
||||
operator bool() const { return hasVal; }
|
||||
Optional &operator=(const Optional &O) {
|
||||
if (!O)
|
||||
reset();
|
||||
else
|
||||
*this = *O;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (hasVal) {
|
||||
(**this).~T();
|
||||
hasVal = false;
|
||||
}
|
||||
}
|
||||
|
||||
~Optional() {
|
||||
reset();
|
||||
}
|
||||
|
||||
const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
|
||||
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
|
||||
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
|
||||
T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
|
||||
|
||||
LLVM_EXPLICIT operator bool() const { return hasVal; }
|
||||
bool hasValue() const { return hasVal; }
|
||||
const T* operator->() const { return getPointer(); }
|
||||
const T& operator*() const { assert(hasVal); return x; }
|
||||
T* operator->() { return getPointer(); }
|
||||
const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
|
||||
T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCE_THIS
|
||||
T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
|
||||
T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T> struct simplify_type;
|
||||
|
||||
template <typename T>
|
||||
struct simplify_type<const Optional<T> > {
|
||||
typedef const T* SimpleType;
|
||||
static SimpleType getSimplifiedValue(const Optional<T> &Val) {
|
||||
return Val.getPointer();
|
||||
}
|
||||
template <typename T> struct isPodLike;
|
||||
template <typename T> struct isPodLike<Optional<T> > {
|
||||
// An Optional<T> is pod-like if T is.
|
||||
static const bool value = isPodLike<T>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct simplify_type<Optional<T> >
|
||||
: public simplify_type<const Optional<T> > {};
|
||||
|
||||
/// \brief Poison comparison between two \c Optional objects. Clients needs to
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator==(const Optional<T> &X, const Optional<U> &Y);
|
||||
@ -83,7 +147,7 @@ void operator==(const Optional<T> &X, const Optional<U> &Y);
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator!=(const Optional<T> &X, const Optional<U> &Y);
|
||||
@ -92,7 +156,7 @@ void operator!=(const Optional<T> &X, const Optional<U> &Y);
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator<(const Optional<T> &X, const Optional<U> &Y);
|
||||
@ -101,7 +165,7 @@ void operator<(const Optional<T> &X, const Optional<U> &Y);
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator<=(const Optional<T> &X, const Optional<U> &Y);
|
||||
@ -110,7 +174,7 @@ void operator<=(const Optional<T> &X, const Optional<U> &Y);
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator>=(const Optional<T> &X, const Optional<U> &Y);
|
||||
@ -119,7 +183,7 @@ void operator>=(const Optional<T> &X, const Optional<U> &Y);
|
||||
/// explicitly compare the underlying values and account for empty \c Optional
|
||||
/// objects.
|
||||
///
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// This routine will never be defined. It returns \c void to help diagnose
|
||||
/// errors at compile time.
|
||||
template<typename T, typename U>
|
||||
void operator>(const Optional<T> &X, const Optional<U> &Y);
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_OWNING_PTR_H
|
||||
#define LLVM_ADT_OWNING_PTR_H
|
||||
#ifndef LLVM_ADT_OWNINGPTR_H
|
||||
#define LLVM_ADT_OWNINGPTR_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
@ -32,7 +32,7 @@ class OwningPtr {
|
||||
public:
|
||||
explicit OwningPtr(T *P = 0) : Ptr(P) {}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
|
||||
|
||||
OwningPtr &operator=(OwningPtr &&Other) {
|
||||
@ -95,7 +95,7 @@ class OwningArrayPtr {
|
||||
public:
|
||||
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
|
||||
|
||||
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
|
||||
|
@ -57,11 +57,13 @@ class PointerIntPair {
|
||||
};
|
||||
public:
|
||||
PointerIntPair() : Value(0) {}
|
||||
PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
|
||||
PointerIntPair(PointerTy Ptr, IntType Int) {
|
||||
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
|
||||
"PointerIntPair formed with integer size too large for pointer");
|
||||
setPointer(Ptr);
|
||||
setInt(Int);
|
||||
setPointerAndInt(Ptr, Int);
|
||||
}
|
||||
explicit PointerIntPair(PointerTy Ptr) {
|
||||
initWithPointer(Ptr);
|
||||
}
|
||||
|
||||
PointerTy getPointer() const {
|
||||
@ -91,6 +93,25 @@ class PointerIntPair {
|
||||
Value |= IntVal << IntShift; // Set new integer.
|
||||
}
|
||||
|
||||
void initWithPointer(PointerTy Ptr) {
|
||||
intptr_t PtrVal
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
|
||||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
"Pointer is not sufficiently aligned");
|
||||
Value = PtrVal;
|
||||
}
|
||||
|
||||
void setPointerAndInt(PointerTy Ptr, IntType Int) {
|
||||
intptr_t PtrVal
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
|
||||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
"Pointer is not sufficiently aligned");
|
||||
intptr_t IntVal = Int;
|
||||
assert(IntVal < (1 << IntBits) && "Integer too large for field");
|
||||
|
||||
Value = PtrVal | (IntVal << IntShift);
|
||||
}
|
||||
|
||||
PointerTy const *getAddrOfPointer() const {
|
||||
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
|
||||
}
|
||||
|
@ -95,15 +95,11 @@ namespace llvm {
|
||||
public:
|
||||
PointerUnion() {}
|
||||
|
||||
PointerUnion(PT1 V) {
|
||||
Val.setPointer(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
|
||||
Val.setInt(0);
|
||||
PointerUnion(PT1 V) : Val(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
|
||||
}
|
||||
PointerUnion(PT2 V) {
|
||||
Val.setPointer(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
|
||||
Val.setInt(1);
|
||||
PointerUnion(PT2 V) : Val(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
|
||||
}
|
||||
|
||||
/// isNull - Return true if the pointer held in the union is null,
|
||||
@ -160,15 +156,14 @@ namespace llvm {
|
||||
/// Assignment operators - Allow assigning into this union from either
|
||||
/// pointer type, setting the discriminator to remember what it came from.
|
||||
const PointerUnion &operator=(const PT1 &RHS) {
|
||||
Val.setPointer(
|
||||
Val.initWithPointer(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
|
||||
Val.setInt(0);
|
||||
return *this;
|
||||
}
|
||||
const PointerUnion &operator=(const PT2 &RHS) {
|
||||
Val.setPointer(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
|
||||
Val.setInt(1);
|
||||
Val.setPointerAndInt(
|
||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
|
||||
1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ class ReversePostOrderTraversal {
|
||||
typedef typename GT::NodeType NodeType;
|
||||
std::vector<NodeType*> Blocks; // Block list in normal PO order
|
||||
inline void Initialize(NodeType *BB) {
|
||||
copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
|
||||
std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
|
||||
}
|
||||
public:
|
||||
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_PRIORITY_QUEUE_H
|
||||
#define LLVM_ADT_PRIORITY_QUEUE_H
|
||||
#ifndef LLVM_ADT_PRIORITYQUEUE_H
|
||||
#define LLVM_ADT_PRIORITYQUEUE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
|
@ -21,8 +21,8 @@
|
||||
#ifndef LLVM_ADT_SCCITERATOR_H
|
||||
#define LLVM_ADT_SCCITERATOR_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -246,10 +246,10 @@ inline int array_pod_sort_comparator(const void *P1, const void *P2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// get_array_pad_sort_comparator - This is an internal helper function used to
|
||||
/// get_array_pod_sort_comparator - This is an internal helper function used to
|
||||
/// get type deduction of T right.
|
||||
template<typename T>
|
||||
inline int (*get_array_pad_sort_comparator(const T &))
|
||||
inline int (*get_array_pod_sort_comparator(const T &))
|
||||
(const void*, const void*) {
|
||||
return array_pod_sort_comparator<T>;
|
||||
}
|
||||
@ -274,7 +274,7 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
|
||||
// Don't dereference start iterator of empty sequence.
|
||||
if (Start == End) return;
|
||||
qsort(&*Start, End-Start, sizeof(*Start),
|
||||
get_array_pad_sort_comparator(*Start));
|
||||
get_array_pod_sort_comparator(*Start));
|
||||
}
|
||||
|
||||
template<class IteratorTy>
|
||||
|
@ -153,7 +153,7 @@ class SmallBitVector {
|
||||
switchToLarge(new BitVector(*RHS.getPointer()));
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
|
||||
RHS.X = 1;
|
||||
}
|
||||
@ -178,9 +178,9 @@ class SmallBitVector {
|
||||
unsigned count() const {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
if (NumBaseBits == 32)
|
||||
return CountPopulation_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
if (NumBaseBits == 64)
|
||||
return CountPopulation_64(Bits);
|
||||
llvm_unreachable("Unsupported!");
|
||||
}
|
||||
@ -215,9 +215,9 @@ class SmallBitVector {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
if (Bits == 0)
|
||||
return -1;
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
if (NumBaseBits == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
if (NumBaseBits == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
llvm_unreachable("Unsupported!");
|
||||
}
|
||||
@ -233,9 +233,9 @@ class SmallBitVector {
|
||||
Bits &= ~uintptr_t(0) << (Prev + 1);
|
||||
if (Bits == 0 || Prev + 1 >= getSmallSize())
|
||||
return -1;
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
if (NumBaseBits == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
if (NumBaseBits == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
llvm_unreachable("Unsupported!");
|
||||
}
|
||||
@ -472,7 +472,7 @@ class SmallBitVector {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
const SmallBitVector &operator=(SmallBitVector &&RHS) {
|
||||
if (this != &RHS) {
|
||||
clear();
|
||||
|
@ -54,8 +54,6 @@ class SmallPtrSetImpl {
|
||||
/// then the set is in 'small mode'.
|
||||
const void **CurArray;
|
||||
/// CurArraySize - The allocated size of CurArray, always a power of two.
|
||||
/// Note that CurArray points to an array that has CurArraySize+1 elements in
|
||||
/// it, so that the end iterator actually points to valid memory.
|
||||
unsigned CurArraySize;
|
||||
|
||||
// If small, this is # elts allocated consecutively
|
||||
@ -68,9 +66,6 @@ class SmallPtrSetImpl {
|
||||
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
|
||||
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
|
||||
"Initial size must be a power of two!");
|
||||
// The end pointer, always valid, is set to a valid element to help the
|
||||
// iterator.
|
||||
CurArray[SmallSize] = 0;
|
||||
clear();
|
||||
}
|
||||
~SmallPtrSetImpl();
|
||||
@ -147,9 +142,11 @@ class SmallPtrSetImpl {
|
||||
class SmallPtrSetIteratorImpl {
|
||||
protected:
|
||||
const void *const *Bucket;
|
||||
const void *const *End;
|
||||
public:
|
||||
explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
|
||||
AdvanceIfNotValid();
|
||||
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
|
||||
: Bucket(BP), End(E) {
|
||||
AdvanceIfNotValid();
|
||||
}
|
||||
|
||||
bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
|
||||
@ -164,8 +161,10 @@ class SmallPtrSetIteratorImpl {
|
||||
/// that is. This is guaranteed to stop because the end() bucket is marked
|
||||
/// valid.
|
||||
void AdvanceIfNotValid() {
|
||||
while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
|
||||
*Bucket == SmallPtrSetImpl::getTombstoneMarker())
|
||||
assert(Bucket <= End);
|
||||
while (Bucket != End &&
|
||||
(*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
|
||||
*Bucket == SmallPtrSetImpl::getTombstoneMarker()))
|
||||
++Bucket;
|
||||
}
|
||||
};
|
||||
@ -182,12 +181,13 @@ class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
explicit SmallPtrSetIterator(const void *const *BP)
|
||||
: SmallPtrSetIteratorImpl(BP) {}
|
||||
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
|
||||
: SmallPtrSetIteratorImpl(BP, E) {}
|
||||
|
||||
// Most methods provided by baseclass.
|
||||
|
||||
const PtrTy operator*() const {
|
||||
assert(Bucket < End);
|
||||
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
|
||||
}
|
||||
|
||||
@ -236,9 +236,8 @@ template<class PtrType, unsigned SmallSize>
|
||||
class SmallPtrSet : public SmallPtrSetImpl {
|
||||
// Make sure that SmallSize is a power of two, round up if not.
|
||||
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
|
||||
/// SmallStorage - Fixed size storage used in 'small mode'. The extra element
|
||||
/// ensures that the end iterator actually points to valid memory.
|
||||
const void *SmallStorage[SmallSizePowTwo+1];
|
||||
/// SmallStorage - Fixed size storage used in 'small mode'.
|
||||
const void *SmallStorage[SmallSizePowTwo];
|
||||
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
|
||||
public:
|
||||
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
|
||||
@ -275,10 +274,10 @@ class SmallPtrSet : public SmallPtrSetImpl {
|
||||
typedef SmallPtrSetIterator<PtrType> iterator;
|
||||
typedef SmallPtrSetIterator<PtrType> const_iterator;
|
||||
inline iterator begin() const {
|
||||
return iterator(CurArray);
|
||||
return iterator(CurArray, CurArray+CurArraySize);
|
||||
}
|
||||
inline iterator end() const {
|
||||
return iterator(CurArray+CurArraySize);
|
||||
return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
|
||||
}
|
||||
|
||||
// Allow assignment from any smallptrset with the same element type even if it
|
||||
|
@ -14,8 +14,8 @@
|
||||
#ifndef LLVM_ADT_SMALLSET_H
|
||||
#define LLVM_ADT_SMALLSET_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
@ -55,6 +55,7 @@ class SmallSet {
|
||||
}
|
||||
|
||||
/// insert - Insert an element into the set if it isn't already there.
|
||||
/// Returns true if the element is inserted (it was not in the set before).
|
||||
bool insert(const T &V) {
|
||||
if (!isSmall())
|
||||
return Set.insert(V).second;
|
||||
|
@ -77,7 +77,7 @@ class SmallString : public SmallVector<char, InternalLen> {
|
||||
void append(in_iter S, in_iter E) {
|
||||
SmallVectorImpl<char>::append(S, E);
|
||||
}
|
||||
|
||||
|
||||
void append(size_t NumInputs, char Elt) {
|
||||
SmallVectorImpl<char>::append(NumInputs, Elt);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@ -145,16 +146,20 @@ class SmallVectorTemplateCommon : public SmallVectorBase {
|
||||
}
|
||||
|
||||
reference front() {
|
||||
assert(!empty());
|
||||
return begin()[0];
|
||||
}
|
||||
const_reference front() const {
|
||||
assert(!empty());
|
||||
return begin()[0];
|
||||
}
|
||||
|
||||
reference back() {
|
||||
assert(!empty());
|
||||
return end()[-1];
|
||||
}
|
||||
const_reference back() const {
|
||||
assert(!empty());
|
||||
return end()[-1];
|
||||
}
|
||||
};
|
||||
@ -178,7 +183,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
||||
/// std::move, but not all stdlibs actually provide that.
|
||||
template<typename It1, typename It2>
|
||||
static It2 move(It1 I, It1 E, It2 Dest) {
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
for (; I != E; ++I, ++Dest)
|
||||
*Dest = ::std::move(*I);
|
||||
return Dest;
|
||||
@ -193,7 +198,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
||||
/// std::move_backward, but not all stdlibs actually provide that.
|
||||
template<typename It1, typename It2>
|
||||
static It2 move_backward(It1 I, It1 E, It2 Dest) {
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
while (I != E)
|
||||
*--Dest = ::std::move(*--E);
|
||||
return Dest;
|
||||
@ -206,7 +211,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
||||
/// memory starting with "Dest", constructing elements as needed.
|
||||
template<typename It1, typename It2>
|
||||
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
for (; I != E; ++I, ++Dest)
|
||||
::new ((void*) &*Dest) T(::std::move(*I));
|
||||
#else
|
||||
@ -239,7 +244,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
||||
goto Retry;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
void push_back(T &&Elt) {
|
||||
if (this->EndX < this->CapacityX) {
|
||||
Retry:
|
||||
@ -263,7 +268,8 @@ template <typename T, bool isPodLike>
|
||||
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
|
||||
size_t CurCapacity = this->capacity();
|
||||
size_t CurSize = this->size();
|
||||
size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
|
||||
// Always grow, even from zero.
|
||||
size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
|
||||
if (NewCapacity < MinSize)
|
||||
NewCapacity = MinSize;
|
||||
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
|
||||
@ -365,7 +371,7 @@ template <typename T>
|
||||
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
|
||||
|
||||
SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
|
||||
SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
typedef typename SuperClass::iterator iterator;
|
||||
typedef typename SuperClass::size_type size_type;
|
||||
@ -422,7 +428,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||
}
|
||||
|
||||
T pop_back_val() {
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
T Result = ::std::move(this->back());
|
||||
#else
|
||||
T Result = this->back();
|
||||
@ -495,7 +501,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||
return(N);
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
iterator insert(iterator I, T &&Elt) {
|
||||
if (I == this->end()) { // Important special case for empty vector.
|
||||
this->push_back(::std::move(Elt));
|
||||
@ -667,7 +673,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||
|
||||
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
|
||||
#endif
|
||||
|
||||
@ -787,7 +793,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
template <typename T>
|
||||
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
|
||||
// Avoid self-assignment.
|
||||
@ -898,7 +904,7 @@ class SmallVector : public SmallVectorImpl<T> {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
|
||||
if (!RHS.empty())
|
||||
SmallVectorImpl<T>::operator=(::std::move(RHS));
|
||||
|
526
contrib/llvm/include/llvm/ADT/SparseMultiSet.h
Normal file
526
contrib/llvm/include/llvm/ADT/SparseMultiSet.h
Normal file
@ -0,0 +1,526 @@
|
||||
//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the SparseMultiSet class, which adds multiset behavior to
|
||||
// the SparseSet.
|
||||
//
|
||||
// A sparse multiset holds a small number of objects identified by integer keys
|
||||
// from a moderately sized universe. The sparse multiset uses more memory than
|
||||
// other containers in order to provide faster operations. Any key can map to
|
||||
// multiple values. A SparseMultiSetNode class is provided, which serves as a
|
||||
// convenient base class for the contents of a SparseMultiSet.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_SPARSEMULTISET_H
|
||||
#define LLVM_ADT_SPARSEMULTISET_H
|
||||
|
||||
#include "llvm/ADT/SparseSet.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Fast multiset implementation for objects that can be identified by small
|
||||
/// unsigned keys.
|
||||
///
|
||||
/// SparseMultiSet allocates memory proportional to the size of the key
|
||||
/// universe, so it is not recommended for building composite data structures.
|
||||
/// It is useful for algorithms that require a single set with fast operations.
|
||||
///
|
||||
/// Compared to DenseSet and DenseMap, SparseMultiSet provides constant-time
|
||||
/// fast clear() as fast as a vector. The find(), insert(), and erase()
|
||||
/// operations are all constant time, and typically faster than a hash table.
|
||||
/// The iteration order doesn't depend on numerical key values, it only depends
|
||||
/// on the order of insert() and erase() operations. Iteration order is the
|
||||
/// insertion order. Iteration is only provided over elements of equivalent
|
||||
/// keys, but iterators are bidirectional.
|
||||
///
|
||||
/// Compared to BitVector, SparseMultiSet<unsigned> uses 8x-40x more memory, but
|
||||
/// offers constant-time clear() and size() operations as well as fast iteration
|
||||
/// independent on the size of the universe.
|
||||
///
|
||||
/// SparseMultiSet contains a dense vector holding all the objects and a sparse
|
||||
/// array holding indexes into the dense vector. Most of the memory is used by
|
||||
/// the sparse array which is the size of the key universe. The SparseT template
|
||||
/// parameter provides a space/speed tradeoff for sets holding many elements.
|
||||
///
|
||||
/// When SparseT is uint32_t, find() only touches up to 3 cache lines, but the
|
||||
/// sparse array uses 4 x Universe bytes.
|
||||
///
|
||||
/// When SparseT is uint8_t (the default), find() touches up to 3+[N/256] cache
|
||||
/// lines, but the sparse array is 4x smaller. N is the number of elements in
|
||||
/// the set.
|
||||
///
|
||||
/// For sets that may grow to thousands of elements, SparseT should be set to
|
||||
/// uint16_t or uint32_t.
|
||||
///
|
||||
/// Multiset behavior is provided by providing doubly linked lists for values
|
||||
/// that are inlined in the dense vector. SparseMultiSet is a good choice when
|
||||
/// one desires a growable number of entries per key, as it will retain the
|
||||
/// SparseSet algorithmic properties despite being growable. Thus, it is often a
|
||||
/// better choice than a SparseSet of growable containers or a vector of
|
||||
/// vectors. SparseMultiSet also keeps iterators valid after erasure (provided
|
||||
/// the iterators don't point to the element erased), allowing for more
|
||||
/// intuitive and fast removal.
|
||||
///
|
||||
/// @tparam ValueT The type of objects in the set.
|
||||
/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
|
||||
/// @tparam SparseT An unsigned integer type. See above.
|
||||
///
|
||||
template<typename ValueT,
|
||||
typename KeyFunctorT = llvm::identity<unsigned>,
|
||||
typename SparseT = uint8_t>
|
||||
class SparseMultiSet {
|
||||
/// The actual data that's stored, as a doubly-linked list implemented via
|
||||
/// indices into the DenseVector. The doubly linked list is implemented
|
||||
/// circular in Prev indices, and INVALID-terminated in Next indices. This
|
||||
/// provides efficient access to list tails. These nodes can also be
|
||||
/// tombstones, in which case they are actually nodes in a single-linked
|
||||
/// freelist of recyclable slots.
|
||||
struct SMSNode {
|
||||
static const unsigned INVALID = ~0U;
|
||||
|
||||
ValueT Data;
|
||||
unsigned Prev;
|
||||
unsigned Next;
|
||||
|
||||
SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { }
|
||||
|
||||
/// List tails have invalid Nexts.
|
||||
bool isTail() const {
|
||||
return Next == INVALID;
|
||||
}
|
||||
|
||||
/// Whether this node is a tombstone node, and thus is in our freelist.
|
||||
bool isTombstone() const {
|
||||
return Prev == INVALID;
|
||||
}
|
||||
|
||||
/// Since the list is circular in Prev, all non-tombstone nodes have a valid
|
||||
/// Prev.
|
||||
bool isValid() const { return Prev != INVALID; }
|
||||
};
|
||||
|
||||
typedef typename KeyFunctorT::argument_type KeyT;
|
||||
typedef SmallVector<SMSNode, 8> DenseT;
|
||||
DenseT Dense;
|
||||
SparseT *Sparse;
|
||||
unsigned Universe;
|
||||
KeyFunctorT KeyIndexOf;
|
||||
SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
|
||||
|
||||
/// We have a built-in recycler for reusing tombstone slots. This recycler
|
||||
/// puts a singly-linked free list into tombstone slots, allowing us quick
|
||||
/// erasure, iterator preservation, and dense size.
|
||||
unsigned FreelistIdx;
|
||||
unsigned NumFree;
|
||||
|
||||
unsigned sparseIndex(const ValueT &Val) const {
|
||||
assert(ValIndexOf(Val) < Universe &&
|
||||
"Invalid key in set. Did object mutate?");
|
||||
return ValIndexOf(Val);
|
||||
}
|
||||
unsigned sparseIndex(const SMSNode &N) const { return sparseIndex(N.Data); }
|
||||
|
||||
// Disable copy construction and assignment.
|
||||
// This data structure is not meant to be used that way.
|
||||
SparseMultiSet(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
|
||||
SparseMultiSet &operator=(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// Whether the given entry is the head of the list. List heads's previous
|
||||
/// pointers are to the tail of the list, allowing for efficient access to the
|
||||
/// list tail. D must be a valid entry node.
|
||||
bool isHead(const SMSNode &D) const {
|
||||
assert(D.isValid() && "Invalid node for head");
|
||||
return Dense[D.Prev].isTail();
|
||||
}
|
||||
|
||||
/// Whether the given entry is a singleton entry, i.e. the only entry with
|
||||
/// that key.
|
||||
bool isSingleton(const SMSNode &N) const {
|
||||
assert(N.isValid() && "Invalid node for singleton");
|
||||
// Is N its own predecessor?
|
||||
return &Dense[N.Prev] == &N;
|
||||
}
|
||||
|
||||
/// Add in the given SMSNode. Uses a free entry in our freelist if
|
||||
/// available. Returns the index of the added node.
|
||||
unsigned addValue(const ValueT& V, unsigned Prev, unsigned Next) {
|
||||
if (NumFree == 0) {
|
||||
Dense.push_back(SMSNode(V, Prev, Next));
|
||||
return Dense.size() - 1;
|
||||
}
|
||||
|
||||
// Peel off a free slot
|
||||
unsigned Idx = FreelistIdx;
|
||||
unsigned NextFree = Dense[Idx].Next;
|
||||
assert(Dense[Idx].isTombstone() && "Non-tombstone free?");
|
||||
|
||||
Dense[Idx] = SMSNode(V, Prev, Next);
|
||||
FreelistIdx = NextFree;
|
||||
--NumFree;
|
||||
return Idx;
|
||||
}
|
||||
|
||||
/// Make the current index a new tombstone. Pushes it onto the freelist.
|
||||
void makeTombstone(unsigned Idx) {
|
||||
Dense[Idx].Prev = SMSNode::INVALID;
|
||||
Dense[Idx].Next = FreelistIdx;
|
||||
FreelistIdx = Idx;
|
||||
++NumFree;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef ValueT value_type;
|
||||
typedef ValueT &reference;
|
||||
typedef const ValueT &const_reference;
|
||||
typedef ValueT *pointer;
|
||||
typedef const ValueT *const_pointer;
|
||||
|
||||
SparseMultiSet()
|
||||
: Sparse(0), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) { }
|
||||
|
||||
~SparseMultiSet() { free(Sparse); }
|
||||
|
||||
/// Set the universe size which determines the largest key the set can hold.
|
||||
/// The universe must be sized before any elements can be added.
|
||||
///
|
||||
/// @param U Universe size. All object keys must be less than U.
|
||||
///
|
||||
void setUniverse(unsigned U) {
|
||||
// It's not hard to resize the universe on a non-empty set, but it doesn't
|
||||
// seem like a likely use case, so we can add that code when we need it.
|
||||
assert(empty() && "Can only resize universe on an empty map");
|
||||
// Hysteresis prevents needless reallocations.
|
||||
if (U >= Universe/4 && U <= Universe)
|
||||
return;
|
||||
free(Sparse);
|
||||
// The Sparse array doesn't actually need to be initialized, so malloc
|
||||
// would be enough here, but that will cause tools like valgrind to
|
||||
// complain about branching on uninitialized data.
|
||||
Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
|
||||
Universe = U;
|
||||
}
|
||||
|
||||
/// Our iterators are iterators over the collection of objects that share a
|
||||
/// key.
|
||||
template<typename SMSPtrTy>
|
||||
class iterator_base : public std::iterator<std::bidirectional_iterator_tag,
|
||||
ValueT> {
|
||||
friend class SparseMultiSet;
|
||||
SMSPtrTy SMS;
|
||||
unsigned Idx;
|
||||
unsigned SparseIdx;
|
||||
|
||||
iterator_base(SMSPtrTy P, unsigned I, unsigned SI)
|
||||
: SMS(P), Idx(I), SparseIdx(SI) { }
|
||||
|
||||
/// Whether our iterator has fallen outside our dense vector.
|
||||
bool isEnd() const {
|
||||
if (Idx == SMSNode::INVALID)
|
||||
return true;
|
||||
|
||||
assert(Idx < SMS->Dense.size() && "Out of range, non-INVALID Idx?");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Whether our iterator is properly keyed, i.e. the SparseIdx is valid
|
||||
bool isKeyed() const { return SparseIdx < SMS->Universe; }
|
||||
|
||||
unsigned Prev() const { return SMS->Dense[Idx].Prev; }
|
||||
unsigned Next() const { return SMS->Dense[Idx].Next; }
|
||||
|
||||
void setPrev(unsigned P) { SMS->Dense[Idx].Prev = P; }
|
||||
void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
|
||||
|
||||
public:
|
||||
typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super;
|
||||
typedef typename super::value_type value_type;
|
||||
typedef typename super::difference_type difference_type;
|
||||
typedef typename super::pointer pointer;
|
||||
typedef typename super::reference reference;
|
||||
|
||||
iterator_base(const iterator_base &RHS)
|
||||
: SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { }
|
||||
|
||||
const iterator_base &operator=(const iterator_base &RHS) {
|
||||
SMS = RHS.SMS;
|
||||
Idx = RHS.Idx;
|
||||
SparseIdx = RHS.SparseIdx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
|
||||
"Dereferencing iterator of invalid key or index");
|
||||
|
||||
return SMS->Dense[Idx].Data;
|
||||
}
|
||||
pointer operator->() const { return &operator*(); }
|
||||
|
||||
/// Comparison operators
|
||||
bool operator==(const iterator_base &RHS) const {
|
||||
// end compares equal
|
||||
if (SMS == RHS.SMS && Idx == RHS.Idx) {
|
||||
assert((isEnd() || SparseIdx == RHS.SparseIdx) &&
|
||||
"Same dense entry, but different keys?");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator_base &RHS) const {
|
||||
return !operator==(RHS);
|
||||
}
|
||||
|
||||
/// Increment and decrement operators
|
||||
iterator_base &operator--() { // predecrement - Back up
|
||||
assert(isKeyed() && "Decrementing an invalid iterator");
|
||||
assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) &&
|
||||
"Decrementing head of list");
|
||||
|
||||
// If we're at the end, then issue a new find()
|
||||
if (isEnd())
|
||||
Idx = SMS->findIndex(SparseIdx).Prev();
|
||||
else
|
||||
Idx = Prev();
|
||||
|
||||
return *this;
|
||||
}
|
||||
iterator_base &operator++() { // preincrement - Advance
|
||||
assert(!isEnd() && isKeyed() && "Incrementing an invalid/end iterator");
|
||||
Idx = Next();
|
||||
return *this;
|
||||
}
|
||||
iterator_base operator--(int) { // postdecrement
|
||||
iterator_base I(*this);
|
||||
--*this;
|
||||
return I;
|
||||
}
|
||||
iterator_base operator++(int) { // postincrement
|
||||
iterator_base I(*this);
|
||||
++*this;
|
||||
return I;
|
||||
}
|
||||
};
|
||||
typedef iterator_base<SparseMultiSet *> iterator;
|
||||
typedef iterator_base<const SparseMultiSet *> const_iterator;
|
||||
|
||||
// Convenience types
|
||||
typedef std::pair<iterator, iterator> RangePair;
|
||||
|
||||
/// Returns an iterator past this container. Note that such an iterator cannot
|
||||
/// be decremented, but will compare equal to other end iterators.
|
||||
iterator end() { return iterator(this, SMSNode::INVALID, SMSNode::INVALID); }
|
||||
const_iterator end() const {
|
||||
return const_iterator(this, SMSNode::INVALID, SMSNode::INVALID);
|
||||
}
|
||||
|
||||
/// Returns true if the set is empty.
|
||||
///
|
||||
/// This is not the same as BitVector::empty().
|
||||
///
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/// Returns the number of elements in the set.
|
||||
///
|
||||
/// This is not the same as BitVector::size() which returns the size of the
|
||||
/// universe.
|
||||
///
|
||||
unsigned size() const {
|
||||
assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
|
||||
return Dense.size() - NumFree;
|
||||
}
|
||||
|
||||
/// Clears the set. This is a very fast constant time operation.
|
||||
///
|
||||
void clear() {
|
||||
// Sparse does not need to be cleared, see find().
|
||||
Dense.clear();
|
||||
NumFree = 0;
|
||||
FreelistIdx = SMSNode::INVALID;
|
||||
}
|
||||
|
||||
/// Find an element by its index.
|
||||
///
|
||||
/// @param Idx A valid index to find.
|
||||
/// @returns An iterator to the element identified by key, or end().
|
||||
///
|
||||
iterator findIndex(unsigned Idx) {
|
||||
assert(Idx < Universe && "Key out of range");
|
||||
assert(std::numeric_limits<SparseT>::is_integer &&
|
||||
!std::numeric_limits<SparseT>::is_signed &&
|
||||
"SparseT must be an unsigned integer type");
|
||||
const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
|
||||
for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
|
||||
const unsigned FoundIdx = sparseIndex(Dense[i]);
|
||||
// Check that we're pointing at the correct entry and that it is the head
|
||||
// of a valid list.
|
||||
if (Idx == FoundIdx && Dense[i].isValid() && isHead(Dense[i]))
|
||||
return iterator(this, i, Idx);
|
||||
// Stride is 0 when SparseT >= unsigned. We don't need to loop.
|
||||
if (!Stride)
|
||||
break;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
/// Find an element by its key.
|
||||
///
|
||||
/// @param Key A valid key to find.
|
||||
/// @returns An iterator to the element identified by key, or end().
|
||||
///
|
||||
iterator find(const KeyT &Key) {
|
||||
return findIndex(KeyIndexOf(Key));
|
||||
}
|
||||
|
||||
const_iterator find(const KeyT &Key) const {
|
||||
iterator I = const_cast<SparseMultiSet*>(this)->findIndex(KeyIndexOf(Key));
|
||||
return const_iterator(I.SMS, I.Idx, KeyIndexOf(Key));
|
||||
}
|
||||
|
||||
/// Returns the number of elements identified by Key. This will be linear in
|
||||
/// the number of elements of that key.
|
||||
unsigned count(const KeyT &Key) const {
|
||||
unsigned Ret = 0;
|
||||
for (const_iterator It = find(Key); It != end(); ++It)
|
||||
++Ret;
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/// Returns true if this set contains an element identified by Key.
|
||||
bool contains(const KeyT &Key) const {
|
||||
return find(Key) != end();
|
||||
}
|
||||
|
||||
/// Return the head and tail of the subset's list, otherwise returns end().
|
||||
iterator getHead(const KeyT &Key) { return find(Key); }
|
||||
iterator getTail(const KeyT &Key) {
|
||||
iterator I = find(Key);
|
||||
if (I != end())
|
||||
I = iterator(this, I.Prev(), KeyIndexOf(Key));
|
||||
return I;
|
||||
}
|
||||
|
||||
/// The bounds of the range of items sharing Key K. First member is the head
|
||||
/// of the list, and the second member is a decrementable end iterator for
|
||||
/// that key.
|
||||
RangePair equal_range(const KeyT &K) {
|
||||
iterator B = find(K);
|
||||
iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
|
||||
return make_pair(B, E);
|
||||
}
|
||||
|
||||
/// Insert a new element at the tail of the subset list. Returns an iterator
|
||||
/// to the newly added entry.
|
||||
iterator insert(const ValueT &Val) {
|
||||
unsigned Idx = sparseIndex(Val);
|
||||
iterator I = findIndex(Idx);
|
||||
|
||||
unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID);
|
||||
|
||||
if (I == end()) {
|
||||
// Make a singleton list
|
||||
Sparse[Idx] = NodeIdx;
|
||||
Dense[NodeIdx].Prev = NodeIdx;
|
||||
return iterator(this, NodeIdx, Idx);
|
||||
}
|
||||
|
||||
// Stick it at the end.
|
||||
unsigned HeadIdx = I.Idx;
|
||||
unsigned TailIdx = I.Prev();
|
||||
Dense[TailIdx].Next = NodeIdx;
|
||||
Dense[HeadIdx].Prev = NodeIdx;
|
||||
Dense[NodeIdx].Prev = TailIdx;
|
||||
|
||||
return iterator(this, NodeIdx, Idx);
|
||||
}
|
||||
|
||||
/// Erases an existing element identified by a valid iterator.
|
||||
///
|
||||
/// This invalidates iterators pointing at the same entry, but erase() returns
|
||||
/// an iterator pointing to the next element in the subset's list. This makes
|
||||
/// it possible to erase selected elements while iterating over the subset:
|
||||
///
|
||||
/// tie(I, E) = Set.equal_range(Key);
|
||||
/// while (I != E)
|
||||
/// if (test(*I))
|
||||
/// I = Set.erase(I);
|
||||
/// else
|
||||
/// ++I;
|
||||
///
|
||||
/// Note that if the last element in the subset list is erased, this will
|
||||
/// return an end iterator which can be decremented to get the new tail (if it
|
||||
/// exists):
|
||||
///
|
||||
/// tie(B, I) = Set.equal_range(Key);
|
||||
/// for (bool isBegin = B == I; !isBegin; /* empty */) {
|
||||
/// isBegin = (--I) == B;
|
||||
/// if (test(I))
|
||||
/// break;
|
||||
/// I = erase(I);
|
||||
/// }
|
||||
iterator erase(iterator I) {
|
||||
assert(I.isKeyed() && !I.isEnd() && !Dense[I.Idx].isTombstone() &&
|
||||
"erasing invalid/end/tombstone iterator");
|
||||
|
||||
// First, unlink the node from its list. Then swap the node out with the
|
||||
// dense vector's last entry
|
||||
iterator NextI = unlink(Dense[I.Idx]);
|
||||
|
||||
// Put in a tombstone.
|
||||
makeTombstone(I.Idx);
|
||||
|
||||
return NextI;
|
||||
}
|
||||
|
||||
/// Erase all elements with the given key. This invalidates all
|
||||
/// iterators of that key.
|
||||
void eraseAll(const KeyT &K) {
|
||||
for (iterator I = find(K); I != end(); /* empty */)
|
||||
I = erase(I);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Unlink the node from its list. Returns the next node in the list.
|
||||
iterator unlink(const SMSNode &N) {
|
||||
if (isSingleton(N)) {
|
||||
// Singleton is already unlinked
|
||||
assert(N.Next == SMSNode::INVALID && "Singleton has next?");
|
||||
return iterator(this, SMSNode::INVALID, ValIndexOf(N.Data));
|
||||
}
|
||||
|
||||
if (isHead(N)) {
|
||||
// If we're the head, then update the sparse array and our next.
|
||||
Sparse[sparseIndex(N)] = N.Next;
|
||||
Dense[N.Next].Prev = N.Prev;
|
||||
return iterator(this, N.Next, ValIndexOf(N.Data));
|
||||
}
|
||||
|
||||
if (N.isTail()) {
|
||||
// If we're the tail, then update our head and our previous.
|
||||
findIndex(sparseIndex(N)).setPrev(N.Prev);
|
||||
Dense[N.Prev].Next = N.Next;
|
||||
|
||||
// Give back an end iterator that can be decremented
|
||||
iterator I(this, N.Prev, ValIndexOf(N.Data));
|
||||
return ++I;
|
||||
}
|
||||
|
||||
// Otherwise, just drop us
|
||||
Dense[N.Next].Prev = N.Prev;
|
||||
Dense[N.Prev].Next = N.Next;
|
||||
return iterator(this, N.Next, ValIndexOf(N.Data));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -20,8 +20,8 @@
|
||||
#ifndef LLVM_ADT_SPARSESET_H
|
||||
#define LLVM_ADT_SPARSESET_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <limits>
|
||||
|
||||
|
@ -51,7 +51,9 @@ class Statistic {
|
||||
|
||||
// Allow use of this class as the value itself.
|
||||
operator unsigned() const { return Value; }
|
||||
const Statistic &operator=(unsigned Val) {
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
||||
const Statistic &operator=(unsigned Val) {
|
||||
Value = Val;
|
||||
return init();
|
||||
}
|
||||
@ -106,6 +108,46 @@ class Statistic {
|
||||
return init();
|
||||
}
|
||||
|
||||
#else // Statistics are disabled in release builds.
|
||||
|
||||
const Statistic &operator=(unsigned Val) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Statistic &operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned operator++(int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Statistic &operator--() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned operator--(int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Statistic &operator+=(const unsigned &V) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Statistic &operator-=(const unsigned &V) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Statistic &operator*=(const unsigned &V) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Statistic &operator/=(const unsigned &V) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
||||
|
||||
protected:
|
||||
Statistic &init() {
|
||||
bool tmp = Initialized;
|
||||
|
@ -14,8 +14,8 @@
|
||||
#ifndef LLVM_ADT_STRINGEXTRAS_H
|
||||
#define LLVM_ADT_STRINGEXTRAS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename T> class SmallVectorImpl;
|
||||
@ -27,6 +27,17 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) {
|
||||
return X < 10 ? '0' + X : HexChar + X - 10;
|
||||
}
|
||||
|
||||
/// Interpret the given character \p C as a hexadecimal digit and return its
|
||||
/// value.
|
||||
///
|
||||
/// If \p C is not a valid hex digit, -1U is returned.
|
||||
static inline unsigned hexDigitValue(char C) {
|
||||
if (C >= '0' && C <= '9') return C-'0';
|
||||
if (C >= 'a' && C <= 'f') return C-'a'+10U;
|
||||
if (C >= 'A' && C <= 'F') return C-'A'+10U;
|
||||
return -1U;
|
||||
}
|
||||
|
||||
/// utohex_buffer - Emit the specified number into the buffer specified by
|
||||
/// BufferEnd, returning a pointer to the start of the string. This can be used
|
||||
/// like this: (note that the buffer must be large enough to handle any number):
|
||||
|
@ -53,7 +53,7 @@ class StringMapEntryBase {
|
||||
class StringMapImpl {
|
||||
protected:
|
||||
// Array of NumBuckets pointers to entries, null pointers are holes.
|
||||
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed
|
||||
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
|
||||
// by an array of the actual hash values as unsigned integers.
|
||||
StringMapEntryBase **TheTable;
|
||||
unsigned NumBuckets;
|
||||
@ -171,7 +171,6 @@ class StringMapEntry : public StringMapEntryBase {
|
||||
return Create(KeyStart, KeyEnd, Allocator, 0);
|
||||
}
|
||||
|
||||
|
||||
/// Create - Create a StringMapEntry with normal malloc/free.
|
||||
template<typename InitType>
|
||||
static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
|
||||
@ -204,7 +203,6 @@ class StringMapEntry : public StringMapEntryBase {
|
||||
return *reinterpret_cast<StringMapEntry*>(Ptr);
|
||||
}
|
||||
|
||||
|
||||
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
|
||||
/// specified allocator.
|
||||
template<typename AllocatorTy>
|
||||
@ -239,6 +237,10 @@ class StringMap : public StringMapImpl {
|
||||
explicit StringMap(AllocatorTy A)
|
||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
|
||||
|
||||
StringMap(unsigned InitialSize, AllocatorTy A)
|
||||
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
|
||||
Allocator(A) {}
|
||||
|
||||
StringMap(const StringMap &RHS)
|
||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
|
||||
assert(RHS.empty() &&
|
||||
@ -290,7 +292,7 @@ class StringMap : public StringMapImpl {
|
||||
return const_iterator(TheTable+Bucket, true);
|
||||
}
|
||||
|
||||
/// lookup - Return the entry for the specified key, or a default
|
||||
/// lookup - Return the entry for the specified key, or a default
|
||||
/// constructed value if no such entry exists.
|
||||
ValueTy lookup(StringRef Key) const {
|
||||
const_iterator it = find(Key);
|
||||
@ -336,8 +338,8 @@ class StringMap : public StringMapImpl {
|
||||
StringMapEntryBase *&Bucket = TheTable[I];
|
||||
if (Bucket && Bucket != getTombstoneVal()) {
|
||||
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
|
||||
Bucket = 0;
|
||||
}
|
||||
Bucket = 0;
|
||||
}
|
||||
|
||||
NumItems = 0;
|
||||
@ -427,7 +429,7 @@ class StringMapConstIterator {
|
||||
return Ptr != RHS.Ptr;
|
||||
}
|
||||
|
||||
inline StringMapConstIterator& operator++() { // Preincrement
|
||||
inline StringMapConstIterator& operator++() { // Preincrement
|
||||
++Ptr;
|
||||
AdvancePastEmptyBuckets();
|
||||
return *this;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define LLVM_ADT_STRINGREF_H
|
||||
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
@ -58,14 +57,14 @@ namespace llvm {
|
||||
// integer works around this bug.
|
||||
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
|
||||
static size_t max(size_t a, size_t b) { return a > b ? a : b; }
|
||||
|
||||
|
||||
// Workaround memcmp issue with null pointers (undefined behavior)
|
||||
// by providing a specialized version
|
||||
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
|
||||
if (Length == 0) { return 0; }
|
||||
return ::memcmp(Lhs,Rhs,Length);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
@ -388,7 +387,7 @@ namespace llvm {
|
||||
Start = min(Start, Length);
|
||||
return StringRef(Data + Start, min(N, Length - Start));
|
||||
}
|
||||
|
||||
|
||||
/// Return a StringRef equal to 'this' but with the first \p N elements
|
||||
/// dropped.
|
||||
StringRef drop_front(unsigned N = 1) const {
|
||||
@ -536,7 +535,7 @@ namespace llvm {
|
||||
return LHS.compare(RHS) != -1;
|
||||
}
|
||||
|
||||
inline std::string &operator+=(std::string &buffer, llvm::StringRef string) {
|
||||
inline std::string &operator+=(std::string &buffer, StringRef string) {
|
||||
return buffer.append(string.data(), string.size());
|
||||
}
|
||||
|
||||
|
@ -18,23 +18,25 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// StringSet - A wrapper for StringMap that provides set-like
|
||||
/// functionality. Only insert() and count() methods are used by my
|
||||
/// code.
|
||||
/// StringSet - A wrapper for StringMap that provides set-like functionality.
|
||||
template <class AllocatorTy = llvm::MallocAllocator>
|
||||
class StringSet : public llvm::StringMap<char, AllocatorTy> {
|
||||
typedef llvm::StringMap<char, AllocatorTy> base;
|
||||
public:
|
||||
bool insert(StringRef InLang) {
|
||||
assert(!InLang.empty());
|
||||
const char *KeyStart = InLang.data();
|
||||
const char *KeyEnd = KeyStart + InLang.size();
|
||||
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
|
||||
Create(KeyStart, KeyEnd, base::getAllocator(), '+');
|
||||
if (!base::insert(Entry)) {
|
||||
Entry->Destroy(base::getAllocator());
|
||||
|
||||
/// insert - Insert the specified key into the set. If the key already
|
||||
/// exists in the set, return false and ignore the request, otherwise insert
|
||||
/// it and return true.
|
||||
bool insert(StringRef Key) {
|
||||
// Get or create the map entry for the key; if it doesn't exist the value
|
||||
// type will be default constructed which we use to detect insert.
|
||||
//
|
||||
// We use '+' as the sentinel value in the map.
|
||||
assert(!Key.empty());
|
||||
StringMapEntry<char> &Entry = this->GetOrCreateValue(Key);
|
||||
if (Entry.getValue() == '+')
|
||||
return false;
|
||||
}
|
||||
Entry.setValue('+');
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -70,7 +70,7 @@ class TinyPtrVector {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_USE_RVALUE_REFERENCES
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
|
||||
RHS.Val = (EltTy)0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Triple {
|
||||
UnknownArch,
|
||||
|
||||
arm, // ARM; arm, armv.*, xscale
|
||||
cellspu, // CellSPU: spu, cellspu
|
||||
aarch64, // AArch64: aarch64
|
||||
hexagon, // Hexagon: hexagon
|
||||
mips, // MIPS: mips, mipsallegrex
|
||||
mipsel, // MIPSEL: mipsel, mipsallegrexel
|
||||
@ -101,8 +101,8 @@ class Triple {
|
||||
Haiku,
|
||||
Minix,
|
||||
RTEMS,
|
||||
NativeClient,
|
||||
CNK, // BG/P Compute-Node Kernel
|
||||
NaCl, // Native Client
|
||||
CNK, // BG/P Compute-Node Kernel
|
||||
Bitrig,
|
||||
AIX
|
||||
};
|
||||
@ -112,6 +112,7 @@ class Triple {
|
||||
GNU,
|
||||
GNUEABI,
|
||||
GNUEABIHF,
|
||||
GNUX32,
|
||||
EABI,
|
||||
MachO,
|
||||
Android,
|
||||
@ -296,9 +297,14 @@ class Triple {
|
||||
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
|
||||
}
|
||||
|
||||
/// Is this an iOS triple.
|
||||
bool isiOS() const {
|
||||
return getOS() == Triple::IOS;
|
||||
}
|
||||
|
||||
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
|
||||
bool isOSDarwin() const {
|
||||
return isMacOSX() || getOS() == Triple::IOS;
|
||||
return isMacOSX() || isiOS();
|
||||
}
|
||||
|
||||
/// \brief Tests for either Cygwin or MinGW OS
|
||||
@ -311,6 +317,11 @@ class Triple {
|
||||
return getOS() == Triple::Win32 || isOSCygMing();
|
||||
}
|
||||
|
||||
/// \brief Tests whether the OS is NaCl (Native Client)
|
||||
bool isOSNaCl() const {
|
||||
return getOS() == Triple::NaCl;
|
||||
}
|
||||
|
||||
/// \brief Tests whether the OS uses the ELF binary format.
|
||||
bool isOSBinFormatELF() const {
|
||||
return !isOSDarwin() && !isOSWindows();
|
||||
|
@ -27,10 +27,9 @@
|
||||
#define LLVM_ADT_VALUEMAP_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
|
||||
#define LLVM_ADT_VARIADIC_FUNCTION_H
|
||||
#ifndef LLVM_ADT_VARIADICFUNCTION_H
|
||||
#define LLVM_ADT_VARIADICFUNCTION_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
@ -328,4 +328,4 @@ struct VariadicFunction3 {
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_ADT_VARIADIC_FUNCTION_H
|
||||
#endif // LLVM_ADT_VARIADICFUNCTION_H
|
||||
|
@ -234,17 +234,17 @@ class ilist_iterator
|
||||
pointer getNodePtrUnchecked() const { return NodePtr; }
|
||||
};
|
||||
|
||||
// do not implement. this is to catch errors when people try to use
|
||||
// them as random access iterators
|
||||
// These are to catch errors when people try to use them as random access
|
||||
// iterators.
|
||||
template<typename T>
|
||||
void operator-(int, ilist_iterator<T>);
|
||||
void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
|
||||
template<typename T>
|
||||
void operator-(ilist_iterator<T>,int);
|
||||
void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
|
||||
|
||||
template<typename T>
|
||||
void operator+(int, ilist_iterator<T>);
|
||||
void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
|
||||
template<typename T>
|
||||
void operator+(ilist_iterator<T>,int);
|
||||
void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
|
||||
|
||||
// operator!=/operator== - Allow mixed comparisons without dereferencing
|
||||
// the iterator, which could very likely be pointing to end().
|
||||
@ -274,12 +274,12 @@ template<typename From> struct simplify_type;
|
||||
template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
|
||||
typedef NodeTy* SimpleType;
|
||||
|
||||
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
|
||||
static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
|
||||
return &*Node;
|
||||
}
|
||||
};
|
||||
template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
|
||||
typedef NodeTy* SimpleType;
|
||||
typedef /*const*/ NodeTy* SimpleType;
|
||||
|
||||
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
|
||||
return &*Node;
|
||||
@ -465,6 +465,17 @@ class iplist : public Traits {
|
||||
return where;
|
||||
}
|
||||
|
||||
/// Remove all nodes from the list like clear(), but do not call
|
||||
/// removeNodeFromList() or deleteNode().
|
||||
///
|
||||
/// This should only be used immediately before freeing nodes in bulk to
|
||||
/// avoid traversing the list and bringing all the nodes into cache.
|
||||
void clearAndLeakNodesUnsafely() {
|
||||
if (Head) {
|
||||
Head = getTail();
|
||||
this->setPrev(Head, Head);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// transfer - The heart of the splice function. Move linked list nodes from
|
||||
@ -472,6 +483,10 @@ class iplist : public Traits {
|
||||
//
|
||||
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
|
||||
assert(first != last && "Should be checked by callers");
|
||||
// Position cannot be contained in the range to be transferred.
|
||||
// Check for the most common mistake.
|
||||
assert(position != first &&
|
||||
"Insertion point can't be one of the transferred nodes");
|
||||
|
||||
if (position != last) {
|
||||
// Note: we have to be careful about the case when we move the first node
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_ILIST_NODE_H
|
||||
#define LLVM_ADT_ILIST_NODE_H
|
||||
#ifndef LLVM_ADT_ILISTNODE_H
|
||||
#define LLVM_ADT_ILISTNODE_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
//===--------- llvm/AddressingMode.h - Addressing Mode -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This file contains addressing mode data structures which are shared
|
||||
// between LSR and a number of places in the codegen.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADDRESSING_MODE_H
|
||||
#define LLVM_ADDRESSING_MODE_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class GlobalValue;
|
||||
|
||||
/// AddrMode - This represents an addressing mode of:
|
||||
/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
|
||||
/// If BaseGV is null, there is no BaseGV.
|
||||
/// If BaseOffs is zero, there is no base offset.
|
||||
/// If HasBaseReg is false, there is no base register.
|
||||
/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
|
||||
/// no scale.
|
||||
///
|
||||
struct AddrMode {
|
||||
GlobalValue *BaseGV;
|
||||
int64_t BaseOffs;
|
||||
bool HasBaseReg;
|
||||
int64_t Scale;
|
||||
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -34,11 +34,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
|
||||
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
|
||||
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
|
||||
#define LLVM_ANALYSIS_ALIASANALYSIS_H
|
||||
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -373,7 +373,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(I, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for call sites) - Return whether information about whether
|
||||
/// getModRefInfo (for call sites) - Return information about whether
|
||||
/// a particular call site modifies or reads the specified memory location.
|
||||
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
|
||||
const Location &Loc);
|
||||
@ -384,7 +384,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(CS, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for calls) - Return whether information about whether
|
||||
/// getModRefInfo (for calls) - Return information about whether
|
||||
/// a particular call modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
|
||||
return getModRefInfo(ImmutableCallSite(C), Loc);
|
||||
@ -395,7 +395,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(C, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for invokes) - Return whether information about whether
|
||||
/// getModRefInfo (for invokes) - Return information about whether
|
||||
/// a particular invoke modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const InvokeInst *I,
|
||||
const Location &Loc) {
|
||||
@ -408,7 +408,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(I, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for loads) - Return whether information about whether
|
||||
/// getModRefInfo (for loads) - Return information about whether
|
||||
/// a particular load modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
|
||||
|
||||
@ -417,7 +417,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(L, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for stores) - Return whether information about whether
|
||||
/// getModRefInfo (for stores) - Return information about whether
|
||||
/// a particular store modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
|
||||
|
||||
@ -426,7 +426,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(S, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for fences) - Return whether information about whether
|
||||
/// getModRefInfo (for fences) - Return information about whether
|
||||
/// a particular store modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
|
||||
// Conservatively correct. (We could possibly be a bit smarter if
|
||||
@ -439,7 +439,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(S, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for cmpxchges) - Return whether information about whether
|
||||
/// getModRefInfo (for cmpxchges) - Return information about whether
|
||||
/// a particular cmpxchg modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
|
||||
|
||||
@ -449,7 +449,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(CX, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for atomicrmws) - Return whether information about whether
|
||||
/// getModRefInfo (for atomicrmws) - Return information about whether
|
||||
/// a particular atomicrmw modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
|
||||
|
||||
@ -459,7 +459,7 @@ class AliasAnalysis {
|
||||
return getModRefInfo(RMW, Location(P, Size));
|
||||
}
|
||||
|
||||
/// getModRefInfo (for va_args) - Return whether information about whether
|
||||
/// getModRefInfo (for va_args) - Return information about whether
|
||||
/// a particular va_arg modifies or reads the specified memory location.
|
||||
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
|
||||
|
||||
@ -587,17 +587,12 @@ bool isNoAliasCall(const Value *V);
|
||||
/// isIdentifiedObject - Return true if this pointer refers to a distinct and
|
||||
/// identifiable object. This returns true for:
|
||||
/// Global Variables and Functions (but not Global Aliases)
|
||||
/// Allocas and Mallocs
|
||||
/// Allocas
|
||||
/// ByVal and NoAlias Arguments
|
||||
/// NoAlias returns
|
||||
/// NoAlias returns (e.g. calls to malloc)
|
||||
///
|
||||
bool isIdentifiedObject(const Value *V);
|
||||
|
||||
/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
|
||||
/// its definition. This returns true for allocas, non-extern-weak globals and
|
||||
/// byval arguments.
|
||||
bool isKnownNonNull(const Value *V);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -17,11 +17,10 @@
|
||||
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
|
||||
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
|
||||
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -14,17 +14,17 @@
|
||||
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
||||
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/Support/BlockFrequency.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -271,7 +271,7 @@ class BlockFrequencyImpl {
|
||||
|
||||
BlockT *EntryBlock = fn->begin();
|
||||
|
||||
copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
|
||||
std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT));
|
||||
|
||||
unsigned RPOidx = 0;
|
||||
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
|
||||
|
@ -14,10 +14,10 @@
|
||||
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
|
||||
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
|
||||
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -15,10 +15,10 @@
|
||||
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
|
||||
#define LLVM_ANALYSIS_CFGPRINTER_H
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/GraphWriter.h"
|
||||
|
||||
|
@ -51,13 +51,13 @@
|
||||
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
|
||||
#define LLVM_ANALYSIS_CALLGRAPH_H
|
||||
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Support/IncludeFile.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -18,11 +18,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
|
||||
#define LLVM_CALL_GRAPH_SCC_PASS_H
|
||||
#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
|
||||
#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -39,6 +39,9 @@ class CallGraphSCCPass : public Pass {
|
||||
/// corresponding to a CallGraph.
|
||||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
|
||||
|
||||
using llvm::Pass::doInitialization;
|
||||
using llvm::Pass::doFinalization;
|
||||
|
||||
/// doInitialization - This method is called before the SCC's of the program
|
||||
/// has been processed, allowing the pass to do initialization as necessary.
|
||||
virtual bool doInitialization(CallGraph &CG) {
|
27
contrib/llvm/include/llvm/Analysis/CallPrinter.h
Normal file
27
contrib/llvm/include/llvm/Analysis/CallPrinter.h
Normal file
@ -0,0 +1,27 @@
|
||||
//===-- CallPrinter.h - Call graph printer external interface ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines external functions that can be called to explicitly
|
||||
// instantiate the call graph printer.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_CALLPRINTER_H
|
||||
#define LLVM_ANALYSIS_CALLPRINTER_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ModulePass;
|
||||
|
||||
ModulePass *createCallGraphViewerPass();
|
||||
ModulePass *createCallGraphPrinterPass();
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -14,12 +14,11 @@
|
||||
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
|
||||
#define LLVM_ANALYSIS_CAPTURETRACKING_H
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Value;
|
||||
class Use;
|
||||
|
||||
/// PointerMayBeCaptured - Return true if this pointer value may be captured
|
||||
/// by the enclosing function (which is required to exist). This routine can
|
||||
/// be expensive, so consider caching the results. The boolean ReturnCaptures
|
||||
|
@ -19,77 +19,75 @@
|
||||
#include "llvm/Support/CallSite.h"
|
||||
|
||||
namespace llvm {
|
||||
class BasicBlock;
|
||||
class Function;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
class Value;
|
||||
class BasicBlock;
|
||||
class Function;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
class TargetTransformInfo;
|
||||
class Value;
|
||||
|
||||
/// \brief Check whether an instruction is likely to be "free" when lowered.
|
||||
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
|
||||
/// \brief Check whether a call will lower to something small.
|
||||
///
|
||||
/// This tests checks whether this callsite will lower to something
|
||||
/// significantly cheaper than a traditional call, often a single
|
||||
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
|
||||
/// return true, so will this function.
|
||||
bool callIsSmall(ImmutableCallSite CS);
|
||||
|
||||
/// \brief Check whether a call will lower to something small.
|
||||
/// \brief Utility to calculate the size and a few similar metrics for a set
|
||||
/// of basic blocks.
|
||||
struct CodeMetrics {
|
||||
/// \brief True if this function contains a call to setjmp or other functions
|
||||
/// with attribute "returns twice" without having the attribute itself.
|
||||
bool exposesReturnsTwice;
|
||||
|
||||
/// \brief True if this function calls itself.
|
||||
bool isRecursive;
|
||||
|
||||
/// \brief True if this function cannot be duplicated.
|
||||
///
|
||||
/// This tests checks whether this callsite will lower to something
|
||||
/// significantly cheaper than a traditional call, often a single
|
||||
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
|
||||
/// return true, so will this function.
|
||||
bool callIsSmall(ImmutableCallSite CS);
|
||||
/// True if this function contains one or more indirect branches, or it contains
|
||||
/// one or more 'noduplicate' instructions.
|
||||
bool notDuplicatable;
|
||||
|
||||
/// \brief Utility to calculate the size and a few similar metrics for a set
|
||||
/// of basic blocks.
|
||||
struct CodeMetrics {
|
||||
/// \brief True if this function contains a call to setjmp or other functions
|
||||
/// with attribute "returns twice" without having the attribute itself.
|
||||
bool exposesReturnsTwice;
|
||||
/// \brief True if this function calls alloca (in the C sense).
|
||||
bool usesDynamicAlloca;
|
||||
|
||||
/// \brief True if this function calls itself.
|
||||
bool isRecursive;
|
||||
/// \brief Number of instructions in the analyzed blocks.
|
||||
unsigned NumInsts;
|
||||
|
||||
/// \brief True if this function contains one or more indirect branches.
|
||||
bool containsIndirectBr;
|
||||
/// \brief Number of analyzed blocks.
|
||||
unsigned NumBlocks;
|
||||
|
||||
/// \brief True if this function calls alloca (in the C sense).
|
||||
bool usesDynamicAlloca;
|
||||
/// \brief Keeps track of basic block code size estimates.
|
||||
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
|
||||
|
||||
/// \brief Number of instructions in the analyzed blocks.
|
||||
unsigned NumInsts;
|
||||
/// \brief Keep track of the number of calls to 'big' functions.
|
||||
unsigned NumCalls;
|
||||
|
||||
/// \brief Number of analyzed blocks.
|
||||
unsigned NumBlocks;
|
||||
/// \brief The number of calls to internal functions with a single caller.
|
||||
///
|
||||
/// These are likely targets for future inlining, likely exposed by
|
||||
/// interleaved devirtualization.
|
||||
unsigned NumInlineCandidates;
|
||||
|
||||
/// \brief Keeps track of basic block code size estimates.
|
||||
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
|
||||
/// \brief How many instructions produce vector values.
|
||||
///
|
||||
/// The inliner is more aggressive with inlining vector kernels.
|
||||
unsigned NumVectorInsts;
|
||||
|
||||
/// \brief Keep track of the number of calls to 'big' functions.
|
||||
unsigned NumCalls;
|
||||
/// \brief How many 'ret' instructions the blocks contain.
|
||||
unsigned NumRets;
|
||||
|
||||
/// \brief The number of calls to internal functions with a single caller.
|
||||
///
|
||||
/// These are likely targets for future inlining, likely exposed by
|
||||
/// interleaved devirtualization.
|
||||
unsigned NumInlineCandidates;
|
||||
CodeMetrics()
|
||||
: exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
|
||||
usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
|
||||
NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
|
||||
|
||||
/// \brief How many instructions produce vector values.
|
||||
///
|
||||
/// The inliner is more aggressive with inlining vector kernels.
|
||||
unsigned NumVectorInsts;
|
||||
/// \brief Add information about a block to the current state.
|
||||
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
|
||||
};
|
||||
|
||||
/// \brief How many 'ret' instructions the blocks contain.
|
||||
unsigned NumRets;
|
||||
|
||||
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
|
||||
containsIndirectBr(false), usesDynamicAlloca(false),
|
||||
NumInsts(0), NumBlocks(0), NumCalls(0),
|
||||
NumInlineCandidates(0), NumVectorInsts(0),
|
||||
NumRets(0) {}
|
||||
|
||||
/// \brief Add information about a block to the current state.
|
||||
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
|
||||
|
||||
/// \brief Add information about a function to the current state.
|
||||
void analyzeFunction(Function *F, const DataLayout *TD = 0);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -11,27 +11,25 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
|
||||
#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
|
||||
#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
|
||||
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/CFGPrinter.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
namespace llvm {
|
||||
template <class Analysis, bool Simple>
|
||||
struct DOTGraphTraitsViewer : public FunctionPass {
|
||||
std::string Name;
|
||||
|
||||
DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
|
||||
Name = GraphName;
|
||||
}
|
||||
template <class Analysis, bool Simple>
|
||||
class DOTGraphTraitsViewer : public FunctionPass {
|
||||
public:
|
||||
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
|
||||
: FunctionPass(ID), Name(GraphName) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
Analysis *Graph;
|
||||
std::string Title, GraphName;
|
||||
Graph = &getAnalysis<Analysis>();
|
||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||
Analysis *Graph = &getAnalysis<Analysis>();
|
||||
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||
|
||||
ViewGraph(Graph, Name, Simple, Title);
|
||||
|
||||
return false;
|
||||
@ -41,36 +39,34 @@ struct DOTGraphTraitsViewer : public FunctionPass {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<Analysis>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
template <class Analysis, bool Simple>
|
||||
struct DOTGraphTraitsPrinter : public FunctionPass {
|
||||
|
||||
std::string Name;
|
||||
|
||||
DOTGraphTraitsPrinter(std::string GraphName, char &ID)
|
||||
: FunctionPass(ID) {
|
||||
Name = GraphName;
|
||||
}
|
||||
class DOTGraphTraitsPrinter : public FunctionPass {
|
||||
public:
|
||||
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
|
||||
: FunctionPass(ID), Name(GraphName) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
Analysis *Graph;
|
||||
Analysis *Graph = &getAnalysis<Analysis>();
|
||||
std::string Filename = Name + "." + F.getName().str() + ".dot";
|
||||
std::string ErrorInfo;
|
||||
|
||||
errs() << "Writing '" << Filename << "'...";
|
||||
|
||||
std::string ErrorInfo;
|
||||
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
|
||||
Graph = &getAnalysis<Analysis>();
|
||||
|
||||
std::string Title, GraphName;
|
||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||
|
||||
if (ErrorInfo.empty())
|
||||
WriteGraph(File, Graph, Simple, Title);
|
||||
else
|
||||
errs() << " error opening file for writing!";
|
||||
errs() << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -78,6 +74,69 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<Analysis>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Analysis, bool Simple>
|
||||
class DOTGraphTraitsModuleViewer : public ModulePass {
|
||||
public:
|
||||
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
|
||||
: ModulePass(ID), Name(GraphName) {}
|
||||
|
||||
virtual bool runOnModule(Module &M) {
|
||||
Analysis *Graph = &getAnalysis<Analysis>();
|
||||
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
|
||||
ViewGraph(Graph, Name, Simple, Title);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<Analysis>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
template <class Analysis, bool Simple>
|
||||
class DOTGraphTraitsModulePrinter : public ModulePass {
|
||||
public:
|
||||
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
|
||||
: ModulePass(ID), Name(GraphName) {}
|
||||
|
||||
virtual bool runOnModule(Module &M) {
|
||||
Analysis *Graph = &getAnalysis<Analysis>();
|
||||
std::string Filename = Name + ".dot";
|
||||
std::string ErrorInfo;
|
||||
|
||||
errs() << "Writing '" << Filename << "'...";
|
||||
|
||||
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
|
||||
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||
|
||||
if (ErrorInfo.empty())
|
||||
WriteGraph(File, Graph, Simple, Title);
|
||||
else
|
||||
errs() << " error opening file for writing!";
|
||||
errs() << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<Analysis>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,16 @@
|
||||
// of memory references in a function, returning either NULL, for no dependence,
|
||||
// or a more-or-less detailed description of the dependence between them.
|
||||
//
|
||||
// This pass exists to support the DependenceGraph pass. There are two separate
|
||||
// passes because there's a useful separation of concerns. A dependence exists
|
||||
// if two conditions are met:
|
||||
//
|
||||
// 1) Two instructions reference the same memory location, and
|
||||
// 2) There is a flow of control leading from one instruction to the other.
|
||||
//
|
||||
// DependenceAnalysis attacks the first condition; DependenceGraph will attack
|
||||
// the second (it's not yet ready).
|
||||
//
|
||||
// Please note that this is work in progress and the interface is subject to
|
||||
// change.
|
||||
//
|
||||
@ -30,9 +40,9 @@
|
||||
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
||||
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
||||
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
namespace llvm {
|
||||
class AliasAnalysis;
|
||||
@ -53,8 +63,8 @@ namespace llvm {
|
||||
/// input dependences are unordered.
|
||||
class Dependence {
|
||||
public:
|
||||
Dependence(const Instruction *Source,
|
||||
const Instruction *Destination) :
|
||||
Dependence(Instruction *Source,
|
||||
Instruction *Destination) :
|
||||
Src(Source), Dst(Destination) {}
|
||||
virtual ~Dependence() {}
|
||||
|
||||
@ -82,11 +92,11 @@ namespace llvm {
|
||||
|
||||
/// getSrc - Returns the source instruction for this dependence.
|
||||
///
|
||||
const Instruction *getSrc() const { return Src; }
|
||||
Instruction *getSrc() const { return Src; }
|
||||
|
||||
/// getDst - Returns the destination instruction for this dependence.
|
||||
///
|
||||
const Instruction *getDst() const { return Dst; }
|
||||
Instruction *getDst() const { return Dst; }
|
||||
|
||||
/// isInput - Returns true if this is an input dependence.
|
||||
///
|
||||
@ -158,14 +168,14 @@ namespace llvm {
|
||||
///
|
||||
void dump(raw_ostream &OS) const;
|
||||
private:
|
||||
const Instruction *Src, *Dst;
|
||||
Instruction *Src, *Dst;
|
||||
friend class DependenceAnalysis;
|
||||
};
|
||||
|
||||
|
||||
/// FullDependence - This class represents a dependence between two memory
|
||||
/// references in a function. It contains detailed information about the
|
||||
/// dependence (direction vectors, etc) and is used when the compiler is
|
||||
/// dependence (direction vectors, etc.) and is used when the compiler is
|
||||
/// able to accurately analyze the interaction of the references; that is,
|
||||
/// it is not a confused dependence (see Dependence). In most cases
|
||||
/// (for output, flow, and anti dependences), the dependence implies an
|
||||
@ -173,12 +183,12 @@ namespace llvm {
|
||||
/// input dependences are unordered.
|
||||
class FullDependence : public Dependence {
|
||||
public:
|
||||
FullDependence(const Instruction *Src,
|
||||
const Instruction *Dst,
|
||||
FullDependence(Instruction *Src,
|
||||
Instruction *Dst,
|
||||
bool LoopIndependent,
|
||||
unsigned Levels);
|
||||
~FullDependence() {
|
||||
delete DV;
|
||||
delete[] DV;
|
||||
}
|
||||
|
||||
/// isLoopIndependent - Returns true if this is a loop-independent
|
||||
@ -234,8 +244,8 @@ namespace llvm {
|
||||
/// DependenceAnalysis - This class is the main dependence-analysis driver.
|
||||
///
|
||||
class DependenceAnalysis : public FunctionPass {
|
||||
void operator=(const DependenceAnalysis &); // do not implement
|
||||
DependenceAnalysis(const DependenceAnalysis &); // do not implement
|
||||
void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
|
||||
DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
/// depends - Tests for a dependence between the Src and Dst instructions.
|
||||
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
|
||||
@ -243,11 +253,11 @@ namespace llvm {
|
||||
/// The flag PossiblyLoopIndependent should be set by the caller
|
||||
/// if it appears that control flow can reach from Src to Dst
|
||||
/// without traversing a loop back edge.
|
||||
Dependence *depends(const Instruction *Src,
|
||||
const Instruction *Dst,
|
||||
Dependence *depends(Instruction *Src,
|
||||
Instruction *Dst,
|
||||
bool PossiblyLoopIndependent);
|
||||
|
||||
/// getSplitIteration - Give a dependence that's splitable at some
|
||||
/// getSplitIteration - Give a dependence that's splittable at some
|
||||
/// particular level, return the iteration that should be used to split
|
||||
/// the loop.
|
||||
///
|
||||
|
@ -10,8 +10,8 @@
|
||||
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
||||
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
||||
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -15,13 +15,13 @@
|
||||
#ifndef LLVM_ANALYSIS_DOMINATORS_H
|
||||
#define LLVM_ANALYSIS_DOMINATORS_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -101,18 +101,18 @@ class DomTreeNodeBase {
|
||||
Children.clear();
|
||||
}
|
||||
|
||||
bool compare(DomTreeNodeBase<NodeT> *Other) {
|
||||
bool compare(const DomTreeNodeBase<NodeT> *Other) const {
|
||||
if (getNumChildren() != Other->getNumChildren())
|
||||
return true;
|
||||
|
||||
SmallPtrSet<NodeT *, 4> OtherChildren;
|
||||
for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
|
||||
NodeT *Nd = (*I)->getBlock();
|
||||
SmallPtrSet<const NodeT *, 4> OtherChildren;
|
||||
for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
|
||||
const NodeT *Nd = (*I)->getBlock();
|
||||
OtherChildren.insert(Nd);
|
||||
}
|
||||
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
NodeT *N = (*I)->getBlock();
|
||||
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
||||
const NodeT *N = (*I)->getBlock();
|
||||
if (OtherChildren.count(N) == 0)
|
||||
return true;
|
||||
}
|
||||
@ -663,8 +663,7 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
||||
// Initialize the roots list
|
||||
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
|
||||
E = TraitsTy::nodes_end(&F); I != E; ++I) {
|
||||
if (std::distance(TraitsTy::child_begin(I),
|
||||
TraitsTy::child_end(I)) == 0)
|
||||
if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
|
||||
addRoot(I);
|
||||
|
||||
// Prepopulate maps so that we don't get iterator invalidation issues later.
|
||||
|
@ -24,7 +24,6 @@ namespace llvm {
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class Value;
|
||||
class IVUsers;
|
||||
class ScalarEvolution;
|
||||
class SCEV;
|
||||
class IVUsers;
|
||||
|
@ -14,122 +14,130 @@
|
||||
#ifndef LLVM_ANALYSIS_INLINECOST_H
|
||||
#define LLVM_ANALYSIS_INLINECOST_H
|
||||
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/ValueMap.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class CallSite;
|
||||
class DataLayout;
|
||||
class Function;
|
||||
class TargetTransformInfo;
|
||||
|
||||
class CallSite;
|
||||
class DataLayout;
|
||||
namespace InlineConstants {
|
||||
// Various magic constants used to adjust heuristics.
|
||||
const int InstrCost = 5;
|
||||
const int IndirectCallThreshold = 100;
|
||||
const int CallPenalty = 25;
|
||||
const int LastCallToStaticBonus = -15000;
|
||||
const int ColdccPenalty = 2000;
|
||||
const int NoreturnPenalty = 10000;
|
||||
/// Do not inline functions which allocate this many bytes on the stack
|
||||
/// when the caller is recursive.
|
||||
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
|
||||
}
|
||||
|
||||
namespace InlineConstants {
|
||||
// Various magic constants used to adjust heuristics.
|
||||
const int InstrCost = 5;
|
||||
const int IndirectCallThreshold = 100;
|
||||
const int CallPenalty = 25;
|
||||
const int LastCallToStaticBonus = -15000;
|
||||
const int ColdccPenalty = 2000;
|
||||
const int NoreturnPenalty = 10000;
|
||||
/// Do not inline functions which allocate this many bytes on the stack
|
||||
/// when the caller is recursive.
|
||||
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
|
||||
/// \brief Represents the cost of inlining a function.
|
||||
///
|
||||
/// This supports special values for functions which should "always" or
|
||||
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
|
||||
/// smaller values increase the likelihood of the function being inlined.
|
||||
///
|
||||
/// Objects of this type also provide the adjusted threshold for inlining
|
||||
/// based on the information available for a particular callsite. They can be
|
||||
/// directly tested to determine if inlining should occur given the cost and
|
||||
/// threshold for this cost metric.
|
||||
class InlineCost {
|
||||
enum SentinelValues {
|
||||
AlwaysInlineCost = INT_MIN,
|
||||
NeverInlineCost = INT_MAX
|
||||
};
|
||||
|
||||
/// \brief The estimated cost of inlining this callsite.
|
||||
const int Cost;
|
||||
|
||||
/// \brief The adjusted threshold against which this cost was computed.
|
||||
const int Threshold;
|
||||
|
||||
// Trivial constructor, interesting logic in the factory functions below.
|
||||
InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {}
|
||||
|
||||
public:
|
||||
static InlineCost get(int Cost, int Threshold) {
|
||||
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
|
||||
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
|
||||
return InlineCost(Cost, Threshold);
|
||||
}
|
||||
static InlineCost getAlways() {
|
||||
return InlineCost(AlwaysInlineCost, 0);
|
||||
}
|
||||
static InlineCost getNever() {
|
||||
return InlineCost(NeverInlineCost, 0);
|
||||
}
|
||||
|
||||
/// \brief Represents the cost of inlining a function.
|
||||
/// \brief Test whether the inline cost is low enough for inlining.
|
||||
operator bool() const {
|
||||
return Cost < Threshold;
|
||||
}
|
||||
|
||||
bool isAlways() const { return Cost == AlwaysInlineCost; }
|
||||
bool isNever() const { return Cost == NeverInlineCost; }
|
||||
bool isVariable() const { return !isAlways() && !isNever(); }
|
||||
|
||||
/// \brief Get the inline cost estimate.
|
||||
/// It is an error to call this on an "always" or "never" InlineCost.
|
||||
int getCost() const {
|
||||
assert(isVariable() && "Invalid access of InlineCost");
|
||||
return Cost;
|
||||
}
|
||||
|
||||
/// \brief Get the cost delta from the threshold for inlining.
|
||||
/// Only valid if the cost is of the variable kind. Returns a negative
|
||||
/// value if the cost is too high to inline.
|
||||
int getCostDelta() const { return Threshold - getCost(); }
|
||||
};
|
||||
|
||||
/// \brief Cost analyzer used by inliner.
|
||||
class InlineCostAnalysis : public CallGraphSCCPass {
|
||||
const DataLayout *TD;
|
||||
const TargetTransformInfo *TTI;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
InlineCostAnalysis();
|
||||
~InlineCostAnalysis();
|
||||
|
||||
// Pass interface implementation.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
bool runOnSCC(CallGraphSCC &SCC);
|
||||
|
||||
/// \brief Get an InlineCost object representing the cost of inlining this
|
||||
/// callsite.
|
||||
///
|
||||
/// This supports special values for functions which should "always" or
|
||||
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
|
||||
/// smaller values increase the likelihood of the function being inlined.
|
||||
/// Note that threshold is passed into this function. Only costs below the
|
||||
/// threshold are computed with any accuracy. The threshold can be used to
|
||||
/// bound the computation necessary to determine whether the cost is
|
||||
/// sufficiently low to warrant inlining.
|
||||
///
|
||||
/// Objects of this type also provide the adjusted threshold for inlining
|
||||
/// based on the information available for a particular callsite. They can be
|
||||
/// directly tested to determine if inlining should occur given the cost and
|
||||
/// threshold for this cost metric.
|
||||
class InlineCost {
|
||||
enum SentinelValues {
|
||||
AlwaysInlineCost = INT_MIN,
|
||||
NeverInlineCost = INT_MAX
|
||||
};
|
||||
/// Also note that calling this function *dynamically* computes the cost of
|
||||
/// inlining the callsite. It is an expensive, heavyweight call.
|
||||
InlineCost getInlineCost(CallSite CS, int Threshold);
|
||||
|
||||
/// \brief The estimated cost of inlining this callsite.
|
||||
const int Cost;
|
||||
/// \brief Get an InlineCost with the callee explicitly specified.
|
||||
/// This allows you to calculate the cost of inlining a function via a
|
||||
/// pointer. This behaves exactly as the version with no explicit callee
|
||||
/// parameter in all other respects.
|
||||
//
|
||||
// Note: This is used by out-of-tree passes, please do not remove without
|
||||
// adding a replacement API.
|
||||
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
|
||||
|
||||
/// \brief The adjusted threshold against which this cost was computed.
|
||||
const int Threshold;
|
||||
/// \brief Minimal filter to detect invalid constructs for inlining.
|
||||
bool isInlineViable(Function &Callee);
|
||||
};
|
||||
|
||||
// Trivial constructor, interesting logic in the factory functions below.
|
||||
InlineCost(int Cost, int Threshold)
|
||||
: Cost(Cost), Threshold(Threshold) {}
|
||||
|
||||
public:
|
||||
static InlineCost get(int Cost, int Threshold) {
|
||||
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
|
||||
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
|
||||
return InlineCost(Cost, Threshold);
|
||||
}
|
||||
static InlineCost getAlways() {
|
||||
return InlineCost(AlwaysInlineCost, 0);
|
||||
}
|
||||
static InlineCost getNever() {
|
||||
return InlineCost(NeverInlineCost, 0);
|
||||
}
|
||||
|
||||
/// \brief Test whether the inline cost is low enough for inlining.
|
||||
operator bool() const {
|
||||
return Cost < Threshold;
|
||||
}
|
||||
|
||||
bool isAlways() const { return Cost == AlwaysInlineCost; }
|
||||
bool isNever() const { return Cost == NeverInlineCost; }
|
||||
bool isVariable() const { return !isAlways() && !isNever(); }
|
||||
|
||||
/// \brief Get the inline cost estimate.
|
||||
/// It is an error to call this on an "always" or "never" InlineCost.
|
||||
int getCost() const {
|
||||
assert(isVariable() && "Invalid access of InlineCost");
|
||||
return Cost;
|
||||
}
|
||||
|
||||
/// \brief Get the cost delta from the threshold for inlining.
|
||||
/// Only valid if the cost is of the variable kind. Returns a negative
|
||||
/// value if the cost is too high to inline.
|
||||
int getCostDelta() const { return Threshold - getCost(); }
|
||||
};
|
||||
|
||||
/// InlineCostAnalyzer - Cost analyzer used by inliner.
|
||||
class InlineCostAnalyzer {
|
||||
// DataLayout if available, or null.
|
||||
const DataLayout *TD;
|
||||
|
||||
public:
|
||||
InlineCostAnalyzer(): TD(0) {}
|
||||
|
||||
void setDataLayout(const DataLayout *TData) { TD = TData; }
|
||||
|
||||
/// \brief Get an InlineCost object representing the cost of inlining this
|
||||
/// callsite.
|
||||
///
|
||||
/// Note that threshold is passed into this function. Only costs below the
|
||||
/// threshold are computed with any accuracy. The threshold can be used to
|
||||
/// bound the computation necessary to determine whether the cost is
|
||||
/// sufficiently low to warrant inlining.
|
||||
InlineCost getInlineCost(CallSite CS, int Threshold);
|
||||
/// getCalledFunction - The heuristic used to determine if we should inline
|
||||
/// the function call or not. The callee is explicitly specified, to allow
|
||||
/// you to calculate the cost of inlining a function via a pointer. This
|
||||
/// behaves exactly as the version with no explicit callee parameter in all
|
||||
/// other respects.
|
||||
//
|
||||
// Note: This is used by out-of-tree passes, please do not remove without
|
||||
// adding a replacement API.
|
||||
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -14,17 +14,33 @@
|
||||
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
|
||||
// then it dominates the original instruction.
|
||||
//
|
||||
// These routines implicitly resolve undef uses. The easiest way to be safe when
|
||||
// using these routines to obtain simplified values for existing instructions is
|
||||
// to always replace all uses of the instructions with the resulting simplified
|
||||
// values. This will prevent other code from seeing the same undef uses and
|
||||
// resolving them to different values.
|
||||
//
|
||||
// These routines are designed to tolerate moderately incomplete IR, such as
|
||||
// instructions that are not connected to basic blocks yet. However, they do
|
||||
// require that all the IR that they encounter be valid. In particular, they
|
||||
// require that all non-constant values be defined in the same function, and the
|
||||
// same call context of that function (and not split between caller and callee
|
||||
// contexts of a directly recursive call, for example).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||
|
||||
#include "llvm/IR/User.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class ArrayRef;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
class FastMathFlags;
|
||||
class TargetLibraryInfo;
|
||||
class Type;
|
||||
class Value;
|
||||
@ -43,6 +59,28 @@ namespace llvm {
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// Given operands for an FAdd, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// Given operands for an FSub, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// Given operands for an FMul, see if we can fold the result. If not, this
|
||||
/// returns null.
|
||||
Value *SimplifyFMulInst(Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// SimplifyMulInst - Given operands for a Mul, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||
@ -57,7 +95,7 @@ namespace llvm {
|
||||
|
||||
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
@ -69,7 +107,7 @@ namespace llvm {
|
||||
|
||||
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
@ -88,7 +126,7 @@ namespace llvm {
|
||||
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout *TD = 0,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
@ -127,14 +165,14 @@ namespace llvm {
|
||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = 0,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = 0,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
@ -178,10 +216,28 @@ namespace llvm {
|
||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const DataLayout *TD = 0,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// \brief Given a function and iterators over arguments, see if we can fold
|
||||
/// the result.
|
||||
///
|
||||
/// If this call could not be simplified returns null.
|
||||
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
|
||||
User::op_iterator ArgEnd, const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// \brief Given a function and set of arguments, see if we can fold the
|
||||
/// result.
|
||||
///
|
||||
/// If this call could not be simplified returns null.
|
||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
|
||||
const DataLayout *TD = 0,
|
||||
const TargetLibraryInfo *TLI = 0,
|
||||
const DominatorTree *DT = 0);
|
||||
|
||||
/// SimplifyInstruction - See if we can compute a simplified version of this
|
||||
/// instruction. If not, this returns null.
|
||||
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
|
||||
|
@ -17,8 +17,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_INTERVAL_H
|
||||
#define LLVM_INTERVAL_H
|
||||
#ifndef LLVM_ANALYSIS_INTERVAL_H
|
||||
#define LLVM_ANALYSIS_INTERVAL_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include <vector>
|
||||
|
@ -30,11 +30,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_INTERVAL_ITERATOR_H
|
||||
#define LLVM_INTERVAL_ITERATOR_H
|
||||
#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
|
||||
#define LLVM_ANALYSIS_INTERVALITERATOR_H
|
||||
|
||||
#include "llvm/Analysis/IntervalPartition.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
@ -157,7 +157,7 @@ class IntervalIterator {
|
||||
private:
|
||||
// ProcessInterval - This method is used during the construction of the
|
||||
// interval graph. It walks through the source graph, recursively creating
|
||||
// an interval per invokation until the entire graph is covered. This uses
|
||||
// an interval per invocation until the entire graph is covered. This uses
|
||||
// the ProcessNode method to add all of the nodes to the interval.
|
||||
//
|
||||
// This method is templated because it may operate on two different source
|
||||
|
@ -20,8 +20,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_INTERVAL_PARTITION_H
|
||||
#define LLVM_INTERVAL_PARTITION_H
|
||||
#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
|
||||
#define LLVM_ANALYSIS_INTERVALPARTITION_H
|
||||
|
||||
#include "llvm/Analysis/Interval.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LIBCALL_AA_H
|
||||
#define LLVM_ANALYSIS_LIBCALL_AA_H
|
||||
#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
|
||||
#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
|
||||
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_ANALYSIS_LOADS_H
|
||||
#define LLVM_ANALYSIS_LOADS_H
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -27,21 +27,16 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LOOP_INFO_H
|
||||
#define LLVM_ANALYSIS_LOOP_INFO_H
|
||||
#ifndef LLVM_ANALYSIS_LOOPINFO_H
|
||||
#define LLVM_ANALYSIS_LOOPINFO_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -56,6 +51,7 @@ class DominatorTree;
|
||||
class LoopInfo;
|
||||
class Loop;
|
||||
class PHINode;
|
||||
class raw_ostream;
|
||||
template<class N, class M> class LoopInfoBase;
|
||||
template<class N, class M> class LoopBase;
|
||||
|
||||
@ -151,10 +147,10 @@ class LoopBase {
|
||||
/// block that is outside of the current loop.
|
||||
///
|
||||
bool isLoopExiting(const BlockT *BB) const {
|
||||
typedef GraphTraits<BlockT*> BlockTraits;
|
||||
typedef GraphTraits<const BlockT*> BlockTraits;
|
||||
for (typename BlockTraits::ChildIteratorType SI =
|
||||
BlockTraits::child_begin(const_cast<BlockT*>(BB)),
|
||||
SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++SI) {
|
||||
BlockTraits::child_begin(BB),
|
||||
SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
|
||||
if (!contains(*SI))
|
||||
return true;
|
||||
}
|
||||
@ -169,8 +165,8 @@ class LoopBase {
|
||||
|
||||
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
|
||||
for (typename InvBlockTraits::ChildIteratorType I =
|
||||
InvBlockTraits::child_begin(const_cast<BlockT*>(H)),
|
||||
E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I)
|
||||
InvBlockTraits::child_begin(H),
|
||||
E = InvBlockTraits::child_end(H); I != E; ++I)
|
||||
if (contains(*I))
|
||||
++NumBackEdges;
|
||||
|
||||
@ -381,6 +377,20 @@ class Loop : public LoopBase<BasicBlock, Loop> {
|
||||
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
|
||||
bool isSafeToClone() const;
|
||||
|
||||
/// Returns true if the loop is annotated parallel.
|
||||
///
|
||||
/// A parallel loop can be assumed to not contain any dependencies between
|
||||
/// iterations by the compiler. That is, any loop-carried dependency checking
|
||||
/// can be skipped completely when parallelizing the loop on the target
|
||||
/// machine. Thus, if the parallel loop information originates from the
|
||||
/// programmer, e.g. via the OpenMP parallel for pragma, it is the
|
||||
/// programmer's responsibility to ensure there are no loop-carried
|
||||
/// dependencies. The final execution order of the instructions across
|
||||
/// iterations is not guaranteed, thus, the end result might or might not
|
||||
/// implement actual concurrent execution of instructions across multiple
|
||||
/// iterations.
|
||||
bool isAnnotatedParallel() const;
|
||||
|
||||
/// hasDedicatedExits - Return true if no exit block for the loop
|
||||
/// has a predecessor that is outside the loop.
|
||||
bool hasDedicatedExits() const;
|
||||
|
@ -12,11 +12,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
|
||||
#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
|
||||
#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
|
||||
#define LLVM_ANALYSIS_LOOPINFOIMPL_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -21,10 +21,9 @@
|
||||
// reachable from the loop header.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
|
||||
#define LLVM_ANALYSIS_LOOP_ITERATOR_H
|
||||
#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
|
||||
#define LLVM_ANALYSIS_LOOPITERATOR_H
|
||||
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
|
||||
|
@ -12,13 +12,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LOOP_PASS_H
|
||||
#define LLVM_LOOP_PASS_H
|
||||
#ifndef LLVM_ANALYSIS_LOOPPASS_H
|
||||
#define LLVM_ANALYSIS_LOOPPASS_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/PassManagers.h"
|
||||
#include "llvm/Function.h"
|
||||
#include <deque>
|
||||
|
||||
namespace llvm {
|
||||
@ -39,6 +38,9 @@ class LoopPass : public Pass {
|
||||
// whatever action is necessary for the specified Loop.
|
||||
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
|
||||
|
||||
using llvm::Pass::doInitialization;
|
||||
using llvm::Pass::doFinalization;
|
||||
|
||||
// Initialization and finalization hooks.
|
||||
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
|
||||
return false;
|
||||
|
@ -15,12 +15,12 @@
|
||||
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
|
||||
#define LLVM_ANALYSIS_MEMORYBUILTINS_H
|
||||
|
||||
#include "llvm/IRBuilder.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/InstVisitor.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/InstVisitor.h"
|
||||
#include "llvm/Support/TargetFolder.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
|
||||
@ -138,12 +138,22 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
|
||||
//
|
||||
|
||||
/// \brief Compute the size of the object pointed by Ptr. Returns true and the
|
||||
/// object size in Size if successful, and false otherwise.
|
||||
/// object size in Size if successful, and false otherwise. In this context, by
|
||||
/// object we mean the region of memory starting at Ptr to the end of the
|
||||
/// underlying object pointed to by Ptr.
|
||||
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
|
||||
/// byval arguments, and global variables.
|
||||
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
|
||||
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
|
||||
|
||||
/// \brief Compute the size of the underlying object pointed by Ptr. Returns
|
||||
/// true and the object size in Size if successful, and false otherwise.
|
||||
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
|
||||
/// byval arguments, and global variables.
|
||||
bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
|
||||
const DataLayout *TD, const TargetLibraryInfo *TLI,
|
||||
bool RoundToAlign = false);
|
||||
|
||||
|
||||
|
||||
typedef std::pair<APInt, APInt> SizeOffsetType;
|
||||
@ -153,12 +163,14 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
|
||||
class ObjectSizeOffsetVisitor
|
||||
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
|
||||
|
||||
typedef DenseMap<const Value*, SizeOffsetType> CacheMapTy;
|
||||
|
||||
const DataLayout *TD;
|
||||
const TargetLibraryInfo *TLI;
|
||||
bool RoundToAlign;
|
||||
unsigned IntTyBits;
|
||||
APInt Zero;
|
||||
SmallPtrSet<Instruction *, 8> SeenInsts;
|
||||
CacheMapTy CacheMap;
|
||||
|
||||
APInt align(APInt Size, uint64_t Align);
|
||||
|
||||
@ -191,6 +203,7 @@ class ObjectSizeOffsetVisitor
|
||||
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
|
||||
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
|
||||
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
|
||||
SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
|
||||
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
|
||||
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
|
||||
SizeOffsetType visitLoadInst(LoadInst &I);
|
||||
|
@ -11,17 +11,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
|
||||
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
|
||||
#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
|
||||
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
@ -34,14 +34,14 @@ namespace llvm {
|
||||
class PredIteratorCache;
|
||||
class DominatorTree;
|
||||
class PHITransAddr;
|
||||
|
||||
|
||||
/// MemDepResult - A memory dependence query can return one of three different
|
||||
/// answers, described below.
|
||||
class MemDepResult {
|
||||
enum DepType {
|
||||
/// Invalid - Clients of MemDep never see this.
|
||||
Invalid = 0,
|
||||
|
||||
|
||||
/// Clobber - This is a dependence on the specified instruction which
|
||||
/// clobbers the desired value. The pointer member of the MemDepResult
|
||||
/// pair holds the instruction that clobbers the memory. For example,
|
||||
@ -72,7 +72,7 @@ namespace llvm {
|
||||
/// and no intervening clobbers. No validation is done that the
|
||||
/// operands to the calls are the same.
|
||||
Def,
|
||||
|
||||
|
||||
/// Other - This marker indicates that the query has no known dependency
|
||||
/// in the specified block. More detailed state info is encoded in the
|
||||
/// upper part of the pair (i.e. the Instruction*)
|
||||
@ -99,7 +99,7 @@ namespace llvm {
|
||||
explicit MemDepResult(PairTy V) : Value(V) {}
|
||||
public:
|
||||
MemDepResult() : Value(0, Invalid) {}
|
||||
|
||||
|
||||
/// get methods: These are static ctor methods for creating various
|
||||
/// MemDepResult kinds.
|
||||
static MemDepResult getDef(Instruction *Inst) {
|
||||
@ -130,7 +130,7 @@ namespace llvm {
|
||||
/// isDef - Return true if this MemDepResult represents a query that is
|
||||
/// an instruction definition dependency.
|
||||
bool isDef() const { return Value.getInt() == Def; }
|
||||
|
||||
|
||||
/// isNonLocal - Return true if this MemDepResult represents a query that
|
||||
/// is transparent to the start of the block, but where a non-local hasn't
|
||||
/// been done.
|
||||
@ -145,7 +145,7 @@ namespace llvm {
|
||||
return Value.getInt() == Other
|
||||
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
|
||||
}
|
||||
|
||||
|
||||
/// isUnknown - Return true if this MemDepResult represents a query which
|
||||
/// cannot and/or will not be computed.
|
||||
bool isUnknown() const {
|
||||
@ -159,7 +159,7 @@ namespace llvm {
|
||||
if (Value.getInt() == Other) return NULL;
|
||||
return Value.getPointer();
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const MemDepResult &M) const { return Value == M.Value; }
|
||||
bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
|
||||
bool operator<(const MemDepResult &M) const { return Value < M.Value; }
|
||||
@ -175,11 +175,11 @@ namespace llvm {
|
||||
/// In a default-constructed MemDepResult object, the type will be Dirty
|
||||
/// and the instruction pointer will be null.
|
||||
///
|
||||
|
||||
|
||||
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
|
||||
/// state.
|
||||
bool isDirty() const { return Value.getInt() == Invalid; }
|
||||
|
||||
|
||||
static MemDepResult getDirty(Instruction *Inst) {
|
||||
return MemDepResult(PairTy(Inst, Invalid));
|
||||
}
|
||||
@ -199,16 +199,16 @@ namespace llvm {
|
||||
|
||||
// BB is the sort key, it can't be changed.
|
||||
BasicBlock *getBB() const { return BB; }
|
||||
|
||||
|
||||
void setResult(const MemDepResult &R) { Result = R; }
|
||||
|
||||
const MemDepResult &getResult() const { return Result; }
|
||||
|
||||
|
||||
bool operator<(const NonLocalDepEntry &RHS) const {
|
||||
return BB < RHS.BB;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
|
||||
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
|
||||
/// (potentially phi translated) address that was live in the block.
|
||||
@ -218,17 +218,17 @@ namespace llvm {
|
||||
public:
|
||||
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
|
||||
: Entry(bb, result), Address(address) {}
|
||||
|
||||
|
||||
// BB is the sort key, it can't be changed.
|
||||
BasicBlock *getBB() const { return Entry.getBB(); }
|
||||
|
||||
|
||||
void setResult(const MemDepResult &R, Value *Addr) {
|
||||
Entry.setResult(R);
|
||||
Address = Addr;
|
||||
}
|
||||
|
||||
|
||||
const MemDepResult &getResult() const { return Entry.getResult(); }
|
||||
|
||||
|
||||
/// getAddress - Return the address of this pointer in this block. This can
|
||||
/// be different than the address queried for the non-local result because
|
||||
/// of phi translation. This returns null if the address was not available
|
||||
@ -238,7 +238,7 @@ namespace llvm {
|
||||
/// The address is always null for a non-local 'call' dependence.
|
||||
Value *getAddress() const { return Address; }
|
||||
};
|
||||
|
||||
|
||||
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
|
||||
/// given memory operation, what preceding memory operations it depends on.
|
||||
/// It builds on alias analysis information, and tries to provide a lazy,
|
||||
@ -297,30 +297,30 @@ namespace llvm {
|
||||
CachedNonLocalPointerInfo NonLocalPointerDeps;
|
||||
|
||||
// A map from instructions to their non-local pointer dependencies.
|
||||
typedef DenseMap<Instruction*,
|
||||
typedef DenseMap<Instruction*,
|
||||
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
|
||||
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
|
||||
|
||||
|
||||
|
||||
/// PerInstNLInfo - This is the instruction we keep for each cached access
|
||||
/// that we have for an instruction. The pointer is an owning pointer and
|
||||
/// the bool indicates whether we have any dirty bits in the set.
|
||||
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
|
||||
|
||||
|
||||
// A map from instructions to their non-local dependencies.
|
||||
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
|
||||
|
||||
|
||||
NonLocalDepMapType NonLocalDeps;
|
||||
|
||||
|
||||
// A reverse mapping from dependencies to the dependees. This is
|
||||
// used when removing instructions to keep the cache coherent.
|
||||
typedef DenseMap<Instruction*,
|
||||
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
||||
ReverseDepMapType ReverseLocalDeps;
|
||||
|
||||
|
||||
// A reverse mapping from dependencies to the non-local dependees.
|
||||
ReverseDepMapType ReverseNonLocalDeps;
|
||||
|
||||
|
||||
/// Current AA implementation, just a cache.
|
||||
AliasAnalysis *AA;
|
||||
DataLayout *TD;
|
||||
@ -333,15 +333,15 @@ namespace llvm {
|
||||
|
||||
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
|
||||
bool runOnFunction(Function &);
|
||||
|
||||
|
||||
/// Clean up memory in between runs
|
||||
void releaseMemory();
|
||||
|
||||
|
||||
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
|
||||
/// and Alias Analysis.
|
||||
///
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
|
||||
/// getDependency - Return the instruction on which a memory operation
|
||||
/// depends. See the class comment for more details. It is illegal to call
|
||||
/// this on non-memory instructions.
|
||||
@ -360,8 +360,8 @@ namespace llvm {
|
||||
/// removed. Clients must copy this data if they want it around longer than
|
||||
/// that.
|
||||
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
|
||||
|
||||
|
||||
|
||||
|
||||
/// getNonLocalPointerDependency - Perform a full dependency query for an
|
||||
/// access to the specified (non-volatile) memory location, returning the
|
||||
/// set of instructions that either define or clobber the value.
|
||||
@ -374,7 +374,7 @@ namespace llvm {
|
||||
/// removeInstruction - Remove an instruction from the dependence analysis,
|
||||
/// updating the dependence of instructions that previously depended on it.
|
||||
void removeInstruction(Instruction *InstToRemove);
|
||||
|
||||
|
||||
/// invalidateCachedPointerInfo - This method is used to invalidate cached
|
||||
/// information about the specified pointer, because it may be too
|
||||
/// conservative in memdep. This is an optional call that can be used when
|
||||
@ -387,20 +387,23 @@ namespace llvm {
|
||||
/// This needs to be done when the CFG changes, e.g., due to splitting
|
||||
/// critical edges.
|
||||
void invalidateCachedPredecessors();
|
||||
|
||||
|
||||
/// getPointerDependencyFrom - Return the instruction on which a memory
|
||||
/// location depends. If isLoad is true, this routine ignores may-aliases
|
||||
/// with read-only operations. If isLoad is false, this routine ignores
|
||||
/// may-aliases with reads from read-only locations.
|
||||
/// may-aliases with reads from read-only locations. If possible, pass
|
||||
/// the query instruction as well; this function may take advantage of
|
||||
/// the metadata annotated to the query instruction to refine the result.
|
||||
///
|
||||
/// Note that this is an uncached query, and thus may be inefficient.
|
||||
///
|
||||
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
|
||||
bool isLoad,
|
||||
bool isLoad,
|
||||
BasicBlock::iterator ScanIt,
|
||||
BasicBlock *BB);
|
||||
|
||||
|
||||
BasicBlock *BB,
|
||||
Instruction *QueryInst = 0);
|
||||
|
||||
|
||||
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
|
||||
/// looks at a memory location for a load (specified by MemLocBase, Offs,
|
||||
/// and Size) and compares it against a load. If the specified load could
|
||||
@ -413,7 +416,7 @@ namespace llvm {
|
||||
unsigned MemLocSize,
|
||||
const LoadInst *LI,
|
||||
const DataLayout &TD);
|
||||
|
||||
|
||||
private:
|
||||
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
|
||||
BasicBlock::iterator ScanIt,
|
||||
@ -430,11 +433,11 @@ namespace llvm {
|
||||
unsigned NumSortedEntries);
|
||||
|
||||
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
|
||||
|
||||
|
||||
/// verifyRemoved - Verify that the specified instruction does not occur
|
||||
/// in our internal data structures.
|
||||
void verifyRemoved(Instruction *Inst) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -14,8 +14,8 @@
|
||||
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
|
||||
#define LLVM_ANALYSIS_PHITRANSADDR_H
|
||||
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
|
||||
namespace llvm {
|
||||
class DominatorTree;
|
||||
|
@ -198,9 +198,6 @@ namespace llvm {
|
||||
// analyze.
|
||||
FunctionPass *createInstCountPass();
|
||||
|
||||
// print debug info intrinsics in human readable form
|
||||
FunctionPass *createDbgInfoPrinterPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createRegionInfoPass - This pass finds all single entry single exit regions
|
||||
|
@ -23,14 +23,14 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_PATH_NUMBERING_H
|
||||
#define LLVM_PATH_NUMBERING_H
|
||||
#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
|
||||
#define LLVM_ANALYSIS_PATHNUMBERING_H
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Analysis/ProfileInfoTypes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Analysis/ProfileInfoTypes.h"
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
@ -11,11 +11,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_PATHPROFILEINFO_H
|
||||
#define LLVM_PATHPROFILEINFO_H
|
||||
#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
|
||||
#define LLVM_ANALYSIS_PATHPROFILEINFO_H
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Analysis/PathNumbering.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
|
||||
#define LLVM_ANALYSIS_POST_DOMINATORS_H
|
||||
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
|
||||
#define LLVM_ANALYSIS_POSTDOMINATORS_H
|
||||
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
|
||||
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
@ -26,9 +26,9 @@
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class Pass;
|
||||
|
@ -16,9 +16,9 @@
|
||||
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
||||
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
285
contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h
Normal file
285
contrib/llvm/include/llvm/Analysis/PtrUseVisitor.h
Normal file
@ -0,0 +1,285 @@
|
||||
//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
/// This file provides a collection of visitors which walk the (instruction)
|
||||
/// uses of a pointer. These visitors all provide the same essential behavior
|
||||
/// as an InstVisitor with similar template-based flexibility and
|
||||
/// implementation strategies.
|
||||
///
|
||||
/// These can be used, for example, to quickly analyze the uses of an alloca,
|
||||
/// global variable, or function argument.
|
||||
///
|
||||
/// FIXME: Provide a variant which doesn't track offsets and is cheaper.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
|
||||
#define LLVM_ANALYSIS_PTRUSEVISITOR_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/InstVisitor.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace detail {
|
||||
/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
|
||||
///
|
||||
/// See \c PtrUseVisitor for the public interface and detailed comments about
|
||||
/// usage. This class is just a helper base class which is not templated and
|
||||
/// contains all common code to be shared between different instantiations of
|
||||
/// PtrUseVisitor.
|
||||
class PtrUseVisitorBase {
|
||||
public:
|
||||
/// \brief This class provides information about the result of a visit.
|
||||
///
|
||||
/// After walking all the users (recursively) of a pointer, the basic
|
||||
/// infrastructure records some commonly useful information such as escape
|
||||
/// analysis and whether the visit completed or aborted early.
|
||||
class PtrInfo {
|
||||
public:
|
||||
PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {}
|
||||
|
||||
/// \brief Reset the pointer info, clearing all state.
|
||||
void reset() {
|
||||
AbortedInfo.setPointer(0);
|
||||
AbortedInfo.setInt(false);
|
||||
EscapedInfo.setPointer(0);
|
||||
EscapedInfo.setInt(false);
|
||||
}
|
||||
|
||||
/// \brief Did we abort the visit early?
|
||||
bool isAborted() const { return AbortedInfo.getInt(); }
|
||||
|
||||
/// \brief Is the pointer escaped at some point?
|
||||
bool isEscaped() const { return EscapedInfo.getInt(); }
|
||||
|
||||
/// \brief Get the instruction causing the visit to abort.
|
||||
/// \returns a pointer to the instruction causing the abort if one is
|
||||
/// available; otherwise returns null.
|
||||
Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); }
|
||||
|
||||
/// \brief Get the instruction causing the pointer to escape.
|
||||
/// \returns a pointer to the instruction which escapes the pointer if one
|
||||
/// is available; otherwise returns null.
|
||||
Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); }
|
||||
|
||||
/// \brief Mark the visit as aborted. Intended for use in a void return.
|
||||
/// \param I The instruction which caused the visit to abort, if available.
|
||||
void setAborted(Instruction *I = 0) {
|
||||
AbortedInfo.setInt(true);
|
||||
AbortedInfo.setPointer(I);
|
||||
}
|
||||
|
||||
/// \brief Mark the pointer as escaped. Intended for use in a void return.
|
||||
/// \param I The instruction which escapes the pointer, if available.
|
||||
void setEscaped(Instruction *I = 0) {
|
||||
EscapedInfo.setInt(true);
|
||||
EscapedInfo.setPointer(I);
|
||||
}
|
||||
|
||||
/// \brief Mark the pointer as escaped, and the visit as aborted. Intended
|
||||
/// for use in a void return.
|
||||
/// \param I The instruction which both escapes the pointer and aborts the
|
||||
/// visit, if available.
|
||||
void setEscapedAndAborted(Instruction *I = 0) {
|
||||
setEscaped(I);
|
||||
setAborted(I);
|
||||
}
|
||||
|
||||
private:
|
||||
PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo;
|
||||
};
|
||||
|
||||
protected:
|
||||
const DataLayout &DL;
|
||||
|
||||
/// \name Visitation infrastructure
|
||||
/// @{
|
||||
|
||||
/// \brief The info collected about the pointer being visited thus far.
|
||||
PtrInfo PI;
|
||||
|
||||
/// \brief A struct of the data needed to visit a particular use.
|
||||
///
|
||||
/// This is used to maintain a worklist fo to-visit uses. This is used to
|
||||
/// make the visit be iterative rather than recursive.
|
||||
struct UseToVisit {
|
||||
typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair;
|
||||
UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
|
||||
APInt Offset;
|
||||
};
|
||||
|
||||
/// \brief The worklist of to-visit uses.
|
||||
SmallVector<UseToVisit, 8> Worklist;
|
||||
|
||||
/// \brief A set of visited uses to break cycles in unreachable code.
|
||||
SmallPtrSet<Use *, 8> VisitedUses;
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// \name Per-visit state
|
||||
/// This state is reset for each instruction visited.
|
||||
/// @{
|
||||
|
||||
/// \brief The use currently being visited.
|
||||
Use *U;
|
||||
|
||||
/// \brief True if we have a known constant offset for the use currently
|
||||
/// being visited.
|
||||
bool IsOffsetKnown;
|
||||
|
||||
/// \brief The constant offset of the use if that is known.
|
||||
APInt Offset;
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
/// Note that the constructor is protected because this class must be a base
|
||||
/// class, we can't create instances directly of this class.
|
||||
PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
|
||||
|
||||
/// \brief Enqueue the users of this instruction in the visit worklist.
|
||||
///
|
||||
/// This will visit the users with the same offset of the current visit
|
||||
/// (including an unknown offset if that is the current state).
|
||||
void enqueueUsers(Instruction &I);
|
||||
|
||||
/// \brief Walk the operands of a GEP and adjust the offset as appropriate.
|
||||
///
|
||||
/// This routine does the heavy lifting of the pointer walk by computing
|
||||
/// offsets and looking through GEPs.
|
||||
bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
/// \brief A base class for visitors over the uses of a pointer value.
|
||||
///
|
||||
/// Once constructed, a user can call \c visit on a pointer value, and this
|
||||
/// will walk its uses and visit each instruction using an InstVisitor. It also
|
||||
/// provides visit methods which will recurse through any pointer-to-pointer
|
||||
/// transformations such as GEPs and bitcasts.
|
||||
///
|
||||
/// During the visit, the current Use* being visited is available to the
|
||||
/// subclass, as well as the current offset from the original base pointer if
|
||||
/// known.
|
||||
///
|
||||
/// The recursive visit of uses is accomplished with a worklist, so the only
|
||||
/// ordering guarantee is that an instruction is visited before any uses of it
|
||||
/// are visited. Note that this does *not* mean before any of its users are
|
||||
/// visited! This is because users can be visited multiple times due to
|
||||
/// multiple, different uses of pointers derived from the same base.
|
||||
///
|
||||
/// A particular Use will only be visited once, but a User may be visited
|
||||
/// multiple times, once per Use. This visits may notably have different
|
||||
/// offsets.
|
||||
///
|
||||
/// All visit methods on the underlying InstVisitor return a boolean. This
|
||||
/// return short-circuits the visit, stopping it immediately.
|
||||
///
|
||||
/// FIXME: Generalize this for all values rather than just instructions.
|
||||
template <typename DerivedT>
|
||||
class PtrUseVisitor : protected InstVisitor<DerivedT>,
|
||||
public detail::PtrUseVisitorBase {
|
||||
friend class InstVisitor<DerivedT>;
|
||||
typedef InstVisitor<DerivedT> Base;
|
||||
|
||||
public:
|
||||
PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
|
||||
|
||||
/// \brief Recursively visit the uses of the given pointer.
|
||||
/// \returns An info struct about the pointer. See \c PtrInfo for details.
|
||||
PtrInfo visitPtr(Instruction &I) {
|
||||
// This must be a pointer type. Get an integer type suitable to hold
|
||||
// offsets on this pointer.
|
||||
// FIXME: Support a vector of pointers.
|
||||
assert(I.getType()->isPointerTy());
|
||||
IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType()));
|
||||
IsOffsetKnown = true;
|
||||
Offset = APInt(IntPtrTy->getBitWidth(), 0);
|
||||
PI.reset();
|
||||
|
||||
// Enqueue the uses of this pointer.
|
||||
enqueueUsers(I);
|
||||
|
||||
// Visit all the uses off the worklist until it is empty.
|
||||
while (!Worklist.empty()) {
|
||||
UseToVisit ToVisit = Worklist.pop_back_val();
|
||||
U = ToVisit.UseAndIsOffsetKnown.getPointer();
|
||||
IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
|
||||
if (IsOffsetKnown)
|
||||
Offset = llvm_move(ToVisit.Offset);
|
||||
|
||||
Instruction *I = cast<Instruction>(U->getUser());
|
||||
static_cast<DerivedT*>(this)->visit(I);
|
||||
if (PI.isAborted())
|
||||
break;
|
||||
}
|
||||
return PI;
|
||||
}
|
||||
|
||||
protected:
|
||||
void visitStoreInst(StoreInst &SI) {
|
||||
if (SI.getValueOperand() == U->get())
|
||||
PI.setEscaped(&SI);
|
||||
}
|
||||
|
||||
void visitBitCastInst(BitCastInst &BC) {
|
||||
enqueueUsers(BC);
|
||||
}
|
||||
|
||||
void visitPtrToIntInst(PtrToIntInst &I) {
|
||||
PI.setEscaped(&I);
|
||||
}
|
||||
|
||||
void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
|
||||
if (GEPI.use_empty())
|
||||
return;
|
||||
|
||||
// If we can't walk the GEP, clear the offset.
|
||||
if (!adjustOffsetForGEP(GEPI)) {
|
||||
IsOffsetKnown = false;
|
||||
Offset = APInt();
|
||||
}
|
||||
|
||||
// Enqueue the users now that the offset has been adjusted.
|
||||
enqueueUsers(GEPI);
|
||||
}
|
||||
|
||||
// No-op intrinsics which we know don't escape the pointer to to logic in
|
||||
// some other function.
|
||||
void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {}
|
||||
void visitMemIntrinsic(MemIntrinsic &I) {}
|
||||
void visitIntrinsicInst(IntrinsicInst &II) {
|
||||
switch (II.getIntrinsicID()) {
|
||||
default:
|
||||
return Base::visitIntrinsicInst(II);
|
||||
|
||||
case Intrinsic::lifetime_start:
|
||||
case Intrinsic::lifetime_end:
|
||||
return; // No-op intrinsics.
|
||||
}
|
||||
}
|
||||
|
||||
// Generically, arguments to calls and invokes escape the pointer to some
|
||||
// other function. Mark that.
|
||||
void visitCallSite(CallSite CS) {
|
||||
PI.setEscaped(CS.getInstruction());
|
||||
Base::visitCallSite(CS);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -24,8 +24,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_REGION_INFO_H
|
||||
#define LLVM_ANALYSIS_REGION_INFO_H
|
||||
#ifndef LLVM_ANALYSIS_REGIONINFO_H
|
||||
#define LLVM_ANALYSIS_REGIONINFO_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Analysis/DominanceFrontier.h"
|
||||
|
@ -8,12 +8,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This file defines the iterators to iterate over the elements of a Region.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
|
||||
#define LLVM_ANALYSIS_REGION_ITERATOR_H
|
||||
#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
|
||||
#define LLVM_ANALYSIS_REGIONITERATOR_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/RegionInfo.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -13,15 +13,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_REGION_PASS_H
|
||||
#define LLVM_REGION_PASS_H
|
||||
#ifndef LLVM_ANALYSIS_REGIONPASS_H
|
||||
#define LLVM_ANALYSIS_REGIONPASS_H
|
||||
|
||||
#include "llvm/Analysis/RegionInfo.h"
|
||||
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/PassManagers.h"
|
||||
#include "llvm/Function.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace llvm {
|
||||
@ -59,6 +57,9 @@ class RegionPass : public Pass {
|
||||
/// @return The pass to print the LLVM IR in the region.
|
||||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
|
||||
|
||||
using llvm::Pass::doInitialization;
|
||||
using llvm::Pass::doFinalization;
|
||||
|
||||
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
|
||||
virtual bool doFinalization() { return false; }
|
||||
//@}
|
||||
|
@ -21,16 +21,16 @@
|
||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_H
|
||||
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ConstantRange.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
@ -338,6 +338,10 @@ namespace llvm {
|
||||
/// getMax - Get the max backedge taken count for the loop.
|
||||
const SCEV *getMax(ScalarEvolution *SE) const;
|
||||
|
||||
/// Return true if any backedge taken count expressions refer to the given
|
||||
/// subexpression.
|
||||
bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
|
||||
|
||||
/// clear - Invalidate this result and free associated memory.
|
||||
void clear();
|
||||
};
|
||||
@ -831,7 +835,7 @@ namespace llvm {
|
||||
|
||||
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
|
||||
/// predicate Pred. Return true iff any changes were made. If the
|
||||
/// operands are provably equal or inequal, LHS and RHS are set to
|
||||
/// operands are provably equal or unequal, LHS and RHS are set to
|
||||
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
|
||||
///
|
||||
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
|
@ -11,18 +11,18 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
|
||||
|
||||
#include "llvm/IRBuilder.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/Support/TargetFolder.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
class TargetLowering;
|
||||
class TargetTransformInfo;
|
||||
|
||||
/// Return true if the given expression is safe to expand in the sense that
|
||||
/// all materialized values are safe to speculate.
|
||||
@ -40,8 +40,10 @@ namespace llvm {
|
||||
// New instructions receive a name to identifies them with the current pass.
|
||||
const char* IVName;
|
||||
|
||||
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
|
||||
// InsertedExpressions caches Values for reuse, so must track RAUW.
|
||||
std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
|
||||
InsertedExpressions;
|
||||
// InsertedValues only flags inserted instructions so needs no RAUW.
|
||||
std::set<AssertingVH<Value> > InsertedValues;
|
||||
std::set<AssertingVH<Value> > InsertedPostIncValues;
|
||||
|
||||
@ -129,7 +131,7 @@ namespace llvm {
|
||||
/// representative. Return the number of phis eliminated.
|
||||
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
SmallVectorImpl<WeakVH> &DeadInsts,
|
||||
const TargetLowering *TLI = NULL);
|
||||
const TargetTransformInfo *TTI = NULL);
|
||||
|
||||
/// expandCodeFor - Insert code to directly compute the specified SCEV
|
||||
/// expression into the program. The inserted code is inserted into the
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user