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
|
# kernel stage
|
||||||
KMAKEENV= ${WMAKEENV}
|
KMAKEENV= ${WMAKEENV}
|
||||||
KMAKE= ${KMAKEENV} ${MAKE} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
|
KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
|
||||||
|
|
||||||
#
|
#
|
||||||
# buildworld
|
# buildworld
|
||||||
|
@ -38,6 +38,37 @@
|
|||||||
# xargs -n1 | sort | uniq -d;
|
# xargs -n1 | sort | uniq -d;
|
||||||
# done
|
# 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
|
# 20130404: legacy ATA stack removed
|
||||||
OLD_FILES+=sbin/atacontrol
|
OLD_FILES+=sbin/atacontrol
|
||||||
OLD_FILES+=usr/share/man/man8/atacontrol.8.gz
|
OLD_FILES+=usr/share/man/man8/atacontrol.8.gz
|
||||||
|
@ -4,7 +4,7 @@ LLVM Release License
|
|||||||
University of Illinois/NCSA
|
University of Illinois/NCSA
|
||||||
Open Source License
|
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.
|
All rights reserved.
|
||||||
|
|
||||||
Developed by:
|
Developed by:
|
||||||
@ -64,7 +64,7 @@ Program Directory
|
|||||||
Autoconf llvm/autoconf
|
Autoconf llvm/autoconf
|
||||||
llvm/projects/ModuleMaker/autoconf
|
llvm/projects/ModuleMaker/autoconf
|
||||||
llvm/projects/sample/autoconf
|
llvm/projects/sample/autoconf
|
||||||
CellSPU backend llvm/lib/Target/CellSPU/README.txt
|
|
||||||
Google Test llvm/utils/unittest/googletest
|
Google Test llvm/utils/unittest/googletest
|
||||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
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'
|
/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
|
||||||
and 'unwrap' conversion functions. */
|
and 'unwrap' conversion functions. */
|
||||||
#include "llvm/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/PassRegistry.h"
|
#include "llvm/PassRegistry.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -173,10 +173,11 @@ typedef enum {
|
|||||||
LLVMUWTable = 1 << 30,
|
LLVMUWTable = 1 << 30,
|
||||||
LLVMNonLazyBind = 1 << 31
|
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
|
a temporary measure until the API/ABI impact to the C API is understood
|
||||||
and the path forward agreed upon.
|
and the path forward agreed upon.
|
||||||
LLVMAddressSafety = 1ULL << 32
|
LLVMAddressSafety = 1ULL << 32,
|
||||||
|
LLVMStackProtectStrongAttribute = 1ULL<<33
|
||||||
*/
|
*/
|
||||||
} LLVMAttribute;
|
} LLVMAttribute;
|
||||||
|
|
||||||
@ -357,6 +358,11 @@ typedef enum {
|
|||||||
|
|
||||||
void LLVMInitializeCore(LLVMPassRegistryRef R);
|
void LLVMInitializeCore(LLVMPassRegistryRef R);
|
||||||
|
|
||||||
|
/** Deallocate and destroy all ManagedStatic variables.
|
||||||
|
@see llvm::llvm_shutdown
|
||||||
|
@see ManagedStatic */
|
||||||
|
void LLVMShutdown();
|
||||||
|
|
||||||
|
|
||||||
/*===-- Error handling ----------------------------------------------------===*/
|
/*===-- Error handling ----------------------------------------------------===*/
|
||||||
|
|
||||||
@ -2547,6 +2553,13 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
|
|||||||
char **OutMessage);
|
char **OutMessage);
|
||||||
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
||||||
char **OutMessage);
|
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);
|
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2614,6 +2627,34 @@ LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
|
|||||||
@see llvm::PassManagerBase::~PassManagerBase. */
|
@see llvm::PassManagerBase::~PassManagerBase. */
|
||||||
void LLVMDisposePassManager(LLVMPassManagerRef PM);
|
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
|
* 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
|
* TagType and callback functions as described above. These can all be passed
|
||||||
* as NULL. If successful, this returns a disassembler context. If not, it
|
* 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,
|
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
|
||||||
int TagType, LLVMOpInfoCallback GetOpInfo,
|
int TagType, LLVMOpInfoCallback GetOpInfo,
|
||||||
LLVMSymbolLookupCallback SymbolLookUp);
|
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
|
* Set the disassembler's options. Returns 1 if it can set the Options and 0
|
||||||
* otherwise.
|
* otherwise.
|
||||||
@ -153,6 +166,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
|
|||||||
|
|
||||||
/* The option to produce marked up assembly. */
|
/* The option to produce marked up assembly. */
|
||||||
#define LLVMDisassembler_Option_UseMarkup 1
|
#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.
|
* 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 LLVMInitializeCore(LLVMPassRegistryRef R);
|
||||||
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
|
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
|
||||||
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
|
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
|
||||||
|
void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R);
|
||||||
void LLVMInitializeVectorization(LLVMPassRegistryRef R);
|
void LLVMInitializeVectorization(LLVMPassRegistryRef R);
|
||||||
void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
|
void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
|
||||||
void LLVMInitializeIPO(LLVMPassRegistryRef R);
|
void LLVMInitializeIPO(LLVMPassRegistryRef R);
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef __LTO_CAPI_H__
|
#ifndef LLVM_C_LINKTIMEOPTIMIZER_H
|
||||||
#define __LTO_CAPI_H__
|
#define LLVM_C_LINKTIMEOPTIMIZER_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define LLVM_C_TARGETMACHINE_H
|
#define LLVM_C_TARGETMACHINE_H
|
||||||
|
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
|
#include "llvm-c/Target.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
|* *|
|
|* *|
|
||||||
\*===----------------------------------------------------------------------===*/
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
#ifndef LLVM_C_PASSMANAGERBUILDER
|
#ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
|
||||||
#define LLVM_C_PASSMANAGERBUILDER
|
#define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
|
||||||
|
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
|
|||||||
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
|
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
|
||||||
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
|
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
|
||||||
LLVMPassManagerRef PM,
|
LLVMPassManagerRef PM,
|
||||||
bool Internalize,
|
LLVMBool Internalize,
|
||||||
bool RunInliner);
|
LLVMBool RunInliner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|* *|
|
|* *|
|
||||||
\*===----------------------------------------------------------------------===*/
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
#ifndef LTO_H
|
#ifndef LLVM_C_LTO_H
|
||||||
#define LTO_H 1
|
#define LLVM_C_LTO_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -291,6 +291,13 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
|
|||||||
extern void
|
extern void
|
||||||
lto_codegen_debug_options(lto_code_gen_t cg, const char *);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -97,8 +97,8 @@
|
|||||||
nexttoward.
|
nexttoward.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LLVM_FLOAT_H
|
#ifndef LLVM_ADT_APFLOAT_H
|
||||||
#define LLVM_FLOAT_H
|
#define LLVM_ADT_APFLOAT_H
|
||||||
|
|
||||||
// APInt contains static functions implementing bignum arithmetic.
|
// APInt contains static functions implementing bignum arithmetic.
|
||||||
#include "llvm/ADT/APInt.h"
|
#include "llvm/ADT/APInt.h"
|
||||||
@ -184,9 +184,9 @@ namespace llvm {
|
|||||||
APFloat(const fltSemantics &, integerPart);
|
APFloat(const fltSemantics &, integerPart);
|
||||||
APFloat(const fltSemantics &, fltCategory, bool negative);
|
APFloat(const fltSemantics &, fltCategory, bool negative);
|
||||||
APFloat(const fltSemantics &, uninitializedTag);
|
APFloat(const fltSemantics &, uninitializedTag);
|
||||||
|
APFloat(const fltSemantics &, const APInt &);
|
||||||
explicit APFloat(double d);
|
explicit APFloat(double d);
|
||||||
explicit APFloat(float f);
|
explicit APFloat(float f);
|
||||||
explicit APFloat(const APInt &, bool isIEEE = false);
|
|
||||||
APFloat(const APFloat &);
|
APFloat(const APFloat &);
|
||||||
~APFloat();
|
~APFloat();
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ namespace llvm {
|
|||||||
/* The definition of equality is not straightforward for floating point,
|
/* The definition of equality is not straightforward for floating point,
|
||||||
so we won't use operator==. Use one of the following, or write
|
so we won't use operator==. Use one of the following, or write
|
||||||
whatever it is you really mean. */
|
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
|
/* IEEE comparison with another floating point number (NaNs
|
||||||
compare unordered, 0==-0). */
|
compare unordered, 0==-0). */
|
||||||
@ -327,6 +327,7 @@ namespace llvm {
|
|||||||
bool isNegative() const { return sign; }
|
bool isNegative() const { return sign; }
|
||||||
bool isPosZero() const { return isZero() && !isNegative(); }
|
bool isPosZero() const { return isZero() && !isNegative(); }
|
||||||
bool isNegZero() const { return isZero() && isNegative(); }
|
bool isNegZero() const { return isZero() && isNegative(); }
|
||||||
|
bool isDenormal() const;
|
||||||
|
|
||||||
APFloat& operator=(const APFloat &);
|
APFloat& operator=(const APFloat &);
|
||||||
|
|
||||||
@ -422,7 +423,7 @@ namespace llvm {
|
|||||||
APInt convertQuadrupleAPFloatToAPInt() const;
|
APInt convertQuadrupleAPFloatToAPInt() const;
|
||||||
APInt convertF80LongDoubleAPFloatToAPInt() const;
|
APInt convertF80LongDoubleAPFloatToAPInt() const;
|
||||||
APInt convertPPCDoubleDoubleAPFloatToAPInt() 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 initFromHalfAPInt(const APInt& api);
|
||||||
void initFromFloatAPInt(const APInt& api);
|
void initFromFloatAPInt(const APInt& api);
|
||||||
void initFromDoubleAPInt(const APInt& api);
|
void initFromDoubleAPInt(const APInt& api);
|
||||||
@ -462,4 +463,4 @@ namespace llvm {
|
|||||||
hash_code hash_value(const APFloat &Arg);
|
hash_code hash_value(const APFloat &Arg);
|
||||||
} /* namespace llvm */
|
} /* namespace llvm */
|
||||||
|
|
||||||
#endif /* LLVM_FLOAT_H */
|
#endif /* LLVM_ADT_APFLOAT_H */
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_APINT_H
|
#ifndef LLVM_ADT_APINT_H
|
||||||
#define LLVM_APINT_H
|
#define LLVM_ADT_APINT_H
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
@ -274,7 +274,7 @@ class APInt {
|
|||||||
initSlowCase(that);
|
initSlowCase(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
/// @brief Move Constructor.
|
/// @brief Move Constructor.
|
||||||
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
|
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
|
||||||
that.BitWidth = 0;
|
that.BitWidth = 0;
|
||||||
@ -427,7 +427,7 @@ class APInt {
|
|||||||
/// @returns the all-ones value for an APInt of the specified bit-width.
|
/// @returns the all-ones value for an APInt of the specified bit-width.
|
||||||
/// @brief Get the all-ones value.
|
/// @brief Get the all-ones value.
|
||||||
static APInt getAllOnesValue(unsigned numBits) {
|
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.
|
/// @returns the '0' value for an APInt of the specified bit-width.
|
||||||
@ -498,13 +498,24 @@ class APInt {
|
|||||||
if (loBitsSet == 0)
|
if (loBitsSet == 0)
|
||||||
return APInt(numBits, 0);
|
return APInt(numBits, 0);
|
||||||
if (loBitsSet == APINT_BITS_PER_WORD)
|
if (loBitsSet == APINT_BITS_PER_WORD)
|
||||||
return APInt(numBits, -1ULL);
|
return APInt(numBits, UINT64_MAX);
|
||||||
// For small values, return quickly.
|
// For small values, return quickly.
|
||||||
if (loBitsSet <= APINT_BITS_PER_WORD)
|
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);
|
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
|
/// \brief Determine if two APInts have the same value, after zero-extending
|
||||||
/// one of them (if needed!) to ensure that the bit-widths match.
|
/// one of them (if needed!) to ensure that the bit-widths match.
|
||||||
static bool isSameValue(const APInt &I1, const APInt &I2) {
|
static bool isSameValue(const APInt &I1, const APInt &I2) {
|
||||||
@ -601,7 +612,7 @@ class APInt {
|
|||||||
return AssignSlowCase(RHS);
|
return AssignSlowCase(RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
/// @brief Move assignment operator.
|
/// @brief Move assignment operator.
|
||||||
APInt& operator=(APInt&& that) {
|
APInt& operator=(APInt&& that) {
|
||||||
if (!isSingleWord())
|
if (!isSingleWord())
|
||||||
@ -799,16 +810,7 @@ class APInt {
|
|||||||
|
|
||||||
/// Signed divide this APInt by APInt RHS.
|
/// Signed divide this APInt by APInt RHS.
|
||||||
/// @brief Signed division function for APInt.
|
/// @brief Signed division function for APInt.
|
||||||
APInt sdiv(const APInt &RHS) const {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform an unsigned remainder operation on this APInt with RHS being the
|
/// Perform an unsigned remainder operation on this APInt with RHS being the
|
||||||
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
|
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
|
||||||
@ -821,16 +823,7 @@ class APInt {
|
|||||||
|
|
||||||
/// Signed remainder operation on APInt.
|
/// Signed remainder operation on APInt.
|
||||||
/// @brief Function for signed remainder operation.
|
/// @brief Function for signed remainder operation.
|
||||||
APInt srem(const APInt &RHS) const {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sometimes it is convenient to divide two APInt values and obtain both the
|
/// Sometimes it is convenient to divide two APInt values and obtain both the
|
||||||
/// quotient and remainder. This function does both operations in the same
|
/// quotient and remainder. This function does both operations in the same
|
||||||
@ -842,24 +835,9 @@ class APInt {
|
|||||||
APInt &Quotient, APInt &Remainder);
|
APInt &Quotient, APInt &Remainder);
|
||||||
|
|
||||||
static void sdivrem(const APInt &LHS, const APInt &RHS,
|
static void sdivrem(const APInt &LHS, const APInt &RHS,
|
||||||
APInt &Quotient, APInt &Remainder) {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Operations that return overflow indicators.
|
// Operations that return overflow indicators.
|
||||||
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
|
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
|
||||||
APInt uadd_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.
|
/// @brief Set every bit to 1.
|
||||||
void setAllBits() {
|
void setAllBits() {
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL = -1ULL;
|
VAL = UINT64_MAX;
|
||||||
else {
|
else {
|
||||||
// Set all the bits in all the words.
|
// Set all the bits in all the words.
|
||||||
for (unsigned i = 0; i < getNumWords(); ++i)
|
for (unsigned i = 0; i < getNumWords(); ++i)
|
||||||
pVal[i] = -1ULL;
|
pVal[i] = UINT64_MAX;
|
||||||
}
|
}
|
||||||
// Clear the unused ones
|
// Clear the unused ones
|
||||||
clearUnusedBits();
|
clearUnusedBits();
|
||||||
@ -1142,10 +1120,10 @@ class APInt {
|
|||||||
/// @brief Toggle every bit to its opposite value.
|
/// @brief Toggle every bit to its opposite value.
|
||||||
void flipAllBits() {
|
void flipAllBits() {
|
||||||
if (isSingleWord())
|
if (isSingleWord())
|
||||||
VAL ^= -1ULL;
|
VAL ^= UINT64_MAX;
|
||||||
else {
|
else {
|
||||||
for (unsigned i = 0; i < getNumWords(); ++i)
|
for (unsigned i = 0; i < getNumWords(); ++i)
|
||||||
pVal[i] ^= -1ULL;
|
pVal[i] ^= UINT64_MAX;
|
||||||
}
|
}
|
||||||
clearUnusedBits();
|
clearUnusedBits();
|
||||||
}
|
}
|
||||||
@ -1191,7 +1169,8 @@ class APInt {
|
|||||||
/// APInt. This is used in conjunction with getActiveData to extract the raw
|
/// APInt. This is used in conjunction with getActiveData to extract the raw
|
||||||
/// value of the APInt.
|
/// value of the APInt.
|
||||||
unsigned getActiveWords() const {
|
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
|
/// Computes the minimum bit width for this APInt while considering it to be
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_APSINT_H
|
#ifndef LLVM_ADT_APSINT_H
|
||||||
#define LLVM_APSINT_H
|
#define LLVM_ADT_APSINT_H
|
||||||
|
|
||||||
#include "llvm/ADT/APInt.h"
|
#include "llvm/ADT/APInt.h"
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ class APSInt : public APInt {
|
|||||||
bool IsUnsigned;
|
bool IsUnsigned;
|
||||||
public:
|
public:
|
||||||
/// Default constructor that creates an uninitialized APInt.
|
/// Default constructor that creates an uninitialized APInt.
|
||||||
explicit APSInt() {}
|
explicit APSInt() : IsUnsigned(false) {}
|
||||||
|
|
||||||
/// APSInt ctor - Create an APSInt with the specified width, default to
|
/// APSInt ctor - Create an APSInt with the specified width, default to
|
||||||
/// unsigned.
|
/// unsigned.
|
||||||
@ -161,11 +161,11 @@ class APSInt : public APInt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
APSInt& operator++() {
|
APSInt& operator++() {
|
||||||
static_cast<APInt&>(*this)++;
|
++(static_cast<APInt&>(*this));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
APSInt& operator--() {
|
APSInt& operator--() {
|
||||||
static_cast<APInt&>(*this)--;
|
--(static_cast<APInt&>(*this));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
APSInt operator++(int) {
|
APSInt operator++(int) {
|
||||||
|
@ -33,6 +33,8 @@ namespace llvm {
|
|||||||
typedef const T *const_iterator;
|
typedef const T *const_iterator;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
|
|
||||||
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The start of the array, in an external buffer.
|
/// The start of the array, in an external buffer.
|
||||||
const T *Data;
|
const T *Data;
|
||||||
@ -84,6 +86,9 @@ namespace llvm {
|
|||||||
iterator begin() const { return Data; }
|
iterator begin() const { return Data; }
|
||||||
iterator end() const { return Data + Length; }
|
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.
|
/// empty - Check if the array is empty.
|
||||||
bool empty() const { return Length == 0; }
|
bool empty() const { return Length == 0; }
|
||||||
|
|
||||||
@ -171,41 +176,41 @@ namespace llvm {
|
|||||||
|
|
||||||
/// Construct an empty ArrayRef.
|
/// Construct an empty ArrayRef.
|
||||||
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
|
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
|
||||||
|
|
||||||
/// Construct an MutableArrayRef from a single element.
|
/// Construct an MutableArrayRef from a single element.
|
||||||
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
|
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
|
||||||
|
|
||||||
/// Construct an MutableArrayRef from a pointer and length.
|
/// Construct an MutableArrayRef from a pointer and length.
|
||||||
/*implicit*/ MutableArrayRef(T *data, size_t length)
|
/*implicit*/ MutableArrayRef(T *data, size_t length)
|
||||||
: ArrayRef<T>(data, length) {}
|
: ArrayRef<T>(data, length) {}
|
||||||
|
|
||||||
/// Construct an MutableArrayRef from a range.
|
/// Construct an MutableArrayRef from a range.
|
||||||
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
|
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
|
||||||
|
|
||||||
/// Construct an MutableArrayRef from a SmallVector.
|
/// Construct an MutableArrayRef from a SmallVector.
|
||||||
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
|
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
|
||||||
: ArrayRef<T>(Vec) {}
|
: ArrayRef<T>(Vec) {}
|
||||||
|
|
||||||
/// Construct a MutableArrayRef from a std::vector.
|
/// Construct a MutableArrayRef from a std::vector.
|
||||||
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
|
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
|
||||||
: ArrayRef<T>(Vec) {}
|
: ArrayRef<T>(Vec) {}
|
||||||
|
|
||||||
/// Construct an MutableArrayRef from a C array.
|
/// Construct an MutableArrayRef from a C array.
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
/*implicit*/ MutableArrayRef(T (&Arr)[N])
|
/*implicit*/ MutableArrayRef(T (&Arr)[N])
|
||||||
: ArrayRef<T>(Arr) {}
|
: ArrayRef<T>(Arr) {}
|
||||||
|
|
||||||
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
|
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
|
||||||
|
|
||||||
iterator begin() const { return data(); }
|
iterator begin() const { return data(); }
|
||||||
iterator end() const { return data() + this->size(); }
|
iterator end() const { return data() + this->size(); }
|
||||||
|
|
||||||
/// front - Get the first element.
|
/// front - Get the first element.
|
||||||
T &front() const {
|
T &front() const {
|
||||||
assert(!this->empty());
|
assert(!this->empty());
|
||||||
return data()[0];
|
return data()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// back - Get the last element.
|
/// back - Get the last element.
|
||||||
T &back() const {
|
T &back() const {
|
||||||
assert(!this->empty());
|
assert(!this->empty());
|
||||||
@ -217,14 +222,14 @@ namespace llvm {
|
|||||||
assert(N <= this->size() && "Invalid specifier");
|
assert(N <= this->size() && "Invalid specifier");
|
||||||
return MutableArrayRef<T>(data()+N, this->size()-N);
|
return MutableArrayRef<T>(data()+N, this->size()-N);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// slice(n, m) - Chop off the first N elements of the array, and keep M
|
/// slice(n, m) - Chop off the first N elements of the array, and keep M
|
||||||
/// elements in the array.
|
/// elements in the array.
|
||||||
MutableArrayRef<T> slice(unsigned N, unsigned M) const {
|
MutableArrayRef<T> slice(unsigned N, unsigned M) const {
|
||||||
assert(N+M <= this->size() && "Invalid specifier");
|
assert(N+M <= this->size() && "Invalid specifier");
|
||||||
return MutableArrayRef<T>(data()+N, M);
|
return MutableArrayRef<T>(data()+N, M);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Operator Overloads
|
/// @name Operator Overloads
|
||||||
/// @{
|
/// @{
|
||||||
@ -301,5 +306,5 @@ namespace llvm {
|
|||||||
static const bool value = true;
|
static const bool value = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,7 +98,7 @@ class BitVector {
|
|||||||
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
|
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
BitVector(BitVector &&RHS)
|
BitVector(BitVector &&RHS)
|
||||||
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
|
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
|
||||||
RHS.Bits = 0;
|
RHS.Bits = 0;
|
||||||
@ -452,7 +452,7 @@ class BitVector {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
const BitVector &operator=(BitVector &&RHS) {
|
const BitVector &operator=(BitVector &&RHS) {
|
||||||
if (this == &RHS) return *this;
|
if (this == &RHS) return *this;
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
|
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
|
||||||
#define LLVM_ADT_DAGDELTAALGORITHM_H
|
#define LLVM_ADT_DAGDELTAALGORITHM_H
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#ifndef LLVM_ADT_DELTAALGORITHM_H
|
#ifndef LLVM_ADT_DELTAALGORITHM_H
|
||||||
#define LLVM_ADT_DELTAALGORITHM_H
|
#define LLVM_ADT_DELTAALGORITHM_H
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -14,20 +14,20 @@
|
|||||||
#ifndef LLVM_ADT_DENSEMAP_H
|
#ifndef LLVM_ADT_DENSEMAP_H
|
||||||
#define 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/AlignOf.h"
|
||||||
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||||
#include "llvm/Support/type_traits.h"
|
#include "llvm/Support/type_traits.h"
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
|
||||||
#include <new>
|
|
||||||
#include <utility>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iterator>
|
||||||
|
#include <new>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class DenseMapBase {
|
|||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
|
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
|
||||||
|
|
||||||
// If the capacity of the array is huge, and the # elements used is small,
|
// If the capacity of the array is huge, and the # elements used is small,
|
||||||
// shrink the array.
|
// shrink the array.
|
||||||
if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
|
if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
|
||||||
@ -159,6 +159,24 @@ class DenseMapBase {
|
|||||||
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
|
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.
|
/// insert - Range insertion of pairs.
|
||||||
template<typename InputIt>
|
template<typename InputIt>
|
||||||
void insert(InputIt I, InputIt E) {
|
void insert(InputIt I, InputIt E) {
|
||||||
@ -198,7 +216,7 @@ class DenseMapBase {
|
|||||||
return FindAndConstruct(Key).second;
|
return FindAndConstruct(Key).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
value_type& FindAndConstruct(KeyT &&Key) {
|
value_type& FindAndConstruct(KeyT &&Key) {
|
||||||
BucketT *TheBucket;
|
BucketT *TheBucket;
|
||||||
if (LookupBucketFor(Key, TheBucket))
|
if (LookupBucketFor(Key, TheBucket))
|
||||||
@ -383,7 +401,7 @@ class DenseMapBase {
|
|||||||
return TheBucket;
|
return TheBucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
|
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
|
||||||
BucketT *TheBucket) {
|
BucketT *TheBucket) {
|
||||||
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
|
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
|
||||||
@ -430,7 +448,8 @@ class DenseMapBase {
|
|||||||
incrementNumEntries();
|
incrementNumEntries();
|
||||||
|
|
||||||
// If we are writing over a tombstone, remember this.
|
// 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();
|
decrementNumTombstones();
|
||||||
|
|
||||||
return TheBucket;
|
return TheBucket;
|
||||||
@ -474,7 +493,6 @@ class DenseMapBase {
|
|||||||
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
|
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
|
||||||
// If we've already seen a tombstone while probing, fill it in instead
|
// If we've already seen a tombstone while probing, fill it in instead
|
||||||
// of the empty bucket we eventually probed to.
|
// of the empty bucket we eventually probed to.
|
||||||
if (FoundTombstone) ThisBucket = FoundTombstone;
|
|
||||||
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
|
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -531,13 +549,13 @@ class DenseMap
|
|||||||
init(NumInitBuckets);
|
init(NumInitBuckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseMap(const DenseMap &other) {
|
DenseMap(const DenseMap &other) : BaseT() {
|
||||||
init(0);
|
init(0);
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
DenseMap(DenseMap &&other) {
|
DenseMap(DenseMap &&other) : BaseT() {
|
||||||
init(0);
|
init(0);
|
||||||
swap(other);
|
swap(other);
|
||||||
}
|
}
|
||||||
@ -566,7 +584,7 @@ class DenseMap
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
DenseMap& operator=(DenseMap &&other) {
|
DenseMap& operator=(DenseMap &&other) {
|
||||||
this->destroyAll();
|
this->destroyAll();
|
||||||
operator delete(Buckets);
|
operator delete(Buckets);
|
||||||
@ -700,7 +718,7 @@ class SmallDenseMap
|
|||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
SmallDenseMap(SmallDenseMap &&other) {
|
SmallDenseMap(SmallDenseMap &&other) {
|
||||||
init(0);
|
init(0);
|
||||||
swap(other);
|
swap(other);
|
||||||
@ -795,7 +813,7 @@ class SmallDenseMap
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
SmallDenseMap& operator=(SmallDenseMap &&other) {
|
SmallDenseMap& operator=(SmallDenseMap &&other) {
|
||||||
this->destroyAll();
|
this->destroyAll();
|
||||||
deallocateBuckets();
|
deallocateBuckets();
|
||||||
@ -1027,7 +1045,7 @@ class DenseMapIterator {
|
|||||||
++Ptr;
|
++Ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename KeyT, typename ValueT, typename KeyInfoT>
|
template<typename KeyT, typename ValueT, typename KeyInfoT>
|
||||||
static inline size_t
|
static inline size_t
|
||||||
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
|
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
|
||||||
|
@ -32,8 +32,10 @@ class DenseSet {
|
|||||||
|
|
||||||
bool empty() const { return TheMap.empty(); }
|
bool empty() const { return TheMap.empty(); }
|
||||||
unsigned size() const { return TheMap.size(); }
|
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 resize(size_t Size) { TheMap.resize(Size); }
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
#define LLVM_ADT_DEPTHFIRSTITERATOR_H
|
#define LLVM_ADT_DEPTHFIRSTITERATOR_H
|
||||||
|
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
|
||||||
#include "llvm/ADT/PointerIntPair.h"
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
#ifndef LLVM_ADT_FOLDINGSET_H
|
#ifndef LLVM_ADT_FOLDINGSET_H
|
||||||
#define LLVM_ADT_FOLDINGSET_H
|
#define LLVM_ADT_FOLDINGSET_H
|
||||||
|
|
||||||
#include "llvm/Support/DataTypes.h"
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class APFloat;
|
class APFloat;
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
|
#ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H
|
||||||
#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
|
#define LLVM_ADT_IMMUTABLEINTERVALMAP_H
|
||||||
|
|
||||||
#include "llvm/ADT/ImmutableMap.h"
|
#include "llvm/ADT/ImmutableMap.h"
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_IMLIST_H
|
#ifndef LLVM_ADT_IMMUTABLELIST_H
|
||||||
#define LLVM_ADT_IMLIST_H
|
#define LLVM_ADT_IMMUTABLELIST_H
|
||||||
|
|
||||||
#include "llvm/Support/Allocator.h"
|
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_IMMAP_H
|
#ifndef LLVM_ADT_IMMUTABLEMAP_H
|
||||||
#define LLVM_ADT_IMMAP_H
|
#define LLVM_ADT_IMMUTABLEMAP_H
|
||||||
|
|
||||||
#include "llvm/ADT/ImmutableSet.h"
|
#include "llvm/ADT/ImmutableSet.h"
|
||||||
|
|
||||||
@ -211,17 +211,22 @@ class ImmutableMap {
|
|||||||
friend class ImmutableMap;
|
friend class ImmutableMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
value_type_ref operator*() const { return itr->getValue(); }
|
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type;
|
||||||
value_type* operator->() const { return &itr->getValue(); }
|
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; }
|
key_type_ref getKey() const { return itr->getValue().first; }
|
||||||
data_type_ref getData() const { return itr->getValue().second; }
|
data_type_ref getData() const { return itr->getValue().second; }
|
||||||
|
|
||||||
|
|
||||||
iterator& operator++() { ++itr; return *this; }
|
iterator& operator++() { ++itr; return *this; }
|
||||||
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
||||||
iterator& operator--() { --itr; return *this; }
|
iterator& operator--() { --itr; return *this; }
|
||||||
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
|
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; }
|
||||||
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) {
|
Factory(F) {
|
||||||
if (Root) { Root->retain(); }
|
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)
|
ImmutableMapRef(const ImmutableMapRef &X)
|
||||||
: Root(X.Root),
|
: Root(X.Root),
|
||||||
@ -318,12 +330,20 @@ class ImmutableMapRef {
|
|||||||
return ImmutableMapRef(0, F);
|
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));
|
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
|
||||||
return ImmutableMapRef(NewT, Factory);
|
return ImmutableMapRef(NewT, Factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmutableMapRef remove(key_type_ref K) {
|
ImmutableMapRef remove(key_type_ref K) const {
|
||||||
TreeTy *NewT = Factory->remove(Root, K);
|
TreeTy *NewT = Factory->remove(Root, K);
|
||||||
return ImmutableMapRef(NewT, Factory);
|
return ImmutableMapRef(NewT, Factory);
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_IMSET_H
|
#ifndef LLVM_ADT_IMMUTABLESET_H
|
||||||
#define LLVM_ADT_IMSET_H
|
#define LLVM_ADT_IMMUTABLESET_H
|
||||||
|
|
||||||
#include "llvm/Support/Allocator.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -1054,18 +1054,27 @@ class ImmutableSet {
|
|||||||
|
|
||||||
class iterator {
|
class iterator {
|
||||||
typename TreeTy::iterator itr;
|
typename TreeTy::iterator itr;
|
||||||
|
|
||||||
|
iterator() {}
|
||||||
iterator(TreeTy* t) : itr(t) {}
|
iterator(TreeTy* t) : itr(t) {}
|
||||||
friend class ImmutableSet<ValT,ValInfo>;
|
friend class ImmutableSet<ValT,ValInfo>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iterator() {}
|
typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type;
|
||||||
inline value_type_ref operator*() const { return itr->getValue(); }
|
typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference;
|
||||||
inline iterator& operator++() { ++itr; return *this; }
|
typedef typename iterator::value_type *pointer;
|
||||||
inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
inline iterator& operator--() { --itr; return *this; }
|
|
||||||
inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
|
typename iterator::reference operator*() const { return itr->getValue(); }
|
||||||
inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
|
typename iterator::pointer operator->() const { return &(operator*()); }
|
||||||
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
|
|
||||||
inline value_type *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); }
|
iterator begin() const { return iterator(Root); }
|
||||||
|
@ -99,8 +99,8 @@
|
|||||||
#ifndef LLVM_ADT_INTERVALMAP_H
|
#ifndef LLVM_ADT_INTERVALMAP_H
|
||||||
#define LLVM_ADT_INTERVALMAP_H
|
#define LLVM_ADT_INTERVALMAP_H
|
||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
|
||||||
#include "llvm/ADT/PointerIntPair.h"
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/RecyclingAllocator.h"
|
#include "llvm/Support/RecyclingAllocator.h"
|
||||||
#include <iterator>
|
#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.
|
/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
|
||||||
/// It should be considered private to the implementation.
|
/// It should be considered private to the implementation.
|
||||||
namespace IntervalMapImpl {
|
namespace IntervalMapImpl {
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
|
#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
|
||||||
#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
|
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
|
||||||
|
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
@ -123,7 +123,7 @@ namespace llvm {
|
|||||||
retain();
|
retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
|
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
|
||||||
S.Obj = 0;
|
S.Obj = 0;
|
||||||
}
|
}
|
||||||
@ -226,13 +226,13 @@ namespace llvm {
|
|||||||
|
|
||||||
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
|
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
|
||||||
typedef T* SimpleType;
|
typedef T* SimpleType;
|
||||||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
|
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
|
||||||
return Val.getPtr();
|
return Val.getPtr();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
|
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
|
||||||
typedef T* SimpleType;
|
typedef /*const*/ T* SimpleType;
|
||||||
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
|
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
|
||||||
return Val.getPtr();
|
return Val.getPtr();
|
||||||
}
|
}
|
||||||
@ -240,4 +240,4 @@ namespace llvm {
|
|||||||
|
|
||||||
} // end 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/ArrayRef.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -63,6 +64,11 @@ class MapVector {
|
|||||||
return Vector.empty();
|
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() {
|
void clear() {
|
||||||
Map.clear();
|
Map.clear();
|
||||||
Vector.clear();
|
Vector.clear();
|
||||||
@ -79,10 +85,46 @@ class MapVector {
|
|||||||
return Vector[I].second;
|
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 {
|
unsigned count(const KeyT &Key) const {
|
||||||
typename MapType::const_iterator Pos = Map.find(Key);
|
typename MapType::const_iterator Pos = Map.find(Key);
|
||||||
return Pos == Map.end()? 0 : 1;
|
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
|
#ifndef LLVM_ADT_NULLABLEPTR_H
|
||||||
#define LLVM_ADT_NULLABLE_PTR_H
|
#define LLVM_ADT_NULLABLEPTR_H
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -13,13 +13,15 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_OPTIONAL
|
#ifndef LLVM_ADT_OPTIONAL_H
|
||||||
#define LLVM_ADT_OPTIONAL
|
#define LLVM_ADT_OPTIONAL_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/None.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include "llvm/Support/AlignOf.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -27,54 +29,116 @@ namespace llvm {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Optional {
|
class Optional {
|
||||||
T x;
|
AlignedCharArrayUnion<T> storage;
|
||||||
unsigned hasVal : 1;
|
bool hasVal;
|
||||||
public:
|
public:
|
||||||
explicit Optional() : x(), hasVal(false) {}
|
Optional(NoneType) : hasVal(false) {}
|
||||||
Optional(const T &y) : x(y), hasVal(true) {}
|
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
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
|
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
|
#endif
|
||||||
|
|
||||||
static inline Optional create(const T* y) {
|
static inline Optional create(const T* y) {
|
||||||
return y ? Optional(*y) : Optional();
|
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) {
|
Optional &operator=(const T &y) {
|
||||||
x = y;
|
if (hasVal)
|
||||||
hasVal = true;
|
**this = y;
|
||||||
|
else {
|
||||||
|
new (storage.buffer) T(y);
|
||||||
|
hasVal = true;
|
||||||
|
}
|
||||||
return *this;
|
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; }
|
bool hasValue() const { return hasVal; }
|
||||||
const T* operator->() const { return getPointer(); }
|
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 isPodLike;
|
||||||
|
template <typename T> struct isPodLike<Optional<T> > {
|
||||||
template <typename T>
|
// An Optional<T> is pod-like if T is.
|
||||||
struct simplify_type<const Optional<T> > {
|
static const bool value = isPodLike<T>::value;
|
||||||
typedef const T* SimpleType;
|
|
||||||
static SimpleType getSimplifiedValue(const Optional<T> &Val) {
|
|
||||||
return Val.getPointer();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
/// \brief Poison comparison between two \c Optional objects. Clients needs to
|
||||||
/// explicitly compare the underlying values and account for empty \c Optional
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator==(const Optional<T> &X, const Optional<U> &Y);
|
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
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator!=(const Optional<T> &X, const Optional<U> &Y);
|
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
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator<(const Optional<T> &X, const Optional<U> &Y);
|
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
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator<=(const Optional<T> &X, const Optional<U> &Y);
|
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
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator>=(const Optional<T> &X, const Optional<U> &Y);
|
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
|
/// explicitly compare the underlying values and account for empty \c Optional
|
||||||
/// objects.
|
/// 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.
|
/// errors at compile time.
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void operator>(const Optional<T> &X, const Optional<U> &Y);
|
void operator>(const Optional<T> &X, const Optional<U> &Y);
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_OWNING_PTR_H
|
#ifndef LLVM_ADT_OWNINGPTR_H
|
||||||
#define LLVM_ADT_OWNING_PTR_H
|
#define LLVM_ADT_OWNINGPTR_H
|
||||||
|
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -32,7 +32,7 @@ class OwningPtr {
|
|||||||
public:
|
public:
|
||||||
explicit OwningPtr(T *P = 0) : Ptr(P) {}
|
explicit OwningPtr(T *P = 0) : Ptr(P) {}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
|
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
|
||||||
|
|
||||||
OwningPtr &operator=(OwningPtr &&Other) {
|
OwningPtr &operator=(OwningPtr &&Other) {
|
||||||
@ -95,7 +95,7 @@ class OwningArrayPtr {
|
|||||||
public:
|
public:
|
||||||
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
|
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
|
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
|
||||||
|
|
||||||
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
|
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
|
||||||
|
@ -57,11 +57,13 @@ class PointerIntPair {
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
PointerIntPair() : Value(0) {}
|
PointerIntPair() : Value(0) {}
|
||||||
PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
|
PointerIntPair(PointerTy Ptr, IntType Int) {
|
||||||
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
|
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
|
||||||
"PointerIntPair formed with integer size too large for pointer");
|
"PointerIntPair formed with integer size too large for pointer");
|
||||||
setPointer(Ptr);
|
setPointerAndInt(Ptr, Int);
|
||||||
setInt(Int);
|
}
|
||||||
|
explicit PointerIntPair(PointerTy Ptr) {
|
||||||
|
initWithPointer(Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerTy getPointer() const {
|
PointerTy getPointer() const {
|
||||||
@ -91,6 +93,25 @@ class PointerIntPair {
|
|||||||
Value |= IntVal << IntShift; // Set new integer.
|
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 {
|
PointerTy const *getAddrOfPointer() const {
|
||||||
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
|
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
|
||||||
}
|
}
|
||||||
|
@ -95,15 +95,11 @@ namespace llvm {
|
|||||||
public:
|
public:
|
||||||
PointerUnion() {}
|
PointerUnion() {}
|
||||||
|
|
||||||
PointerUnion(PT1 V) {
|
PointerUnion(PT1 V) : Val(
|
||||||
Val.setPointer(
|
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
|
||||||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
|
|
||||||
Val.setInt(0);
|
|
||||||
}
|
}
|
||||||
PointerUnion(PT2 V) {
|
PointerUnion(PT2 V) : Val(
|
||||||
Val.setPointer(
|
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
|
||||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
|
|
||||||
Val.setInt(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isNull - Return true if the pointer held in the union is null,
|
/// 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
|
/// Assignment operators - Allow assigning into this union from either
|
||||||
/// pointer type, setting the discriminator to remember what it came from.
|
/// pointer type, setting the discriminator to remember what it came from.
|
||||||
const PointerUnion &operator=(const PT1 &RHS) {
|
const PointerUnion &operator=(const PT1 &RHS) {
|
||||||
Val.setPointer(
|
Val.initWithPointer(
|
||||||
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
|
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
|
||||||
Val.setInt(0);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
const PointerUnion &operator=(const PT2 &RHS) {
|
const PointerUnion &operator=(const PT2 &RHS) {
|
||||||
Val.setPointer(
|
Val.setPointerAndInt(
|
||||||
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
|
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
|
||||||
Val.setInt(1);
|
1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ class ReversePostOrderTraversal {
|
|||||||
typedef typename GT::NodeType NodeType;
|
typedef typename GT::NodeType NodeType;
|
||||||
std::vector<NodeType*> Blocks; // Block list in normal PO order
|
std::vector<NodeType*> Blocks; // Block list in normal PO order
|
||||||
inline void Initialize(NodeType *BB) {
|
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:
|
public:
|
||||||
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
|
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_PRIORITY_QUEUE_H
|
#ifndef LLVM_ADT_PRIORITYQUEUE_H
|
||||||
#define LLVM_ADT_PRIORITY_QUEUE_H
|
#define LLVM_ADT_PRIORITYQUEUE_H
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
#ifndef LLVM_ADT_SCCITERATOR_H
|
#ifndef LLVM_ADT_SCCITERATOR_H
|
||||||
#define LLVM_ADT_SCCITERATOR_H
|
#define LLVM_ADT_SCCITERATOR_H
|
||||||
|
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -246,10 +246,10 @@ inline int array_pod_sort_comparator(const void *P1, const void *P2) {
|
|||||||
return 0;
|
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.
|
/// get type deduction of T right.
|
||||||
template<typename T>
|
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*) {
|
(const void*, const void*) {
|
||||||
return array_pod_sort_comparator<T>;
|
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.
|
// Don't dereference start iterator of empty sequence.
|
||||||
if (Start == End) return;
|
if (Start == End) return;
|
||||||
qsort(&*Start, End-Start, sizeof(*Start),
|
qsort(&*Start, End-Start, sizeof(*Start),
|
||||||
get_array_pad_sort_comparator(*Start));
|
get_array_pod_sort_comparator(*Start));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class IteratorTy>
|
template<class IteratorTy>
|
||||||
|
@ -153,7 +153,7 @@ class SmallBitVector {
|
|||||||
switchToLarge(new BitVector(*RHS.getPointer()));
|
switchToLarge(new BitVector(*RHS.getPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
|
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
|
||||||
RHS.X = 1;
|
RHS.X = 1;
|
||||||
}
|
}
|
||||||
@ -178,9 +178,9 @@ class SmallBitVector {
|
|||||||
unsigned count() const {
|
unsigned count() const {
|
||||||
if (isSmall()) {
|
if (isSmall()) {
|
||||||
uintptr_t Bits = getSmallBits();
|
uintptr_t Bits = getSmallBits();
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
if (NumBaseBits == 32)
|
||||||
return CountPopulation_32(Bits);
|
return CountPopulation_32(Bits);
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
if (NumBaseBits == 64)
|
||||||
return CountPopulation_64(Bits);
|
return CountPopulation_64(Bits);
|
||||||
llvm_unreachable("Unsupported!");
|
llvm_unreachable("Unsupported!");
|
||||||
}
|
}
|
||||||
@ -215,9 +215,9 @@ class SmallBitVector {
|
|||||||
uintptr_t Bits = getSmallBits();
|
uintptr_t Bits = getSmallBits();
|
||||||
if (Bits == 0)
|
if (Bits == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
if (NumBaseBits == 32)
|
||||||
return CountTrailingZeros_32(Bits);
|
return CountTrailingZeros_32(Bits);
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
if (NumBaseBits == 64)
|
||||||
return CountTrailingZeros_64(Bits);
|
return CountTrailingZeros_64(Bits);
|
||||||
llvm_unreachable("Unsupported!");
|
llvm_unreachable("Unsupported!");
|
||||||
}
|
}
|
||||||
@ -233,9 +233,9 @@ class SmallBitVector {
|
|||||||
Bits &= ~uintptr_t(0) << (Prev + 1);
|
Bits &= ~uintptr_t(0) << (Prev + 1);
|
||||||
if (Bits == 0 || Prev + 1 >= getSmallSize())
|
if (Bits == 0 || Prev + 1 >= getSmallSize())
|
||||||
return -1;
|
return -1;
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
if (NumBaseBits == 32)
|
||||||
return CountTrailingZeros_32(Bits);
|
return CountTrailingZeros_32(Bits);
|
||||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
if (NumBaseBits == 64)
|
||||||
return CountTrailingZeros_64(Bits);
|
return CountTrailingZeros_64(Bits);
|
||||||
llvm_unreachable("Unsupported!");
|
llvm_unreachable("Unsupported!");
|
||||||
}
|
}
|
||||||
@ -472,7 +472,7 @@ class SmallBitVector {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
const SmallBitVector &operator=(SmallBitVector &&RHS) {
|
const SmallBitVector &operator=(SmallBitVector &&RHS) {
|
||||||
if (this != &RHS) {
|
if (this != &RHS) {
|
||||||
clear();
|
clear();
|
||||||
|
@ -54,8 +54,6 @@ class SmallPtrSetImpl {
|
|||||||
/// then the set is in 'small mode'.
|
/// then the set is in 'small mode'.
|
||||||
const void **CurArray;
|
const void **CurArray;
|
||||||
/// CurArraySize - The allocated size of CurArray, always a power of two.
|
/// 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;
|
unsigned CurArraySize;
|
||||||
|
|
||||||
// If small, this is # elts allocated consecutively
|
// If small, this is # elts allocated consecutively
|
||||||
@ -68,9 +66,6 @@ class SmallPtrSetImpl {
|
|||||||
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
|
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
|
||||||
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
|
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
|
||||||
"Initial size must be a power of two!");
|
"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();
|
clear();
|
||||||
}
|
}
|
||||||
~SmallPtrSetImpl();
|
~SmallPtrSetImpl();
|
||||||
@ -147,9 +142,11 @@ class SmallPtrSetImpl {
|
|||||||
class SmallPtrSetIteratorImpl {
|
class SmallPtrSetIteratorImpl {
|
||||||
protected:
|
protected:
|
||||||
const void *const *Bucket;
|
const void *const *Bucket;
|
||||||
|
const void *const *End;
|
||||||
public:
|
public:
|
||||||
explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
|
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
|
||||||
AdvanceIfNotValid();
|
: Bucket(BP), End(E) {
|
||||||
|
AdvanceIfNotValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
|
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
|
/// that is. This is guaranteed to stop because the end() bucket is marked
|
||||||
/// valid.
|
/// valid.
|
||||||
void AdvanceIfNotValid() {
|
void AdvanceIfNotValid() {
|
||||||
while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
|
assert(Bucket <= End);
|
||||||
*Bucket == SmallPtrSetImpl::getTombstoneMarker())
|
while (Bucket != End &&
|
||||||
|
(*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
|
||||||
|
*Bucket == SmallPtrSetImpl::getTombstoneMarker()))
|
||||||
++Bucket;
|
++Bucket;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -182,12 +181,13 @@ class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
|
|||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
typedef std::forward_iterator_tag iterator_category;
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
|
||||||
explicit SmallPtrSetIterator(const void *const *BP)
|
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
|
||||||
: SmallPtrSetIteratorImpl(BP) {}
|
: SmallPtrSetIteratorImpl(BP, E) {}
|
||||||
|
|
||||||
// Most methods provided by baseclass.
|
// Most methods provided by baseclass.
|
||||||
|
|
||||||
const PtrTy operator*() const {
|
const PtrTy operator*() const {
|
||||||
|
assert(Bucket < End);
|
||||||
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
|
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,9 +236,8 @@ template<class PtrType, unsigned SmallSize>
|
|||||||
class SmallPtrSet : public SmallPtrSetImpl {
|
class SmallPtrSet : public SmallPtrSetImpl {
|
||||||
// Make sure that SmallSize is a power of two, round up if not.
|
// Make sure that SmallSize is a power of two, round up if not.
|
||||||
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
|
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
|
||||||
/// SmallStorage - Fixed size storage used in 'small mode'. The extra element
|
/// SmallStorage - Fixed size storage used in 'small mode'.
|
||||||
/// ensures that the end iterator actually points to valid memory.
|
const void *SmallStorage[SmallSizePowTwo];
|
||||||
const void *SmallStorage[SmallSizePowTwo+1];
|
|
||||||
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
|
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
|
||||||
public:
|
public:
|
||||||
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
|
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
|
||||||
@ -275,10 +274,10 @@ class SmallPtrSet : public SmallPtrSetImpl {
|
|||||||
typedef SmallPtrSetIterator<PtrType> iterator;
|
typedef SmallPtrSetIterator<PtrType> iterator;
|
||||||
typedef SmallPtrSetIterator<PtrType> const_iterator;
|
typedef SmallPtrSetIterator<PtrType> const_iterator;
|
||||||
inline iterator begin() const {
|
inline iterator begin() const {
|
||||||
return iterator(CurArray);
|
return iterator(CurArray, CurArray+CurArraySize);
|
||||||
}
|
}
|
||||||
inline iterator end() const {
|
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
|
// Allow assignment from any smallptrset with the same element type even if it
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#ifndef LLVM_ADT_SMALLSET_H
|
#ifndef LLVM_ADT_SMALLSET_H
|
||||||
#define LLVM_ADT_SMALLSET_H
|
#define LLVM_ADT_SMALLSET_H
|
||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -55,6 +55,7 @@ class SmallSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// insert - Insert an element into the set if it isn't already there.
|
/// 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) {
|
bool insert(const T &V) {
|
||||||
if (!isSmall())
|
if (!isSmall())
|
||||||
return Set.insert(V).second;
|
return Set.insert(V).second;
|
||||||
|
@ -77,7 +77,7 @@ class SmallString : public SmallVector<char, InternalLen> {
|
|||||||
void append(in_iter S, in_iter E) {
|
void append(in_iter S, in_iter E) {
|
||||||
SmallVectorImpl<char>::append(S, E);
|
SmallVectorImpl<char>::append(S, E);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(size_t NumInputs, char Elt) {
|
void append(size_t NumInputs, char Elt) {
|
||||||
SmallVectorImpl<char>::append(NumInputs, Elt);
|
SmallVectorImpl<char>::append(NumInputs, Elt);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "llvm/Support/AlignOf.h"
|
#include "llvm/Support/AlignOf.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/type_traits.h"
|
#include "llvm/Support/type_traits.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -145,16 +146,20 @@ class SmallVectorTemplateCommon : public SmallVectorBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference front() {
|
reference front() {
|
||||||
|
assert(!empty());
|
||||||
return begin()[0];
|
return begin()[0];
|
||||||
}
|
}
|
||||||
const_reference front() const {
|
const_reference front() const {
|
||||||
|
assert(!empty());
|
||||||
return begin()[0];
|
return begin()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
reference back() {
|
reference back() {
|
||||||
|
assert(!empty());
|
||||||
return end()[-1];
|
return end()[-1];
|
||||||
}
|
}
|
||||||
const_reference back() const {
|
const_reference back() const {
|
||||||
|
assert(!empty());
|
||||||
return end()[-1];
|
return end()[-1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -178,7 +183,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
|||||||
/// std::move, but not all stdlibs actually provide that.
|
/// std::move, but not all stdlibs actually provide that.
|
||||||
template<typename It1, typename It2>
|
template<typename It1, typename It2>
|
||||||
static It2 move(It1 I, It1 E, It2 Dest) {
|
static It2 move(It1 I, It1 E, It2 Dest) {
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
for (; I != E; ++I, ++Dest)
|
for (; I != E; ++I, ++Dest)
|
||||||
*Dest = ::std::move(*I);
|
*Dest = ::std::move(*I);
|
||||||
return Dest;
|
return Dest;
|
||||||
@ -193,7 +198,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
|||||||
/// std::move_backward, but not all stdlibs actually provide that.
|
/// std::move_backward, but not all stdlibs actually provide that.
|
||||||
template<typename It1, typename It2>
|
template<typename It1, typename It2>
|
||||||
static It2 move_backward(It1 I, It1 E, It2 Dest) {
|
static It2 move_backward(It1 I, It1 E, It2 Dest) {
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
while (I != E)
|
while (I != E)
|
||||||
*--Dest = ::std::move(*--E);
|
*--Dest = ::std::move(*--E);
|
||||||
return Dest;
|
return Dest;
|
||||||
@ -206,7 +211,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
|||||||
/// memory starting with "Dest", constructing elements as needed.
|
/// memory starting with "Dest", constructing elements as needed.
|
||||||
template<typename It1, typename It2>
|
template<typename It1, typename It2>
|
||||||
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
|
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)
|
for (; I != E; ++I, ++Dest)
|
||||||
::new ((void*) &*Dest) T(::std::move(*I));
|
::new ((void*) &*Dest) T(::std::move(*I));
|
||||||
#else
|
#else
|
||||||
@ -239,7 +244,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
|
|||||||
goto Retry;
|
goto Retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
void push_back(T &&Elt) {
|
void push_back(T &&Elt) {
|
||||||
if (this->EndX < this->CapacityX) {
|
if (this->EndX < this->CapacityX) {
|
||||||
Retry:
|
Retry:
|
||||||
@ -263,7 +268,8 @@ template <typename T, bool isPodLike>
|
|||||||
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
|
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
|
||||||
size_t CurCapacity = this->capacity();
|
size_t CurCapacity = this->capacity();
|
||||||
size_t CurSize = this->size();
|
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)
|
if (NewCapacity < MinSize)
|
||||||
NewCapacity = MinSize;
|
NewCapacity = MinSize;
|
||||||
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
|
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
|
||||||
@ -365,7 +371,7 @@ template <typename T>
|
|||||||
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
||||||
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
|
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
|
||||||
|
|
||||||
SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
|
SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
|
||||||
public:
|
public:
|
||||||
typedef typename SuperClass::iterator iterator;
|
typedef typename SuperClass::iterator iterator;
|
||||||
typedef typename SuperClass::size_type size_type;
|
typedef typename SuperClass::size_type size_type;
|
||||||
@ -422,7 +428,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
T pop_back_val() {
|
T pop_back_val() {
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
T Result = ::std::move(this->back());
|
T Result = ::std::move(this->back());
|
||||||
#else
|
#else
|
||||||
T Result = this->back();
|
T Result = this->back();
|
||||||
@ -495,7 +501,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
|||||||
return(N);
|
return(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
iterator insert(iterator I, T &&Elt) {
|
iterator insert(iterator I, T &&Elt) {
|
||||||
if (I == this->end()) { // Important special case for empty vector.
|
if (I == this->end()) { // Important special case for empty vector.
|
||||||
this->push_back(::std::move(Elt));
|
this->push_back(::std::move(Elt));
|
||||||
@ -667,7 +673,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
|
|||||||
|
|
||||||
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
|
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -787,7 +793,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
|
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
|
||||||
// Avoid self-assignment.
|
// Avoid self-assignment.
|
||||||
@ -898,7 +904,7 @@ class SmallVector : public SmallVectorImpl<T> {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
|
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
|
||||||
if (!RHS.empty())
|
if (!RHS.empty())
|
||||||
SmallVectorImpl<T>::operator=(::std::move(RHS));
|
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
|
#ifndef LLVM_ADT_SPARSESET_H
|
||||||
#define LLVM_ADT_SPARSESET_H
|
#define LLVM_ADT_SPARSESET_H
|
||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
@ -51,7 +51,9 @@ class Statistic {
|
|||||||
|
|
||||||
// Allow use of this class as the value itself.
|
// Allow use of this class as the value itself.
|
||||||
operator unsigned() const { return Value; }
|
operator unsigned() const { return Value; }
|
||||||
const Statistic &operator=(unsigned Val) {
|
|
||||||
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
||||||
|
const Statistic &operator=(unsigned Val) {
|
||||||
Value = Val;
|
Value = Val;
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
@ -106,6 +108,46 @@ class Statistic {
|
|||||||
return init();
|
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:
|
protected:
|
||||||
Statistic &init() {
|
Statistic &init() {
|
||||||
bool tmp = Initialized;
|
bool tmp = Initialized;
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#ifndef LLVM_ADT_STRINGEXTRAS_H
|
#ifndef LLVM_ADT_STRINGEXTRAS_H
|
||||||
#define LLVM_ADT_STRINGEXTRAS_H
|
#define LLVM_ADT_STRINGEXTRAS_H
|
||||||
|
|
||||||
#include "llvm/Support/DataTypes.h"
|
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template<typename T> class SmallVectorImpl;
|
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;
|
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
|
/// 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
|
/// 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):
|
/// like this: (note that the buffer must be large enough to handle any number):
|
||||||
|
@ -53,7 +53,7 @@ class StringMapEntryBase {
|
|||||||
class StringMapImpl {
|
class StringMapImpl {
|
||||||
protected:
|
protected:
|
||||||
// Array of NumBuckets pointers to entries, null pointers are holes.
|
// 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.
|
// by an array of the actual hash values as unsigned integers.
|
||||||
StringMapEntryBase **TheTable;
|
StringMapEntryBase **TheTable;
|
||||||
unsigned NumBuckets;
|
unsigned NumBuckets;
|
||||||
@ -171,7 +171,6 @@ class StringMapEntry : public StringMapEntryBase {
|
|||||||
return Create(KeyStart, KeyEnd, Allocator, 0);
|
return Create(KeyStart, KeyEnd, Allocator, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Create - Create a StringMapEntry with normal malloc/free.
|
/// Create - Create a StringMapEntry with normal malloc/free.
|
||||||
template<typename InitType>
|
template<typename InitType>
|
||||||
static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
|
static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
|
||||||
@ -204,7 +203,6 @@ class StringMapEntry : public StringMapEntryBase {
|
|||||||
return *reinterpret_cast<StringMapEntry*>(Ptr);
|
return *reinterpret_cast<StringMapEntry*>(Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
|
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
|
||||||
/// specified allocator.
|
/// specified allocator.
|
||||||
template<typename AllocatorTy>
|
template<typename AllocatorTy>
|
||||||
@ -239,6 +237,10 @@ class StringMap : public StringMapImpl {
|
|||||||
explicit StringMap(AllocatorTy A)
|
explicit StringMap(AllocatorTy A)
|
||||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(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)
|
StringMap(const StringMap &RHS)
|
||||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
|
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
|
||||||
assert(RHS.empty() &&
|
assert(RHS.empty() &&
|
||||||
@ -290,7 +292,7 @@ class StringMap : public StringMapImpl {
|
|||||||
return const_iterator(TheTable+Bucket, true);
|
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.
|
/// constructed value if no such entry exists.
|
||||||
ValueTy lookup(StringRef Key) const {
|
ValueTy lookup(StringRef Key) const {
|
||||||
const_iterator it = find(Key);
|
const_iterator it = find(Key);
|
||||||
@ -336,8 +338,8 @@ class StringMap : public StringMapImpl {
|
|||||||
StringMapEntryBase *&Bucket = TheTable[I];
|
StringMapEntryBase *&Bucket = TheTable[I];
|
||||||
if (Bucket && Bucket != getTombstoneVal()) {
|
if (Bucket && Bucket != getTombstoneVal()) {
|
||||||
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
|
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
|
||||||
Bucket = 0;
|
|
||||||
}
|
}
|
||||||
|
Bucket = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NumItems = 0;
|
NumItems = 0;
|
||||||
@ -427,7 +429,7 @@ class StringMapConstIterator {
|
|||||||
return Ptr != RHS.Ptr;
|
return Ptr != RHS.Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StringMapConstIterator& operator++() { // Preincrement
|
inline StringMapConstIterator& operator++() { // Preincrement
|
||||||
++Ptr;
|
++Ptr;
|
||||||
AdvancePastEmptyBuckets();
|
AdvancePastEmptyBuckets();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#define LLVM_ADT_STRINGREF_H
|
#define LLVM_ADT_STRINGREF_H
|
||||||
|
|
||||||
#include "llvm/Support/type_traits.h"
|
#include "llvm/Support/type_traits.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -58,14 +57,14 @@ namespace llvm {
|
|||||||
// integer works around this bug.
|
// integer works around this bug.
|
||||||
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
|
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; }
|
static size_t max(size_t a, size_t b) { return a > b ? a : b; }
|
||||||
|
|
||||||
// Workaround memcmp issue with null pointers (undefined behavior)
|
// Workaround memcmp issue with null pointers (undefined behavior)
|
||||||
// by providing a specialized version
|
// by providing a specialized version
|
||||||
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
|
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
|
||||||
if (Length == 0) { return 0; }
|
if (Length == 0) { return 0; }
|
||||||
return ::memcmp(Lhs,Rhs,Length);
|
return ::memcmp(Lhs,Rhs,Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @name Constructors
|
/// @name Constructors
|
||||||
/// @{
|
/// @{
|
||||||
@ -388,7 +387,7 @@ namespace llvm {
|
|||||||
Start = min(Start, Length);
|
Start = min(Start, Length);
|
||||||
return StringRef(Data + Start, min(N, Length - Start));
|
return StringRef(Data + Start, min(N, Length - Start));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a StringRef equal to 'this' but with the first \p N elements
|
/// Return a StringRef equal to 'this' but with the first \p N elements
|
||||||
/// dropped.
|
/// dropped.
|
||||||
StringRef drop_front(unsigned N = 1) const {
|
StringRef drop_front(unsigned N = 1) const {
|
||||||
@ -536,7 +535,7 @@ namespace llvm {
|
|||||||
return LHS.compare(RHS) != -1;
|
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());
|
return buffer.append(string.data(), string.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,23 +18,25 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
/// StringSet - A wrapper for StringMap that provides set-like
|
/// StringSet - A wrapper for StringMap that provides set-like functionality.
|
||||||
/// functionality. Only insert() and count() methods are used by my
|
|
||||||
/// code.
|
|
||||||
template <class AllocatorTy = llvm::MallocAllocator>
|
template <class AllocatorTy = llvm::MallocAllocator>
|
||||||
class StringSet : public llvm::StringMap<char, AllocatorTy> {
|
class StringSet : public llvm::StringMap<char, AllocatorTy> {
|
||||||
typedef llvm::StringMap<char, AllocatorTy> base;
|
typedef llvm::StringMap<char, AllocatorTy> base;
|
||||||
public:
|
public:
|
||||||
bool insert(StringRef InLang) {
|
|
||||||
assert(!InLang.empty());
|
/// insert - Insert the specified key into the set. If the key already
|
||||||
const char *KeyStart = InLang.data();
|
/// exists in the set, return false and ignore the request, otherwise insert
|
||||||
const char *KeyEnd = KeyStart + InLang.size();
|
/// it and return true.
|
||||||
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
|
bool insert(StringRef Key) {
|
||||||
Create(KeyStart, KeyEnd, base::getAllocator(), '+');
|
// Get or create the map entry for the key; if it doesn't exist the value
|
||||||
if (!base::insert(Entry)) {
|
// type will be default constructed which we use to detect insert.
|
||||||
Entry->Destroy(base::getAllocator());
|
//
|
||||||
|
// We use '+' as the sentinel value in the map.
|
||||||
|
assert(!Key.empty());
|
||||||
|
StringMapEntry<char> &Entry = this->GetOrCreateValue(Key);
|
||||||
|
if (Entry.getValue() == '+')
|
||||||
return false;
|
return false;
|
||||||
}
|
Entry.setValue('+');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,7 @@ class TinyPtrVector {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_USE_RVALUE_REFERENCES
|
#if LLVM_HAS_RVALUE_REFERENCES
|
||||||
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
|
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
|
||||||
RHS.Val = (EltTy)0;
|
RHS.Val = (EltTy)0;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class Triple {
|
|||||||
UnknownArch,
|
UnknownArch,
|
||||||
|
|
||||||
arm, // ARM; arm, armv.*, xscale
|
arm, // ARM; arm, armv.*, xscale
|
||||||
cellspu, // CellSPU: spu, cellspu
|
aarch64, // AArch64: aarch64
|
||||||
hexagon, // Hexagon: hexagon
|
hexagon, // Hexagon: hexagon
|
||||||
mips, // MIPS: mips, mipsallegrex
|
mips, // MIPS: mips, mipsallegrex
|
||||||
mipsel, // MIPSEL: mipsel, mipsallegrexel
|
mipsel, // MIPSEL: mipsel, mipsallegrexel
|
||||||
@ -101,8 +101,8 @@ class Triple {
|
|||||||
Haiku,
|
Haiku,
|
||||||
Minix,
|
Minix,
|
||||||
RTEMS,
|
RTEMS,
|
||||||
NativeClient,
|
NaCl, // Native Client
|
||||||
CNK, // BG/P Compute-Node Kernel
|
CNK, // BG/P Compute-Node Kernel
|
||||||
Bitrig,
|
Bitrig,
|
||||||
AIX
|
AIX
|
||||||
};
|
};
|
||||||
@ -112,6 +112,7 @@ class Triple {
|
|||||||
GNU,
|
GNU,
|
||||||
GNUEABI,
|
GNUEABI,
|
||||||
GNUEABIHF,
|
GNUEABIHF,
|
||||||
|
GNUX32,
|
||||||
EABI,
|
EABI,
|
||||||
MachO,
|
MachO,
|
||||||
Android,
|
Android,
|
||||||
@ -296,9 +297,14 @@ class Triple {
|
|||||||
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
|
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).
|
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
|
||||||
bool isOSDarwin() const {
|
bool isOSDarwin() const {
|
||||||
return isMacOSX() || getOS() == Triple::IOS;
|
return isMacOSX() || isiOS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Tests for either Cygwin or MinGW OS
|
/// \brief Tests for either Cygwin or MinGW OS
|
||||||
@ -311,6 +317,11 @@ class Triple {
|
|||||||
return getOS() == Triple::Win32 || isOSCygMing();
|
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.
|
/// \brief Tests whether the OS uses the ELF binary format.
|
||||||
bool isOSBinFormatELF() const {
|
bool isOSBinFormatELF() const {
|
||||||
return !isOSDarwin() && !isOSWindows();
|
return !isOSDarwin() && !isOSWindows();
|
||||||
|
@ -27,10 +27,9 @@
|
|||||||
#define LLVM_ADT_VALUEMAP_H
|
#define LLVM_ADT_VALUEMAP_H
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/Support/Mutex.h"
|
||||||
#include "llvm/Support/ValueHandle.h"
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include "llvm/Support/type_traits.h"
|
#include "llvm/Support/type_traits.h"
|
||||||
#include "llvm/Support/Mutex.h"
|
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
|
#ifndef LLVM_ADT_VARIADICFUNCTION_H
|
||||||
#define LLVM_ADT_VARIADIC_FUNCTION_H
|
#define LLVM_ADT_VARIADICFUNCTION_H
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
|
||||||
@ -328,4 +328,4 @@ struct VariadicFunction3 {
|
|||||||
|
|
||||||
} // end namespace llvm
|
} // 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; }
|
pointer getNodePtrUnchecked() const { return NodePtr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// do not implement. this is to catch errors when people try to use
|
// These are to catch errors when people try to use them as random access
|
||||||
// them as random access iterators
|
// iterators.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void operator-(int, ilist_iterator<T>);
|
void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void operator-(ilist_iterator<T>,int);
|
void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void operator+(int, ilist_iterator<T>);
|
void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
|
||||||
template<typename T>
|
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
|
// operator!=/operator== - Allow mixed comparisons without dereferencing
|
||||||
// the iterator, which could very likely be pointing to end().
|
// 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> > {
|
template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
|
||||||
typedef NodeTy* SimpleType;
|
typedef NodeTy* SimpleType;
|
||||||
|
|
||||||
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
|
static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
|
||||||
return &*Node;
|
return &*Node;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
|
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) {
|
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
|
||||||
return &*Node;
|
return &*Node;
|
||||||
@ -465,6 +465,17 @@ class iplist : public Traits {
|
|||||||
return where;
|
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:
|
private:
|
||||||
// transfer - The heart of the splice function. Move linked list nodes from
|
// 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) {
|
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
|
||||||
assert(first != last && "Should be checked by callers");
|
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) {
|
if (position != last) {
|
||||||
// Note: we have to be careful about the case when we move the first node
|
// 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
|
#ifndef LLVM_ADT_ILISTNODE_H
|
||||||
#define LLVM_ADT_ILIST_NODE_H
|
#define LLVM_ADT_ILISTNODE_H
|
||||||
|
|
||||||
namespace llvm {
|
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
|
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
|
||||||
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
|
#define LLVM_ANALYSIS_ALIASANALYSIS_H
|
||||||
|
|
||||||
#include "llvm/Support/CallSite.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/Support/CallSite.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(I, Location(P, Size));
|
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.
|
/// a particular call site modifies or reads the specified memory location.
|
||||||
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
|
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
|
||||||
const Location &Loc);
|
const Location &Loc);
|
||||||
@ -384,7 +384,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(CS, Location(P, Size));
|
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.
|
/// a particular call modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
|
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
|
||||||
return getModRefInfo(ImmutableCallSite(C), Loc);
|
return getModRefInfo(ImmutableCallSite(C), Loc);
|
||||||
@ -395,7 +395,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(C, Location(P, Size));
|
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.
|
/// a particular invoke modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const InvokeInst *I,
|
ModRefResult getModRefInfo(const InvokeInst *I,
|
||||||
const Location &Loc) {
|
const Location &Loc) {
|
||||||
@ -408,7 +408,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(I, Location(P, Size));
|
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.
|
/// a particular load modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
|
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(L, Location(P, Size));
|
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.
|
/// a particular store modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
|
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(S, Location(P, Size));
|
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.
|
/// a particular store modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
|
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
|
||||||
// Conservatively correct. (We could possibly be a bit smarter if
|
// Conservatively correct. (We could possibly be a bit smarter if
|
||||||
@ -439,7 +439,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(S, Location(P, Size));
|
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.
|
/// a particular cmpxchg modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
|
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(CX, Location(P, Size));
|
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.
|
/// a particular atomicrmw modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
|
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ class AliasAnalysis {
|
|||||||
return getModRefInfo(RMW, Location(P, Size));
|
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.
|
/// a particular va_arg modifies or reads the specified memory location.
|
||||||
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
|
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
|
/// isIdentifiedObject - Return true if this pointer refers to a distinct and
|
||||||
/// identifiable object. This returns true for:
|
/// identifiable object. This returns true for:
|
||||||
/// Global Variables and Functions (but not Global Aliases)
|
/// Global Variables and Functions (but not Global Aliases)
|
||||||
/// Allocas and Mallocs
|
/// Allocas
|
||||||
/// ByVal and NoAlias Arguments
|
/// ByVal and NoAlias Arguments
|
||||||
/// NoAlias returns
|
/// NoAlias returns (e.g. calls to malloc)
|
||||||
///
|
///
|
||||||
bool isIdentifiedObject(const Value *V);
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,11 +17,10 @@
|
|||||||
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
|
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
|
||||||
#define 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/DenseMap.h"
|
||||||
#include "llvm/ADT/ilist.h"
|
#include "llvm/ADT/ilist.h"
|
||||||
#include "llvm/ADT/ilist_node.h"
|
#include "llvm/ADT/ilist_node.h"
|
||||||
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -14,17 +14,17 @@
|
|||||||
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
||||||
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
|
||||||
|
|
||||||
#include "llvm/BasicBlock.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/PostOrderIterator.h"
|
#include "llvm/ADT/PostOrderIterator.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/Support/BlockFrequency.h"
|
#include "llvm/Support/BlockFrequency.h"
|
||||||
#include "llvm/Support/BranchProbability.h"
|
#include "llvm/Support/BranchProbability.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ class BlockFrequencyImpl {
|
|||||||
|
|
||||||
BlockT *EntryBlock = fn->begin();
|
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;
|
unsigned RPOidx = 0;
|
||||||
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
|
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
|
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
|
||||||
#define 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/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
|
#include "llvm/InitializePasses.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/BranchProbability.h"
|
#include "llvm/Support/BranchProbability.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
|
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
|
||||||
#define LLVM_ANALYSIS_CFGPRINTER_H
|
#define LLVM_ANALYSIS_CFGPRINTER_H
|
||||||
|
|
||||||
#include "llvm/Constants.h"
|
|
||||||
#include "llvm/Function.h"
|
|
||||||
#include "llvm/Instructions.h"
|
|
||||||
#include "llvm/Assembly/Writer.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/CFG.h"
|
||||||
#include "llvm/Support/GraphWriter.h"
|
#include "llvm/Support/GraphWriter.h"
|
||||||
|
|
||||||
|
@ -51,13 +51,13 @@
|
|||||||
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
|
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
|
||||||
#define 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/GraphTraits.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
#include "llvm/Support/ValueHandle.h"
|
|
||||||
#include "llvm/Support/IncludeFile.h"
|
#include "llvm/Support/IncludeFile.h"
|
||||||
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -18,11 +18,11 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
|
#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
|
||||||
#define LLVM_CALL_GRAPH_SCC_PASS_H
|
#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
|
||||||
|
|
||||||
#include "llvm/Pass.h"
|
|
||||||
#include "llvm/Analysis/CallGraph.h"
|
#include "llvm/Analysis/CallGraph.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -39,6 +39,9 @@ class CallGraphSCCPass : public Pass {
|
|||||||
/// corresponding to a CallGraph.
|
/// corresponding to a CallGraph.
|
||||||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
|
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
|
/// doInitialization - This method is called before the SCC's of the program
|
||||||
/// has been processed, allowing the pass to do initialization as necessary.
|
/// has been processed, allowing the pass to do initialization as necessary.
|
||||||
virtual bool doInitialization(CallGraph &CG) {
|
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
|
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
|
||||||
#define 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 {
|
namespace llvm {
|
||||||
|
|
||||||
|
class Value;
|
||||||
|
class Use;
|
||||||
|
|
||||||
/// PointerMayBeCaptured - Return true if this pointer value may be captured
|
/// PointerMayBeCaptured - Return true if this pointer value may be captured
|
||||||
/// by the enclosing function (which is required to exist). This routine can
|
/// by the enclosing function (which is required to exist). This routine can
|
||||||
/// be expensive, so consider caching the results. The boolean ReturnCaptures
|
/// be expensive, so consider caching the results. The boolean ReturnCaptures
|
||||||
|
@ -19,77 +19,75 @@
|
|||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
class Function;
|
class Function;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class DataLayout;
|
class DataLayout;
|
||||||
class Value;
|
class TargetTransformInfo;
|
||||||
|
class Value;
|
||||||
|
|
||||||
/// \brief Check whether an instruction is likely to be "free" when lowered.
|
/// \brief Check whether a call will lower to something small.
|
||||||
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
|
///
|
||||||
|
/// 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
|
/// True if this function contains one or more indirect branches, or it contains
|
||||||
/// significantly cheaper than a traditional call, often a single
|
/// one or more 'noduplicate' instructions.
|
||||||
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
|
bool notDuplicatable;
|
||||||
/// return true, so will this function.
|
|
||||||
bool callIsSmall(ImmutableCallSite CS);
|
|
||||||
|
|
||||||
/// \brief Utility to calculate the size and a few similar metrics for a set
|
/// \brief True if this function calls alloca (in the C sense).
|
||||||
/// of basic blocks.
|
bool usesDynamicAlloca;
|
||||||
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.
|
/// \brief Number of instructions in the analyzed blocks.
|
||||||
bool isRecursive;
|
unsigned NumInsts;
|
||||||
|
|
||||||
/// \brief True if this function contains one or more indirect branches.
|
/// \brief Number of analyzed blocks.
|
||||||
bool containsIndirectBr;
|
unsigned NumBlocks;
|
||||||
|
|
||||||
/// \brief True if this function calls alloca (in the C sense).
|
/// \brief Keeps track of basic block code size estimates.
|
||||||
bool usesDynamicAlloca;
|
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
|
||||||
|
|
||||||
/// \brief Number of instructions in the analyzed blocks.
|
/// \brief Keep track of the number of calls to 'big' functions.
|
||||||
unsigned NumInsts;
|
unsigned NumCalls;
|
||||||
|
|
||||||
/// \brief Number of analyzed blocks.
|
/// \brief The number of calls to internal functions with a single caller.
|
||||||
unsigned NumBlocks;
|
///
|
||||||
|
/// These are likely targets for future inlining, likely exposed by
|
||||||
|
/// interleaved devirtualization.
|
||||||
|
unsigned NumInlineCandidates;
|
||||||
|
|
||||||
/// \brief Keeps track of basic block code size estimates.
|
/// \brief How many instructions produce vector values.
|
||||||
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
|
///
|
||||||
|
/// The inliner is more aggressive with inlining vector kernels.
|
||||||
|
unsigned NumVectorInsts;
|
||||||
|
|
||||||
/// \brief Keep track of the number of calls to 'big' functions.
|
/// \brief How many 'ret' instructions the blocks contain.
|
||||||
unsigned NumCalls;
|
unsigned NumRets;
|
||||||
|
|
||||||
/// \brief The number of calls to internal functions with a single caller.
|
CodeMetrics()
|
||||||
///
|
: exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
|
||||||
/// These are likely targets for future inlining, likely exposed by
|
usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
|
||||||
/// interleaved devirtualization.
|
NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
|
||||||
unsigned NumInlineCandidates;
|
|
||||||
|
|
||||||
/// \brief How many instructions produce vector values.
|
/// \brief Add information about a block to the current state.
|
||||||
///
|
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
|
||||||
/// The inliner is more aggressive with inlining vector kernels.
|
};
|
||||||
unsigned NumVectorInsts;
|
|
||||||
|
|
||||||
/// \brief How many 'ret' instructions the blocks contain.
|
|
||||||
unsigned NumRets;
|
|
||||||
|
|
||||||
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
|
|
||||||
containsIndirectBr(false), usesDynamicAlloca(false),
|
|
||||||
NumInsts(0), NumBlocks(0), NumCalls(0),
|
|
||||||
NumInlineCandidates(0), NumVectorInsts(0),
|
|
||||||
NumRets(0) {}
|
|
||||||
|
|
||||||
/// \brief Add information about a block to the current state.
|
|
||||||
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
|
|
||||||
|
|
||||||
/// \brief Add information about a function to the current state.
|
|
||||||
void analyzeFunction(Function *F, const DataLayout *TD = 0);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,27 +11,25 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
|
#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
|
||||||
#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
|
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
|
||||||
|
|
||||||
#include "llvm/Pass.h"
|
|
||||||
#include "llvm/Analysis/CFGPrinter.h"
|
#include "llvm/Analysis/CFGPrinter.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template <class Analysis, bool Simple>
|
|
||||||
struct DOTGraphTraitsViewer : public FunctionPass {
|
|
||||||
std::string Name;
|
|
||||||
|
|
||||||
DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
|
template <class Analysis, bool Simple>
|
||||||
Name = GraphName;
|
class DOTGraphTraitsViewer : public FunctionPass {
|
||||||
}
|
public:
|
||||||
|
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
|
||||||
|
: FunctionPass(ID), Name(GraphName) {}
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &F) {
|
virtual bool runOnFunction(Function &F) {
|
||||||
Analysis *Graph;
|
Analysis *Graph = &getAnalysis<Analysis>();
|
||||||
std::string Title, GraphName;
|
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||||
Graph = &getAnalysis<Analysis>();
|
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
|
||||||
Title = GraphName + " for '" + F.getName().str() + "' function";
|
|
||||||
ViewGraph(Graph, Name, Simple, Title);
|
ViewGraph(Graph, Name, Simple, Title);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -41,36 +39,34 @@ struct DOTGraphTraitsViewer : public FunctionPass {
|
|||||||
AU.setPreservesAll();
|
AU.setPreservesAll();
|
||||||
AU.addRequired<Analysis>();
|
AU.addRequired<Analysis>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string Name;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Analysis, bool Simple>
|
template <class Analysis, bool Simple>
|
||||||
struct DOTGraphTraitsPrinter : public FunctionPass {
|
class DOTGraphTraitsPrinter : public FunctionPass {
|
||||||
|
public:
|
||||||
std::string Name;
|
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
|
||||||
|
: FunctionPass(ID), Name(GraphName) {}
|
||||||
DOTGraphTraitsPrinter(std::string GraphName, char &ID)
|
|
||||||
: FunctionPass(ID) {
|
|
||||||
Name = GraphName;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &F) {
|
virtual bool runOnFunction(Function &F) {
|
||||||
Analysis *Graph;
|
Analysis *Graph = &getAnalysis<Analysis>();
|
||||||
std::string Filename = Name + "." + F.getName().str() + ".dot";
|
std::string Filename = Name + "." + F.getName().str() + ".dot";
|
||||||
|
std::string ErrorInfo;
|
||||||
|
|
||||||
errs() << "Writing '" << Filename << "'...";
|
errs() << "Writing '" << Filename << "'...";
|
||||||
|
|
||||||
std::string ErrorInfo;
|
|
||||||
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
|
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
|
||||||
Graph = &getAnalysis<Analysis>();
|
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
||||||
|
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
|
||||||
std::string Title, GraphName;
|
|
||||||
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
|
|
||||||
Title = GraphName + " for '" + F.getName().str() + "' function";
|
|
||||||
|
|
||||||
if (ErrorInfo.empty())
|
if (ErrorInfo.empty())
|
||||||
WriteGraph(File, Graph, Simple, Title);
|
WriteGraph(File, Graph, Simple, Title);
|
||||||
else
|
else
|
||||||
errs() << " error opening file for writing!";
|
errs() << " error opening file for writing!";
|
||||||
errs() << "\n";
|
errs() << "\n";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +74,69 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
|
|||||||
AU.setPreservesAll();
|
AU.setPreservesAll();
|
||||||
AU.addRequired<Analysis>();
|
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
|
#endif
|
||||||
|
@ -18,6 +18,16 @@
|
|||||||
// of memory references in a function, returning either NULL, for no dependence,
|
// of memory references in a function, returning either NULL, for no dependence,
|
||||||
// or a more-or-less detailed description of the dependence between them.
|
// 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
|
// Please note that this is work in progress and the interface is subject to
|
||||||
// change.
|
// change.
|
||||||
//
|
//
|
||||||
@ -30,9 +40,9 @@
|
|||||||
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
||||||
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
|
||||||
|
|
||||||
#include "llvm/Instructions.h"
|
|
||||||
#include "llvm/Pass.h"
|
|
||||||
#include "llvm/ADT/SmallBitVector.h"
|
#include "llvm/ADT/SmallBitVector.h"
|
||||||
|
#include "llvm/IR/Instructions.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class AliasAnalysis;
|
class AliasAnalysis;
|
||||||
@ -53,8 +63,8 @@ namespace llvm {
|
|||||||
/// input dependences are unordered.
|
/// input dependences are unordered.
|
||||||
class Dependence {
|
class Dependence {
|
||||||
public:
|
public:
|
||||||
Dependence(const Instruction *Source,
|
Dependence(Instruction *Source,
|
||||||
const Instruction *Destination) :
|
Instruction *Destination) :
|
||||||
Src(Source), Dst(Destination) {}
|
Src(Source), Dst(Destination) {}
|
||||||
virtual ~Dependence() {}
|
virtual ~Dependence() {}
|
||||||
|
|
||||||
@ -82,11 +92,11 @@ namespace llvm {
|
|||||||
|
|
||||||
/// getSrc - Returns the source instruction for this dependence.
|
/// 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.
|
/// 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.
|
/// isInput - Returns true if this is an input dependence.
|
||||||
///
|
///
|
||||||
@ -158,14 +168,14 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
void dump(raw_ostream &OS) const;
|
void dump(raw_ostream &OS) const;
|
||||||
private:
|
private:
|
||||||
const Instruction *Src, *Dst;
|
Instruction *Src, *Dst;
|
||||||
friend class DependenceAnalysis;
|
friend class DependenceAnalysis;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// FullDependence - This class represents a dependence between two memory
|
/// FullDependence - This class represents a dependence between two memory
|
||||||
/// references in a function. It contains detailed information about the
|
/// 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,
|
/// able to accurately analyze the interaction of the references; that is,
|
||||||
/// it is not a confused dependence (see Dependence). In most cases
|
/// it is not a confused dependence (see Dependence). In most cases
|
||||||
/// (for output, flow, and anti dependences), the dependence implies an
|
/// (for output, flow, and anti dependences), the dependence implies an
|
||||||
@ -173,12 +183,12 @@ namespace llvm {
|
|||||||
/// input dependences are unordered.
|
/// input dependences are unordered.
|
||||||
class FullDependence : public Dependence {
|
class FullDependence : public Dependence {
|
||||||
public:
|
public:
|
||||||
FullDependence(const Instruction *Src,
|
FullDependence(Instruction *Src,
|
||||||
const Instruction *Dst,
|
Instruction *Dst,
|
||||||
bool LoopIndependent,
|
bool LoopIndependent,
|
||||||
unsigned Levels);
|
unsigned Levels);
|
||||||
~FullDependence() {
|
~FullDependence() {
|
||||||
delete DV;
|
delete[] DV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isLoopIndependent - Returns true if this is a loop-independent
|
/// isLoopIndependent - Returns true if this is a loop-independent
|
||||||
@ -234,8 +244,8 @@ namespace llvm {
|
|||||||
/// DependenceAnalysis - This class is the main dependence-analysis driver.
|
/// DependenceAnalysis - This class is the main dependence-analysis driver.
|
||||||
///
|
///
|
||||||
class DependenceAnalysis : public FunctionPass {
|
class DependenceAnalysis : public FunctionPass {
|
||||||
void operator=(const DependenceAnalysis &); // do not implement
|
void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
|
||||||
DependenceAnalysis(const DependenceAnalysis &); // do not implement
|
DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
|
||||||
public:
|
public:
|
||||||
/// depends - Tests for a dependence between the Src and Dst instructions.
|
/// depends - Tests for a dependence between the Src and Dst instructions.
|
||||||
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
|
/// 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
|
/// The flag PossiblyLoopIndependent should be set by the caller
|
||||||
/// if it appears that control flow can reach from Src to Dst
|
/// if it appears that control flow can reach from Src to Dst
|
||||||
/// without traversing a loop back edge.
|
/// without traversing a loop back edge.
|
||||||
Dependence *depends(const Instruction *Src,
|
Dependence *depends(Instruction *Src,
|
||||||
const Instruction *Dst,
|
Instruction *Dst,
|
||||||
bool PossiblyLoopIndependent);
|
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
|
/// particular level, return the iteration that should be used to split
|
||||||
/// the loop.
|
/// the loop.
|
||||||
///
|
///
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
||||||
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
|
||||||
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
|
#include "llvm/Analysis/Dominators.h"
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
#ifndef LLVM_ANALYSIS_DOMINATORS_H
|
#ifndef LLVM_ANALYSIS_DOMINATORS_H
|
||||||
#define 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/DenseMap.h"
|
||||||
#include "llvm/ADT/DepthFirstIterator.h"
|
#include "llvm/ADT/DepthFirstIterator.h"
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
@ -101,18 +101,18 @@ class DomTreeNodeBase {
|
|||||||
Children.clear();
|
Children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare(DomTreeNodeBase<NodeT> *Other) {
|
bool compare(const DomTreeNodeBase<NodeT> *Other) const {
|
||||||
if (getNumChildren() != Other->getNumChildren())
|
if (getNumChildren() != Other->getNumChildren())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
SmallPtrSet<NodeT *, 4> OtherChildren;
|
SmallPtrSet<const NodeT *, 4> OtherChildren;
|
||||||
for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
|
for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
|
||||||
NodeT *Nd = (*I)->getBlock();
|
const NodeT *Nd = (*I)->getBlock();
|
||||||
OtherChildren.insert(Nd);
|
OtherChildren.insert(Nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
||||||
NodeT *N = (*I)->getBlock();
|
const NodeT *N = (*I)->getBlock();
|
||||||
if (OtherChildren.count(N) == 0)
|
if (OtherChildren.count(N) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -663,8 +663,7 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
|||||||
// Initialize the roots list
|
// Initialize the roots list
|
||||||
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
|
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
|
||||||
E = TraitsTy::nodes_end(&F); I != E; ++I) {
|
E = TraitsTy::nodes_end(&F); I != E; ++I) {
|
||||||
if (std::distance(TraitsTy::child_begin(I),
|
if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
|
||||||
TraitsTy::child_end(I)) == 0)
|
|
||||||
addRoot(I);
|
addRoot(I);
|
||||||
|
|
||||||
// Prepopulate maps so that we don't get iterator invalidation issues later.
|
// Prepopulate maps so that we don't get iterator invalidation issues later.
|
||||||
|
@ -24,7 +24,6 @@ namespace llvm {
|
|||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class Value;
|
class Value;
|
||||||
class IVUsers;
|
|
||||||
class ScalarEvolution;
|
class ScalarEvolution;
|
||||||
class SCEV;
|
class SCEV;
|
||||||
class IVUsers;
|
class IVUsers;
|
||||||
|
@ -14,122 +14,130 @@
|
|||||||
#ifndef LLVM_ANALYSIS_INLINECOST_H
|
#ifndef LLVM_ANALYSIS_INLINECOST_H
|
||||||
#define 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/CodeMetrics.h"
|
||||||
|
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
class CallSite;
|
||||||
|
class DataLayout;
|
||||||
|
class Function;
|
||||||
|
class TargetTransformInfo;
|
||||||
|
|
||||||
class CallSite;
|
namespace InlineConstants {
|
||||||
class DataLayout;
|
// 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 {
|
/// \brief Represents the cost of inlining a function.
|
||||||
// Various magic constants used to adjust heuristics.
|
///
|
||||||
const int InstrCost = 5;
|
/// This supports special values for functions which should "always" or
|
||||||
const int IndirectCallThreshold = 100;
|
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
|
||||||
const int CallPenalty = 25;
|
/// smaller values increase the likelihood of the function being inlined.
|
||||||
const int LastCallToStaticBonus = -15000;
|
///
|
||||||
const int ColdccPenalty = 2000;
|
/// Objects of this type also provide the adjusted threshold for inlining
|
||||||
const int NoreturnPenalty = 10000;
|
/// based on the information available for a particular callsite. They can be
|
||||||
/// Do not inline functions which allocate this many bytes on the stack
|
/// directly tested to determine if inlining should occur given the cost and
|
||||||
/// when the caller is recursive.
|
/// threshold for this cost metric.
|
||||||
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
|
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
|
/// Note that threshold is passed into this function. Only costs below the
|
||||||
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
|
/// threshold are computed with any accuracy. The threshold can be used to
|
||||||
/// smaller values increase the likelihood of the function being inlined.
|
/// 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
|
/// Also note that calling this function *dynamically* computes the cost of
|
||||||
/// based on the information available for a particular callsite. They can be
|
/// inlining the callsite. It is an expensive, heavyweight call.
|
||||||
/// directly tested to determine if inlining should occur given the cost and
|
InlineCost getInlineCost(CallSite CS, int Threshold);
|
||||||
/// threshold for this cost metric.
|
|
||||||
class InlineCost {
|
|
||||||
enum SentinelValues {
|
|
||||||
AlwaysInlineCost = INT_MIN,
|
|
||||||
NeverInlineCost = INT_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief The estimated cost of inlining this callsite.
|
/// \brief Get an InlineCost with the callee explicitly specified.
|
||||||
const int Cost;
|
/// 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.
|
/// \brief Minimal filter to detect invalid constructs for inlining.
|
||||||
const int Threshold;
|
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
|
#endif
|
||||||
|
@ -14,17 +14,33 @@
|
|||||||
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
|
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
|
||||||
// then it dominates the original 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
|
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||||
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||||
|
|
||||||
|
#include "llvm/IR/User.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ArrayRef;
|
class ArrayRef;
|
||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class DataLayout;
|
class DataLayout;
|
||||||
|
class FastMathFlags;
|
||||||
class TargetLibraryInfo;
|
class TargetLibraryInfo;
|
||||||
class Type;
|
class Type;
|
||||||
class Value;
|
class Value;
|
||||||
@ -43,6 +59,28 @@ namespace llvm {
|
|||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 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
|
/// SimplifyMulInst - Given operands for a Mul, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
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
|
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// 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 TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
@ -69,7 +107,7 @@ namespace llvm {
|
|||||||
|
|
||||||
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// 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 TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
@ -88,7 +126,7 @@ namespace llvm {
|
|||||||
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
@ -127,14 +165,14 @@ namespace llvm {
|
|||||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
@ -178,10 +216,28 @@ namespace llvm {
|
|||||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 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
|
/// SimplifyInstruction - See if we can compute a simplified version of this
|
||||||
/// instruction. If not, this returns null.
|
/// instruction. If not, this returns null.
|
||||||
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
|
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_INTERVAL_H
|
#ifndef LLVM_ANALYSIS_INTERVAL_H
|
||||||
#define LLVM_INTERVAL_H
|
#define LLVM_ANALYSIS_INTERVAL_H
|
||||||
|
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_INTERVAL_ITERATOR_H
|
#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
|
||||||
#define LLVM_INTERVAL_ITERATOR_H
|
#define LLVM_ANALYSIS_INTERVALITERATOR_H
|
||||||
|
|
||||||
#include "llvm/Analysis/IntervalPartition.h"
|
#include "llvm/Analysis/IntervalPartition.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -157,7 +157,7 @@ class IntervalIterator {
|
|||||||
private:
|
private:
|
||||||
// ProcessInterval - This method is used during the construction of the
|
// ProcessInterval - This method is used during the construction of the
|
||||||
// interval graph. It walks through the source graph, recursively creating
|
// 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.
|
// the ProcessNode method to add all of the nodes to the interval.
|
||||||
//
|
//
|
||||||
// This method is templated because it may operate on two different source
|
// This method is templated because it may operate on two different source
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_INTERVAL_PARTITION_H
|
#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
|
||||||
#define LLVM_INTERVAL_PARTITION_H
|
#define LLVM_ANALYSIS_INTERVALPARTITION_H
|
||||||
|
|
||||||
#include "llvm/Analysis/Interval.h"
|
#include "llvm/Analysis/Interval.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_LIBCALL_AA_H
|
#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
|
||||||
#define LLVM_ANALYSIS_LIBCALL_AA_H
|
#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
|
||||||
|
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#ifndef LLVM_ANALYSIS_LOADS_H
|
#ifndef LLVM_ANALYSIS_LOADS_H
|
||||||
#define LLVM_ANALYSIS_LOADS_H
|
#define LLVM_ANALYSIS_LOADS_H
|
||||||
|
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -27,21 +27,16 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_LOOP_INFO_H
|
#ifndef LLVM_ANALYSIS_LOOPINFO_H
|
||||||
#define LLVM_ANALYSIS_LOOP_INFO_H
|
#define LLVM_ANALYSIS_LOOPINFO_H
|
||||||
|
|
||||||
#include "llvm/Pass.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/DepthFirstIterator.h"
|
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -56,6 +51,7 @@ class DominatorTree;
|
|||||||
class LoopInfo;
|
class LoopInfo;
|
||||||
class Loop;
|
class Loop;
|
||||||
class PHINode;
|
class PHINode;
|
||||||
|
class raw_ostream;
|
||||||
template<class N, class M> class LoopInfoBase;
|
template<class N, class M> class LoopInfoBase;
|
||||||
template<class N, class M> class LoopBase;
|
template<class N, class M> class LoopBase;
|
||||||
|
|
||||||
@ -151,10 +147,10 @@ class LoopBase {
|
|||||||
/// block that is outside of the current loop.
|
/// block that is outside of the current loop.
|
||||||
///
|
///
|
||||||
bool isLoopExiting(const BlockT *BB) const {
|
bool isLoopExiting(const BlockT *BB) const {
|
||||||
typedef GraphTraits<BlockT*> BlockTraits;
|
typedef GraphTraits<const BlockT*> BlockTraits;
|
||||||
for (typename BlockTraits::ChildIteratorType SI =
|
for (typename BlockTraits::ChildIteratorType SI =
|
||||||
BlockTraits::child_begin(const_cast<BlockT*>(BB)),
|
BlockTraits::child_begin(BB),
|
||||||
SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++SI) {
|
SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
|
||||||
if (!contains(*SI))
|
if (!contains(*SI))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -169,8 +165,8 @@ class LoopBase {
|
|||||||
|
|
||||||
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
|
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
|
||||||
for (typename InvBlockTraits::ChildIteratorType I =
|
for (typename InvBlockTraits::ChildIteratorType I =
|
||||||
InvBlockTraits::child_begin(const_cast<BlockT*>(H)),
|
InvBlockTraits::child_begin(H),
|
||||||
E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I)
|
E = InvBlockTraits::child_end(H); I != E; ++I)
|
||||||
if (contains(*I))
|
if (contains(*I))
|
||||||
++NumBackEdges;
|
++NumBackEdges;
|
||||||
|
|
||||||
@ -381,6 +377,20 @@ class Loop : public LoopBase<BasicBlock, Loop> {
|
|||||||
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
|
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
|
||||||
bool isSafeToClone() const;
|
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
|
/// hasDedicatedExits - Return true if no exit block for the loop
|
||||||
/// has a predecessor that is outside the loop.
|
/// has a predecessor that is outside the loop.
|
||||||
bool hasDedicatedExits() const;
|
bool hasDedicatedExits() const;
|
||||||
|
@ -12,11 +12,12 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
|
#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
|
||||||
#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
|
#define LLVM_ANALYSIS_LOOPINFOIMPL_H
|
||||||
|
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
|
||||||
#include "llvm/ADT/PostOrderIterator.h"
|
#include "llvm/ADT/PostOrderIterator.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -21,10 +21,9 @@
|
|||||||
// reachable from the loop header.
|
// reachable from the loop header.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
|
#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
|
||||||
#define LLVM_ANALYSIS_LOOP_ITERATOR_H
|
#define LLVM_ANALYSIS_LOOPITERATOR_H
|
||||||
|
|
||||||
#include "llvm/ADT/DepthFirstIterator.h"
|
|
||||||
#include "llvm/ADT/PostOrderIterator.h"
|
#include "llvm/ADT/PostOrderIterator.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
|
|
||||||
|
@ -12,13 +12,12 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_LOOP_PASS_H
|
#ifndef LLVM_ANALYSIS_LOOPPASS_H
|
||||||
#define LLVM_LOOP_PASS_H
|
#define LLVM_ANALYSIS_LOOPPASS_H
|
||||||
|
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/PassManagers.h"
|
#include "llvm/PassManagers.h"
|
||||||
#include "llvm/Function.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -39,6 +38,9 @@ class LoopPass : public Pass {
|
|||||||
// whatever action is necessary for the specified Loop.
|
// whatever action is necessary for the specified Loop.
|
||||||
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
|
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
|
||||||
|
|
||||||
|
using llvm::Pass::doInitialization;
|
||||||
|
using llvm::Pass::doFinalization;
|
||||||
|
|
||||||
// Initialization and finalization hooks.
|
// Initialization and finalization hooks.
|
||||||
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
|
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
|
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
|
||||||
#define 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/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.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/DataTypes.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
|
||||||
#include "llvm/Support/TargetFolder.h"
|
#include "llvm/Support/TargetFolder.h"
|
||||||
#include "llvm/Support/ValueHandle.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
|
/// \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,
|
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
|
||||||
/// byval arguments, and global variables.
|
/// byval arguments, and global variables.
|
||||||
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
|
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
|
||||||
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
|
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;
|
typedef std::pair<APInt, APInt> SizeOffsetType;
|
||||||
@ -153,12 +163,14 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
|
|||||||
class ObjectSizeOffsetVisitor
|
class ObjectSizeOffsetVisitor
|
||||||
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
|
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
|
||||||
|
|
||||||
|
typedef DenseMap<const Value*, SizeOffsetType> CacheMapTy;
|
||||||
|
|
||||||
const DataLayout *TD;
|
const DataLayout *TD;
|
||||||
const TargetLibraryInfo *TLI;
|
const TargetLibraryInfo *TLI;
|
||||||
bool RoundToAlign;
|
bool RoundToAlign;
|
||||||
unsigned IntTyBits;
|
unsigned IntTyBits;
|
||||||
APInt Zero;
|
APInt Zero;
|
||||||
SmallPtrSet<Instruction *, 8> SeenInsts;
|
CacheMapTy CacheMap;
|
||||||
|
|
||||||
APInt align(APInt Size, uint64_t Align);
|
APInt align(APInt Size, uint64_t Align);
|
||||||
|
|
||||||
@ -191,6 +203,7 @@ class ObjectSizeOffsetVisitor
|
|||||||
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
|
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
|
||||||
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
|
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
|
||||||
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
|
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
|
||||||
|
SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
|
||||||
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
|
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
|
||||||
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
|
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
|
||||||
SizeOffsetType visitLoadInst(LoadInst &I);
|
SizeOffsetType visitLoadInst(LoadInst &I);
|
||||||
|
@ -11,17 +11,17 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
|
#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
|
||||||
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_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/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
|
||||||
#include "llvm/ADT/OwningPtr.h"
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
#include "llvm/ADT/PointerIntPair.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 {
|
namespace llvm {
|
||||||
class Function;
|
class Function;
|
||||||
@ -34,14 +34,14 @@ namespace llvm {
|
|||||||
class PredIteratorCache;
|
class PredIteratorCache;
|
||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
class PHITransAddr;
|
class PHITransAddr;
|
||||||
|
|
||||||
/// MemDepResult - A memory dependence query can return one of three different
|
/// MemDepResult - A memory dependence query can return one of three different
|
||||||
/// answers, described below.
|
/// answers, described below.
|
||||||
class MemDepResult {
|
class MemDepResult {
|
||||||
enum DepType {
|
enum DepType {
|
||||||
/// Invalid - Clients of MemDep never see this.
|
/// Invalid - Clients of MemDep never see this.
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
|
|
||||||
/// Clobber - This is a dependence on the specified instruction which
|
/// Clobber - This is a dependence on the specified instruction which
|
||||||
/// clobbers the desired value. The pointer member of the MemDepResult
|
/// clobbers the desired value. The pointer member of the MemDepResult
|
||||||
/// pair holds the instruction that clobbers the memory. For example,
|
/// 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
|
/// and no intervening clobbers. No validation is done that the
|
||||||
/// operands to the calls are the same.
|
/// operands to the calls are the same.
|
||||||
Def,
|
Def,
|
||||||
|
|
||||||
/// Other - This marker indicates that the query has no known dependency
|
/// Other - This marker indicates that the query has no known dependency
|
||||||
/// in the specified block. More detailed state info is encoded in the
|
/// in the specified block. More detailed state info is encoded in the
|
||||||
/// upper part of the pair (i.e. the Instruction*)
|
/// upper part of the pair (i.e. the Instruction*)
|
||||||
@ -99,7 +99,7 @@ namespace llvm {
|
|||||||
explicit MemDepResult(PairTy V) : Value(V) {}
|
explicit MemDepResult(PairTy V) : Value(V) {}
|
||||||
public:
|
public:
|
||||||
MemDepResult() : Value(0, Invalid) {}
|
MemDepResult() : Value(0, Invalid) {}
|
||||||
|
|
||||||
/// get methods: These are static ctor methods for creating various
|
/// get methods: These are static ctor methods for creating various
|
||||||
/// MemDepResult kinds.
|
/// MemDepResult kinds.
|
||||||
static MemDepResult getDef(Instruction *Inst) {
|
static MemDepResult getDef(Instruction *Inst) {
|
||||||
@ -130,7 +130,7 @@ namespace llvm {
|
|||||||
/// isDef - Return true if this MemDepResult represents a query that is
|
/// isDef - Return true if this MemDepResult represents a query that is
|
||||||
/// an instruction definition dependency.
|
/// an instruction definition dependency.
|
||||||
bool isDef() const { return Value.getInt() == Def; }
|
bool isDef() const { return Value.getInt() == Def; }
|
||||||
|
|
||||||
/// isNonLocal - Return true if this MemDepResult represents a query that
|
/// 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
|
/// is transparent to the start of the block, but where a non-local hasn't
|
||||||
/// been done.
|
/// been done.
|
||||||
@ -145,7 +145,7 @@ namespace llvm {
|
|||||||
return Value.getInt() == Other
|
return Value.getInt() == Other
|
||||||
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
|
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isUnknown - Return true if this MemDepResult represents a query which
|
/// isUnknown - Return true if this MemDepResult represents a query which
|
||||||
/// cannot and/or will not be computed.
|
/// cannot and/or will not be computed.
|
||||||
bool isUnknown() const {
|
bool isUnknown() const {
|
||||||
@ -159,7 +159,7 @@ namespace llvm {
|
|||||||
if (Value.getInt() == Other) return NULL;
|
if (Value.getInt() == Other) return NULL;
|
||||||
return Value.getPointer();
|
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; }
|
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
|
/// In a default-constructed MemDepResult object, the type will be Dirty
|
||||||
/// and the instruction pointer will be null.
|
/// and the instruction pointer will be null.
|
||||||
///
|
///
|
||||||
|
|
||||||
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
|
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
|
||||||
/// state.
|
/// state.
|
||||||
bool isDirty() const { return Value.getInt() == Invalid; }
|
bool isDirty() const { return Value.getInt() == Invalid; }
|
||||||
|
|
||||||
static MemDepResult getDirty(Instruction *Inst) {
|
static MemDepResult getDirty(Instruction *Inst) {
|
||||||
return MemDepResult(PairTy(Inst, Invalid));
|
return MemDepResult(PairTy(Inst, Invalid));
|
||||||
}
|
}
|
||||||
@ -199,16 +199,16 @@ namespace llvm {
|
|||||||
|
|
||||||
// BB is the sort key, it can't be changed.
|
// BB is the sort key, it can't be changed.
|
||||||
BasicBlock *getBB() const { return BB; }
|
BasicBlock *getBB() const { return BB; }
|
||||||
|
|
||||||
void setResult(const MemDepResult &R) { Result = R; }
|
void setResult(const MemDepResult &R) { Result = R; }
|
||||||
|
|
||||||
const MemDepResult &getResult() const { return Result; }
|
const MemDepResult &getResult() const { return Result; }
|
||||||
|
|
||||||
bool operator<(const NonLocalDepEntry &RHS) const {
|
bool operator<(const NonLocalDepEntry &RHS) const {
|
||||||
return BB < RHS.BB;
|
return BB < RHS.BB;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
|
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
|
||||||
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
|
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
|
||||||
/// (potentially phi translated) address that was live in the block.
|
/// (potentially phi translated) address that was live in the block.
|
||||||
@ -218,17 +218,17 @@ namespace llvm {
|
|||||||
public:
|
public:
|
||||||
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
|
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
|
||||||
: Entry(bb, result), Address(address) {}
|
: Entry(bb, result), Address(address) {}
|
||||||
|
|
||||||
// BB is the sort key, it can't be changed.
|
// BB is the sort key, it can't be changed.
|
||||||
BasicBlock *getBB() const { return Entry.getBB(); }
|
BasicBlock *getBB() const { return Entry.getBB(); }
|
||||||
|
|
||||||
void setResult(const MemDepResult &R, Value *Addr) {
|
void setResult(const MemDepResult &R, Value *Addr) {
|
||||||
Entry.setResult(R);
|
Entry.setResult(R);
|
||||||
Address = Addr;
|
Address = Addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemDepResult &getResult() const { return Entry.getResult(); }
|
const MemDepResult &getResult() const { return Entry.getResult(); }
|
||||||
|
|
||||||
/// getAddress - Return the address of this pointer in this block. This can
|
/// getAddress - Return the address of this pointer in this block. This can
|
||||||
/// be different than the address queried for the non-local result because
|
/// be different than the address queried for the non-local result because
|
||||||
/// of phi translation. This returns null if the address was not available
|
/// 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.
|
/// The address is always null for a non-local 'call' dependence.
|
||||||
Value *getAddress() const { return Address; }
|
Value *getAddress() const { return Address; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
|
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
|
||||||
/// given memory operation, what preceding memory operations it depends on.
|
/// given memory operation, what preceding memory operations it depends on.
|
||||||
/// It builds on alias analysis information, and tries to provide a lazy,
|
/// It builds on alias analysis information, and tries to provide a lazy,
|
||||||
@ -297,30 +297,30 @@ namespace llvm {
|
|||||||
CachedNonLocalPointerInfo NonLocalPointerDeps;
|
CachedNonLocalPointerInfo NonLocalPointerDeps;
|
||||||
|
|
||||||
// A map from instructions to their non-local pointer dependencies.
|
// A map from instructions to their non-local pointer dependencies.
|
||||||
typedef DenseMap<Instruction*,
|
typedef DenseMap<Instruction*,
|
||||||
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
|
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
|
||||||
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
|
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
|
||||||
|
|
||||||
|
|
||||||
/// PerInstNLInfo - This is the instruction we keep for each cached access
|
/// PerInstNLInfo - This is the instruction we keep for each cached access
|
||||||
/// that we have for an instruction. The pointer is an owning pointer and
|
/// 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.
|
/// the bool indicates whether we have any dirty bits in the set.
|
||||||
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
|
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
|
||||||
|
|
||||||
// A map from instructions to their non-local dependencies.
|
// A map from instructions to their non-local dependencies.
|
||||||
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
|
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
|
||||||
|
|
||||||
NonLocalDepMapType NonLocalDeps;
|
NonLocalDepMapType NonLocalDeps;
|
||||||
|
|
||||||
// A reverse mapping from dependencies to the dependees. This is
|
// A reverse mapping from dependencies to the dependees. This is
|
||||||
// used when removing instructions to keep the cache coherent.
|
// used when removing instructions to keep the cache coherent.
|
||||||
typedef DenseMap<Instruction*,
|
typedef DenseMap<Instruction*,
|
||||||
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
||||||
ReverseDepMapType ReverseLocalDeps;
|
ReverseDepMapType ReverseLocalDeps;
|
||||||
|
|
||||||
// A reverse mapping from dependencies to the non-local dependees.
|
// A reverse mapping from dependencies to the non-local dependees.
|
||||||
ReverseDepMapType ReverseNonLocalDeps;
|
ReverseDepMapType ReverseNonLocalDeps;
|
||||||
|
|
||||||
/// Current AA implementation, just a cache.
|
/// Current AA implementation, just a cache.
|
||||||
AliasAnalysis *AA;
|
AliasAnalysis *AA;
|
||||||
DataLayout *TD;
|
DataLayout *TD;
|
||||||
@ -333,15 +333,15 @@ namespace llvm {
|
|||||||
|
|
||||||
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
|
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
|
||||||
bool runOnFunction(Function &);
|
bool runOnFunction(Function &);
|
||||||
|
|
||||||
/// Clean up memory in between runs
|
/// Clean up memory in between runs
|
||||||
void releaseMemory();
|
void releaseMemory();
|
||||||
|
|
||||||
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
|
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
|
||||||
/// and Alias Analysis.
|
/// and Alias Analysis.
|
||||||
///
|
///
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||||
|
|
||||||
/// getDependency - Return the instruction on which a memory operation
|
/// getDependency - Return the instruction on which a memory operation
|
||||||
/// depends. See the class comment for more details. It is illegal to call
|
/// depends. See the class comment for more details. It is illegal to call
|
||||||
/// this on non-memory instructions.
|
/// this on non-memory instructions.
|
||||||
@ -360,8 +360,8 @@ namespace llvm {
|
|||||||
/// removed. Clients must copy this data if they want it around longer than
|
/// removed. Clients must copy this data if they want it around longer than
|
||||||
/// that.
|
/// that.
|
||||||
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
|
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
|
||||||
|
|
||||||
|
|
||||||
/// getNonLocalPointerDependency - Perform a full dependency query for an
|
/// getNonLocalPointerDependency - Perform a full dependency query for an
|
||||||
/// access to the specified (non-volatile) memory location, returning the
|
/// access to the specified (non-volatile) memory location, returning the
|
||||||
/// set of instructions that either define or clobber the value.
|
/// set of instructions that either define or clobber the value.
|
||||||
@ -374,7 +374,7 @@ namespace llvm {
|
|||||||
/// removeInstruction - Remove an instruction from the dependence analysis,
|
/// removeInstruction - Remove an instruction from the dependence analysis,
|
||||||
/// updating the dependence of instructions that previously depended on it.
|
/// updating the dependence of instructions that previously depended on it.
|
||||||
void removeInstruction(Instruction *InstToRemove);
|
void removeInstruction(Instruction *InstToRemove);
|
||||||
|
|
||||||
/// invalidateCachedPointerInfo - This method is used to invalidate cached
|
/// invalidateCachedPointerInfo - This method is used to invalidate cached
|
||||||
/// information about the specified pointer, because it may be too
|
/// information about the specified pointer, because it may be too
|
||||||
/// conservative in memdep. This is an optional call that can be used when
|
/// 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
|
/// This needs to be done when the CFG changes, e.g., due to splitting
|
||||||
/// critical edges.
|
/// critical edges.
|
||||||
void invalidateCachedPredecessors();
|
void invalidateCachedPredecessors();
|
||||||
|
|
||||||
/// getPointerDependencyFrom - Return the instruction on which a memory
|
/// getPointerDependencyFrom - Return the instruction on which a memory
|
||||||
/// location depends. If isLoad is true, this routine ignores may-aliases
|
/// location depends. If isLoad is true, this routine ignores may-aliases
|
||||||
/// with read-only operations. If isLoad is false, this routine ignores
|
/// 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.
|
/// Note that this is an uncached query, and thus may be inefficient.
|
||||||
///
|
///
|
||||||
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
|
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
|
||||||
bool isLoad,
|
bool isLoad,
|
||||||
BasicBlock::iterator ScanIt,
|
BasicBlock::iterator ScanIt,
|
||||||
BasicBlock *BB);
|
BasicBlock *BB,
|
||||||
|
Instruction *QueryInst = 0);
|
||||||
|
|
||||||
|
|
||||||
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
|
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
|
||||||
/// looks at a memory location for a load (specified by MemLocBase, Offs,
|
/// 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
|
/// and Size) and compares it against a load. If the specified load could
|
||||||
@ -413,7 +416,7 @@ namespace llvm {
|
|||||||
unsigned MemLocSize,
|
unsigned MemLocSize,
|
||||||
const LoadInst *LI,
|
const LoadInst *LI,
|
||||||
const DataLayout &TD);
|
const DataLayout &TD);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
|
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
|
||||||
BasicBlock::iterator ScanIt,
|
BasicBlock::iterator ScanIt,
|
||||||
@ -430,11 +433,11 @@ namespace llvm {
|
|||||||
unsigned NumSortedEntries);
|
unsigned NumSortedEntries);
|
||||||
|
|
||||||
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
|
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
|
||||||
|
|
||||||
/// verifyRemoved - Verify that the specified instruction does not occur
|
/// verifyRemoved - Verify that the specified instruction does not occur
|
||||||
/// in our internal data structures.
|
/// in our internal data structures.
|
||||||
void verifyRemoved(Instruction *Inst) const;
|
void verifyRemoved(Instruction *Inst) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
|
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
|
||||||
#define LLVM_ANALYSIS_PHITRANSADDR_H
|
#define LLVM_ANALYSIS_PHITRANSADDR_H
|
||||||
|
|
||||||
#include "llvm/Instruction.h"
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include "llvm/IR/Instruction.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
|
@ -198,9 +198,6 @@ namespace llvm {
|
|||||||
// analyze.
|
// analyze.
|
||||||
FunctionPass *createInstCountPass();
|
FunctionPass *createInstCountPass();
|
||||||
|
|
||||||
// print debug info intrinsics in human readable form
|
|
||||||
FunctionPass *createDbgInfoPrinterPass();
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// createRegionInfoPass - This pass finds all single entry single exit regions
|
// createRegionInfoPass - This pass finds all single entry single exit regions
|
||||||
|
@ -23,14 +23,14 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_PATH_NUMBERING_H
|
#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
|
||||||
#define LLVM_PATH_NUMBERING_H
|
#define LLVM_ANALYSIS_PATHNUMBERING_H
|
||||||
|
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/Analysis/ProfileInfoTypes.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Analysis/ProfileInfoTypes.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_PATHPROFILEINFO_H
|
#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
|
||||||
#define LLVM_PATHPROFILEINFO_H
|
#define LLVM_ANALYSIS_PATHPROFILEINFO_H
|
||||||
|
|
||||||
#include "llvm/BasicBlock.h"
|
|
||||||
#include "llvm/Analysis/PathNumbering.h"
|
#include "llvm/Analysis/PathNumbering.h"
|
||||||
|
#include "llvm/IR/BasicBlock.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
|
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
|
||||||
#define LLVM_ANALYSIS_POST_DOMINATORS_H
|
#define LLVM_ANALYSIS_POSTDOMINATORS_H
|
||||||
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
|
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
|
||||||
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
|
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Pass;
|
class Pass;
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
||||||
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
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
|
#ifndef LLVM_ANALYSIS_REGIONINFO_H
|
||||||
#define LLVM_ANALYSIS_REGION_INFO_H
|
#define LLVM_ANALYSIS_REGIONINFO_H
|
||||||
|
|
||||||
#include "llvm/ADT/PointerIntPair.h"
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
#include "llvm/Analysis/DominanceFrontier.h"
|
#include "llvm/Analysis/DominanceFrontier.h"
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// This file defines the iterators to iterate over the elements of a Region.
|
// This file defines the iterators to iterate over the elements of a Region.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
|
#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
|
||||||
#define LLVM_ANALYSIS_REGION_ITERATOR_H
|
#define LLVM_ANALYSIS_REGIONITERATOR_H
|
||||||
|
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
|
||||||
#include "llvm/ADT/PointerIntPair.h"
|
#include "llvm/ADT/PointerIntPair.h"
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/Analysis/RegionInfo.h"
|
#include "llvm/Analysis/RegionInfo.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
@ -13,15 +13,13 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_REGION_PASS_H
|
#ifndef LLVM_ANALYSIS_REGIONPASS_H
|
||||||
#define LLVM_REGION_PASS_H
|
#define LLVM_ANALYSIS_REGIONPASS_H
|
||||||
|
|
||||||
#include "llvm/Analysis/RegionInfo.h"
|
#include "llvm/Analysis/RegionInfo.h"
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/PassManagers.h"
|
#include "llvm/PassManagers.h"
|
||||||
#include "llvm/Function.h"
|
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -59,6 +57,9 @@ class RegionPass : public Pass {
|
|||||||
/// @return The pass to print the LLVM IR in the region.
|
/// @return The pass to print the LLVM IR in the region.
|
||||||
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
|
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
|
||||||
|
|
||||||
|
using llvm::Pass::doInitialization;
|
||||||
|
using llvm::Pass::doFinalization;
|
||||||
|
|
||||||
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
|
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
|
||||||
virtual bool doFinalization() { return false; }
|
virtual bool doFinalization() { return false; }
|
||||||
//@}
|
//@}
|
||||||
|
@ -21,16 +21,16 @@
|
|||||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
|
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
|
||||||
#define 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/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/Allocator.h"
|
||||||
#include "llvm/Support/ConstantRange.h"
|
#include "llvm/Support/ConstantRange.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -338,6 +338,10 @@ namespace llvm {
|
|||||||
/// getMax - Get the max backedge taken count for the loop.
|
/// getMax - Get the max backedge taken count for the loop.
|
||||||
const SCEV *getMax(ScalarEvolution *SE) const;
|
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.
|
/// clear - Invalidate this result and free associated memory.
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
@ -831,7 +835,7 @@ namespace llvm {
|
|||||||
|
|
||||||
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
|
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
|
||||||
/// predicate Pred. Return true iff any changes were made. If the
|
/// 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.
|
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
|
||||||
///
|
///
|
||||||
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||||
|
@ -11,18 +11,18 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
|
||||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
|
||||||
|
|
||||||
#include "llvm/IRBuilder.h"
|
|
||||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||||
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/Support/TargetFolder.h"
|
#include "llvm/Support/TargetFolder.h"
|
||||||
#include "llvm/Support/ValueHandle.h"
|
#include "llvm/Support/ValueHandle.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class TargetLowering;
|
class TargetTransformInfo;
|
||||||
|
|
||||||
/// Return true if the given expression is safe to expand in the sense that
|
/// Return true if the given expression is safe to expand in the sense that
|
||||||
/// all materialized values are safe to speculate.
|
/// 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.
|
// New instructions receive a name to identifies them with the current pass.
|
||||||
const char* IVName;
|
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;
|
InsertedExpressions;
|
||||||
|
// InsertedValues only flags inserted instructions so needs no RAUW.
|
||||||
std::set<AssertingVH<Value> > InsertedValues;
|
std::set<AssertingVH<Value> > InsertedValues;
|
||||||
std::set<AssertingVH<Value> > InsertedPostIncValues;
|
std::set<AssertingVH<Value> > InsertedPostIncValues;
|
||||||
|
|
||||||
@ -129,7 +131,7 @@ namespace llvm {
|
|||||||
/// representative. Return the number of phis eliminated.
|
/// representative. Return the number of phis eliminated.
|
||||||
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||||
SmallVectorImpl<WeakVH> &DeadInsts,
|
SmallVectorImpl<WeakVH> &DeadInsts,
|
||||||
const TargetLowering *TLI = NULL);
|
const TargetTransformInfo *TTI = NULL);
|
||||||
|
|
||||||
/// expandCodeFor - Insert code to directly compute the specified SCEV
|
/// expandCodeFor - Insert code to directly compute the specified SCEV
|
||||||
/// expression into the program. The inserted code is inserted into the
|
/// 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