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:
Dimitry Andric 2013-04-12 17:57:40 +00:00
commit 139f7f9bf5
2580 changed files with 225457 additions and 119807 deletions

View File

@ -380,7 +380,7 @@ IMAKE_MTREE= MTREE_CMD="nmtree ${MTREEFLAGS}"
# kernel stage
KMAKEENV= ${WMAKEENV}
KMAKE= ${KMAKEENV} ${MAKE} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME}
#
# buildworld

View File

@ -38,6 +38,37 @@
# xargs -n1 | sort | uniq -d;
# done
# 20130411: new clang import which bumps version from 3.2 to 3.3.
OLD_FILES+=usr/include/clang/3.2/__wmmintrin_aes.h
OLD_FILES+=usr/include/clang/3.2/__wmmintrin_pclmul.h
OLD_FILES+=usr/include/clang/3.2/altivec.h
OLD_FILES+=usr/include/clang/3.2/ammintrin.h
OLD_FILES+=usr/include/clang/3.2/avx2intrin.h
OLD_FILES+=usr/include/clang/3.2/avxintrin.h
OLD_FILES+=usr/include/clang/3.2/bmi2intrin.h
OLD_FILES+=usr/include/clang/3.2/bmiintrin.h
OLD_FILES+=usr/include/clang/3.2/cpuid.h
OLD_FILES+=usr/include/clang/3.2/emmintrin.h
OLD_FILES+=usr/include/clang/3.2/f16cintrin.h
OLD_FILES+=usr/include/clang/3.2/fma4intrin.h
OLD_FILES+=usr/include/clang/3.2/fmaintrin.h
OLD_FILES+=usr/include/clang/3.2/immintrin.h
OLD_FILES+=usr/include/clang/3.2/lzcntintrin.h
OLD_FILES+=usr/include/clang/3.2/mm3dnow.h
OLD_FILES+=usr/include/clang/3.2/mm_malloc.h
OLD_FILES+=usr/include/clang/3.2/mmintrin.h
OLD_FILES+=usr/include/clang/3.2/module.map
OLD_FILES+=usr/include/clang/3.2/nmmintrin.h
OLD_FILES+=usr/include/clang/3.2/pmmintrin.h
OLD_FILES+=usr/include/clang/3.2/popcntintrin.h
OLD_FILES+=usr/include/clang/3.2/rtmintrin.h
OLD_FILES+=usr/include/clang/3.2/smmintrin.h
OLD_FILES+=usr/include/clang/3.2/tmmintrin.h
OLD_FILES+=usr/include/clang/3.2/wmmintrin.h
OLD_FILES+=usr/include/clang/3.2/x86intrin.h
OLD_FILES+=usr/include/clang/3.2/xmmintrin.h
OLD_FILES+=usr/include/clang/3.2/xopintrin.h
OLD_DIRS+=usr/include/clang/3.2
# 20130404: legacy ATA stack removed
OLD_FILES+=sbin/atacontrol
OLD_FILES+=usr/share/man/man8/atacontrol.8.gz

View File

@ -4,7 +4,7 @@ LLVM Release License
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
@ -64,7 +64,7 @@ Program Directory
Autoconf llvm/autoconf
llvm/projects/ModuleMaker/autoconf
llvm/projects/sample/autoconf
CellSPU backend llvm/lib/Target/CellSPU/README.txt
Google Test llvm/utils/unittest/googletest
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT

View File

@ -21,8 +21,8 @@
/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
and 'unwrap' conversion functions. */
#include "llvm/IRBuilder.h"
#include "llvm/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/PassRegistry.h"
extern "C" {
@ -173,10 +173,11 @@ typedef enum {
LLVMUWTable = 1 << 30,
LLVMNonLazyBind = 1 << 31
/* FIXME: This attribute is currently not included in the C API as
/* FIXME: These attributes are currently not included in the C API as
a temporary measure until the API/ABI impact to the C API is understood
and the path forward agreed upon.
LLVMAddressSafety = 1ULL << 32
LLVMAddressSafety = 1ULL << 32,
LLVMStackProtectStrongAttribute = 1ULL<<33
*/
} LLVMAttribute;
@ -357,6 +358,11 @@ typedef enum {
void LLVMInitializeCore(LLVMPassRegistryRef R);
/** Deallocate and destroy all ManagedStatic variables.
@see llvm::llvm_shutdown
@see ManagedStatic */
void LLVMShutdown();
/*===-- Error handling ----------------------------------------------------===*/
@ -2547,6 +2553,13 @@ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
char **OutMessage);
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData,
size_t InputDataLength,
const char *BufferName,
LLVMBool RequiresNullTerminator);
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData,
size_t InputDataLength,
const char *BufferName);
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
/**
@ -2614,6 +2627,34 @@ LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
@see llvm::PassManagerBase::~PassManagerBase. */
void LLVMDisposePassManager(LLVMPassManagerRef PM);
/**
* @}
*/
/**
* @defgroup LLVMCCoreThreading Threading
*
* Handle the structures needed to make LLVM safe for multithreading.
*
* @{
*/
/** Allocate and initialize structures needed to make LLVM safe for
multithreading. The return value indicates whether multithreaded
initialization succeeded. Must be executed in isolation from all
other LLVM api calls.
@see llvm::llvm_start_multithreaded */
LLVMBool LLVMStartMultithreaded();
/** Deallocate structures necessary to make LLVM safe for multithreading.
Must be executed in isolation from all other LLVM api calls.
@see llvm::llvm_stop_multithreaded */
void LLVMStopMultithreaded();
/** Check whether LLVM is executing in thread-safe mode or not.
@see llvm::llvm_is_multithreaded */
LLVMBool LLVMIsMultithreaded();
/**
* @}
*/

View File

@ -139,12 +139,25 @@ extern "C" {
* by passing a block of information in the DisInfo parameter and specifying the
* TagType and callback functions as described above. These can all be passed
* as NULL. If successful, this returns a disassembler context. If not, it
* returns NULL.
* returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU()
* with an empty CPU name.
*/
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Create a disassembler for the TripleName and a specific CPU. Symbolic
* disassembly is supported by passing a block of information in the DisInfo
* parameter and specifying the TagType and callback functions as described
* above. These can all be passed * as NULL. If successful, this returns a
* disassembler context. If not, it returns NULL.
*/
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Set the disassembler's options. Returns 1 if it can set the Options and 0
* otherwise.
@ -153,6 +166,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
/* The option to produce marked up assembly. */
#define LLVMDisassembler_Option_UseMarkup 1
/* The option to print immediates as hex. */
#define LLVMDisassembler_Option_PrintImmHex 2
/* The option use the other assembler printer variant */
#define LLVMDisassembler_Option_AsmPrinterVariant 4
/**
* Dispose of a disassembler context.

View File

@ -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

View File

@ -34,6 +34,7 @@ extern "C" {
void LLVMInitializeCore(LLVMPassRegistryRef R);
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R);
void LLVMInitializeVectorization(LLVMPassRegistryRef R);
void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
void LLVMInitializeIPO(LLVMPassRegistryRef R);

View File

@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef __LTO_CAPI_H__
#define __LTO_CAPI_H__
#ifndef LLVM_C_LINKTIMEOPTIMIZER_H
#define LLVM_C_LINKTIMEOPTIMIZER_H
#ifdef __cplusplus
extern "C" {

View File

@ -20,6 +20,7 @@
#define LLVM_C_TARGETMACHINE_H
#include "llvm-c/Core.h"
#include "llvm-c/Target.h"
#ifdef __cplusplus
extern "C" {

View File

@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_PASSMANAGERBUILDER
#define LLVM_C_PASSMANAGERBUILDER
#ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
#define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
#include "llvm-c/Core.h"
@ -77,8 +77,8 @@ LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM,
bool Internalize,
bool RunInliner);
LLVMBool Internalize,
LLVMBool RunInliner);
/**
* @}

View File

@ -13,8 +13,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LTO_H
#define LTO_H 1
#ifndef LLVM_C_LTO_H
#define LLVM_C_LTO_H
#include <stdbool.h>
#include <stddef.h>
@ -291,6 +291,13 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
extern void
lto_codegen_debug_options(lto_code_gen_t cg, const char *);
/**
* Initializes LLVM disassemblers.
* FIXME: This doesn't really belong here.
*/
extern void
lto_initialize_disassembler(void);
#ifdef __cplusplus
}
#endif

View File

@ -97,8 +97,8 @@
nexttoward.
*/
#ifndef LLVM_FLOAT_H
#define LLVM_FLOAT_H
#ifndef LLVM_ADT_APFLOAT_H
#define LLVM_ADT_APFLOAT_H
// APInt contains static functions implementing bignum arithmetic.
#include "llvm/ADT/APInt.h"
@ -184,9 +184,9 @@ namespace llvm {
APFloat(const fltSemantics &, integerPart);
APFloat(const fltSemantics &, fltCategory, bool negative);
APFloat(const fltSemantics &, uninitializedTag);
APFloat(const fltSemantics &, const APInt &);
explicit APFloat(double d);
explicit APFloat(float f);
explicit APFloat(const APInt &, bool isIEEE = false);
APFloat(const APFloat &);
~APFloat();
@ -300,7 +300,7 @@ namespace llvm {
/* The definition of equality is not straightforward for floating point,
so we won't use operator==. Use one of the following, or write
whatever it is you really mean. */
// bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION;
/* IEEE comparison with another floating point number (NaNs
compare unordered, 0==-0). */
@ -327,6 +327,7 @@ namespace llvm {
bool isNegative() const { return sign; }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
bool isDenormal() const;
APFloat& operator=(const APFloat &);
@ -422,7 +423,7 @@ namespace llvm {
APInt convertQuadrupleAPFloatToAPInt() const;
APInt convertF80LongDoubleAPFloatToAPInt() const;
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
void initFromAPInt(const APInt& api, bool isIEEE = false);
void initFromAPInt(const fltSemantics *Sem, const APInt& api);
void initFromHalfAPInt(const APInt& api);
void initFromFloatAPInt(const APInt& api);
void initFromDoubleAPInt(const APInt& api);
@ -462,4 +463,4 @@ namespace llvm {
hash_code hash_value(const APFloat &Arg);
} /* namespace llvm */
#endif /* LLVM_FLOAT_H */
#endif /* LLVM_ADT_APFLOAT_H */

View File

@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_APINT_H
#define LLVM_APINT_H
#ifndef LLVM_ADT_APINT_H
#define LLVM_ADT_APINT_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
@ -274,7 +274,7 @@ class APInt {
initSlowCase(that);
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move Constructor.
APInt(APInt&& that) : BitWidth(that.BitWidth), VAL(that.VAL) {
that.BitWidth = 0;
@ -427,7 +427,7 @@ class APInt {
/// @returns the all-ones value for an APInt of the specified bit-width.
/// @brief Get the all-ones value.
static APInt getAllOnesValue(unsigned numBits) {
return APInt(numBits, -1ULL, true);
return APInt(numBits, UINT64_MAX, true);
}
/// @returns the '0' value for an APInt of the specified bit-width.
@ -498,13 +498,24 @@ class APInt {
if (loBitsSet == 0)
return APInt(numBits, 0);
if (loBitsSet == APINT_BITS_PER_WORD)
return APInt(numBits, -1ULL);
return APInt(numBits, UINT64_MAX);
// For small values, return quickly.
if (loBitsSet <= APINT_BITS_PER_WORD)
return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet));
return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet));
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
/// \brief Return a value containing V broadcasted over NewLen bits.
static APInt getSplat(unsigned NewLen, const APInt &V) {
assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
APInt Val = V.zextOrSelf(NewLen);
for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
Val |= Val << I;
return Val;
}
/// \brief Determine if two APInts have the same value, after zero-extending
/// one of them (if needed!) to ensure that the bit-widths match.
static bool isSameValue(const APInt &I1, const APInt &I2) {
@ -601,7 +612,7 @@ class APInt {
return AssignSlowCase(RHS);
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move assignment operator.
APInt& operator=(APInt&& that) {
if (!isSingleWord())
@ -799,16 +810,7 @@ class APInt {
/// Signed divide this APInt by APInt RHS.
/// @brief Signed division function for APInt.
APInt sdiv(const APInt &RHS) const {
if (isNegative())
if (RHS.isNegative())
return (-(*this)).udiv(-RHS);
else
return -((-(*this)).udiv(RHS));
else if (RHS.isNegative())
return -(this->udiv(-RHS));
return this->udiv(RHS);
}
APInt sdiv(const APInt &RHS) const;
/// Perform an unsigned remainder operation on this APInt with RHS being the
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
@ -821,16 +823,7 @@ class APInt {
/// Signed remainder operation on APInt.
/// @brief Function for signed remainder operation.
APInt srem(const APInt &RHS) const {
if (isNegative())
if (RHS.isNegative())
return -((-(*this)).urem(-RHS));
else
return -((-(*this)).urem(RHS));
else if (RHS.isNegative())
return this->urem(-RHS);
return this->urem(RHS);
}
APInt srem(const APInt &RHS) const;
/// Sometimes it is convenient to divide two APInt values and obtain both the
/// quotient and remainder. This function does both operations in the same
@ -842,24 +835,9 @@ class APInt {
APInt &Quotient, APInt &Remainder);
static void sdivrem(const APInt &LHS, const APInt &RHS,
APInt &Quotient, APInt &Remainder) {
if (LHS.isNegative()) {
if (RHS.isNegative())
APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
else {
APInt::udivrem(-LHS, RHS, Quotient, Remainder);
Quotient = -Quotient;
}
Remainder = -Remainder;
} else if (RHS.isNegative()) {
APInt::udivrem(LHS, -RHS, Quotient, Remainder);
Quotient = -Quotient;
} else {
APInt::udivrem(LHS, RHS, Quotient, Remainder);
}
}
APInt &Quotient, APInt &Remainder);
// Operations that return overflow indicators.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
@ -1113,11 +1091,11 @@ class APInt {
/// @brief Set every bit to 1.
void setAllBits() {
if (isSingleWord())
VAL = -1ULL;
VAL = UINT64_MAX;
else {
// Set all the bits in all the words.
for (unsigned i = 0; i < getNumWords(); ++i)
pVal[i] = -1ULL;
pVal[i] = UINT64_MAX;
}
// Clear the unused ones
clearUnusedBits();
@ -1142,10 +1120,10 @@ class APInt {
/// @brief Toggle every bit to its opposite value.
void flipAllBits() {
if (isSingleWord())
VAL ^= -1ULL;
VAL ^= UINT64_MAX;
else {
for (unsigned i = 0; i < getNumWords(); ++i)
pVal[i] ^= -1ULL;
pVal[i] ^= UINT64_MAX;
}
clearUnusedBits();
}
@ -1191,7 +1169,8 @@ class APInt {
/// APInt. This is used in conjunction with getActiveData to extract the raw
/// value of the APInt.
unsigned getActiveWords() const {
return whichWord(getActiveBits()-1) + 1;
unsigned numActiveBits = getActiveBits();
return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
}
/// Computes the minimum bit width for this APInt while considering it to be

View File

@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_APSINT_H
#define LLVM_APSINT_H
#ifndef LLVM_ADT_APSINT_H
#define LLVM_ADT_APSINT_H
#include "llvm/ADT/APInt.h"
@ -23,7 +23,7 @@ class APSInt : public APInt {
bool IsUnsigned;
public:
/// Default constructor that creates an uninitialized APInt.
explicit APSInt() {}
explicit APSInt() : IsUnsigned(false) {}
/// APSInt ctor - Create an APSInt with the specified width, default to
/// unsigned.
@ -161,11 +161,11 @@ class APSInt : public APInt {
}
APSInt& operator++() {
static_cast<APInt&>(*this)++;
++(static_cast<APInt&>(*this));
return *this;
}
APSInt& operator--() {
static_cast<APInt&>(*this)--;
--(static_cast<APInt&>(*this));
return *this;
}
APSInt operator++(int) {

View File

@ -33,6 +33,8 @@ namespace llvm {
typedef const T *const_iterator;
typedef size_t size_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
private:
/// The start of the array, in an external buffer.
const T *Data;
@ -84,6 +86,9 @@ namespace llvm {
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
/// empty - Check if the array is empty.
bool empty() const { return Length == 0; }
@ -171,41 +176,41 @@ namespace llvm {
/// Construct an empty ArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
/// Construct an MutableArrayRef from a single element.
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
/// Construct an MutableArrayRef from a pointer and length.
/*implicit*/ MutableArrayRef(T *data, size_t length)
: ArrayRef<T>(data, length) {}
/// Construct an MutableArrayRef from a range.
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
/// Construct an MutableArrayRef from a SmallVector.
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
: ArrayRef<T>(Vec) {}
/// Construct a MutableArrayRef from a std::vector.
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
: ArrayRef<T>(Vec) {}
/// Construct an MutableArrayRef from a C array.
template <size_t N>
/*implicit*/ MutableArrayRef(T (&Arr)[N])
: ArrayRef<T>(Arr) {}
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
iterator begin() const { return data(); }
iterator end() const { return data() + this->size(); }
/// front - Get the first element.
T &front() const {
assert(!this->empty());
return data()[0];
}
/// back - Get the last element.
T &back() const {
assert(!this->empty());
@ -217,14 +222,14 @@ namespace llvm {
assert(N <= this->size() && "Invalid specifier");
return MutableArrayRef<T>(data()+N, this->size()-N);
}
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
MutableArrayRef<T> slice(unsigned N, unsigned M) const {
assert(N+M <= this->size() && "Invalid specifier");
return MutableArrayRef<T>(data()+N, M);
}
/// @}
/// @name Operator Overloads
/// @{
@ -301,5 +306,5 @@ namespace llvm {
static const bool value = true;
};
}
#endif

View File

@ -98,7 +98,7 @@ class BitVector {
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
BitVector(BitVector &&RHS)
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
RHS.Bits = 0;
@ -452,7 +452,7 @@ class BitVector {
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;

View File

@ -9,8 +9,8 @@
#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
#define LLVM_ADT_DAGDELTAALGORITHM_H
#include <vector>
#include <set>
#include <vector>
namespace llvm {

View File

@ -9,8 +9,8 @@
#ifndef LLVM_ADT_DELTAALGORITHM_H
#define LLVM_ADT_DELTAALGORITHM_H
#include <vector>
#include <set>
#include <vector>
namespace llvm {

View File

@ -14,20 +14,20 @@
#ifndef LLVM_ADT_DENSEMAP_H
#define LLVM_ADT_DENSEMAP_H
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
#include "llvm/ADT/DenseMapInfo.h"
#include <algorithm>
#include <iterator>
#include <new>
#include <utility>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstring>
#include <iterator>
#include <new>
#include <utility>
namespace llvm {
@ -75,7 +75,7 @@ class DenseMapBase {
void clear() {
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
// If the capacity of the array is huge, and the # elements used is small,
// shrink the array.
if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
@ -159,6 +159,24 @@ class DenseMapBase {
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
#if LLVM_HAS_RVALUE_REFERENCES
// Inserts key,value pair into the map if the key isn't already in the map.
// If the key is already in the map, it returns false and doesn't update the
// value.
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
BucketT *TheBucket;
if (LookupBucketFor(KV.first, TheBucket))
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(std::move(KV.first),
std::move(KV.second),
TheBucket);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
#endif
/// insert - Range insertion of pairs.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
@ -198,7 +216,7 @@ class DenseMapBase {
return FindAndConstruct(Key).second;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
value_type& FindAndConstruct(KeyT &&Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
@ -383,7 +401,7 @@ class DenseMapBase {
return TheBucket;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
BucketT *TheBucket) {
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
@ -430,7 +448,8 @@ class DenseMapBase {
incrementNumEntries();
// If we are writing over a tombstone, remember this.
if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
const KeyT EmptyKey = getEmptyKey();
if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
decrementNumTombstones();
return TheBucket;
@ -474,7 +493,6 @@ class DenseMapBase {
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
// If we've already seen a tombstone while probing, fill it in instead
// of the empty bucket we eventually probed to.
if (FoundTombstone) ThisBucket = FoundTombstone;
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
return false;
}
@ -531,13 +549,13 @@ class DenseMap
init(NumInitBuckets);
}
DenseMap(const DenseMap &other) {
DenseMap(const DenseMap &other) : BaseT() {
init(0);
copyFrom(other);
}
#if LLVM_USE_RVALUE_REFERENCES
DenseMap(DenseMap &&other) {
#if LLVM_HAS_RVALUE_REFERENCES
DenseMap(DenseMap &&other) : BaseT() {
init(0);
swap(other);
}
@ -566,7 +584,7 @@ class DenseMap
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
DenseMap& operator=(DenseMap &&other) {
this->destroyAll();
operator delete(Buckets);
@ -700,7 +718,7 @@ class SmallDenseMap
copyFrom(other);
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap(SmallDenseMap &&other) {
init(0);
swap(other);
@ -795,7 +813,7 @@ class SmallDenseMap
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap& operator=(SmallDenseMap &&other) {
this->destroyAll();
deallocateBuckets();
@ -1027,7 +1045,7 @@ class DenseMapIterator {
++Ptr;
}
};
template<typename KeyT, typename ValueT, typename KeyInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {

View File

@ -32,8 +32,10 @@ class DenseSet {
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }
size_t getMemorySize() const { return TheMap.getMemorySize(); }
/// Grow the denseset so that it has at least Size buckets. Does not shrink
/// Grow the DenseSet so that it has at least Size buckets. Will not shrink
/// the Size of the set.
void resize(size_t Size) { TheMap.resize(Size); }
void clear() {

View File

@ -34,8 +34,8 @@
#define LLVM_ADT_DEPTHFIRSTITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <set>
#include <vector>

View File

@ -16,9 +16,9 @@
#ifndef LLVM_ADT_FOLDINGSET_H
#define LLVM_ADT_FOLDINGSET_H
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class APFloat;

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
#ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H
#define LLVM_ADT_IMMUTABLEINTERVALMAP_H
#include "llvm/ADT/ImmutableMap.h"

View File

@ -11,11 +11,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_IMLIST_H
#define LLVM_ADT_IMLIST_H
#ifndef LLVM_ADT_IMMUTABLELIST_H
#define LLVM_ADT_IMMUTABLELIST_H
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_IMMAP_H
#define LLVM_ADT_IMMAP_H
#ifndef LLVM_ADT_IMMUTABLEMAP_H
#define LLVM_ADT_IMMUTABLEMAP_H
#include "llvm/ADT/ImmutableSet.h"
@ -211,17 +211,22 @@ class ImmutableMap {
friend class ImmutableMap;
public:
value_type_ref operator*() const { return itr->getValue(); }
value_type* operator->() const { return &itr->getValue(); }
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type;
typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference;
typedef typename iterator::value_type *pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typename iterator::reference operator*() const { return itr->getValue(); }
typename iterator::pointer operator->() const { return &itr->getValue(); }
key_type_ref getKey() const { return itr->getValue().first; }
data_type_ref getData() const { return itr->getValue().second; }
iterator& operator++() { ++itr; return *this; }
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
iterator& operator--() { --itr; return *this; }
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
};
@ -288,6 +293,13 @@ class ImmutableMapRef {
Factory(F) {
if (Root) { Root->retain(); }
}
explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
typename ImmutableMap<KeyT, ValT>::Factory &F)
: Root(X.getRootWithoutRetain()),
Factory(F.getTreeFactory()) {
if (Root) { Root->retain(); }
}
ImmutableMapRef(const ImmutableMapRef &X)
: Root(X.Root),
@ -318,12 +330,20 @@ class ImmutableMapRef {
return ImmutableMapRef(0, F);
}
ImmutableMapRef add(key_type_ref K, data_type_ref D) {
void manualRetain() {
if (Root) Root->retain();
}
void manualRelease() {
if (Root) Root->release();
}
ImmutableMapRef add(key_type_ref K, data_type_ref D) const {
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
return ImmutableMapRef(NewT, Factory);
}
ImmutableMapRef remove(key_type_ref K) {
ImmutableMapRef remove(key_type_ref K) const {
TreeTy *NewT = Factory->remove(Root, K);
return ImmutableMapRef(NewT, Factory);
}

View File

@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_IMSET_H
#define LLVM_ADT_IMSET_H
#ifndef LLVM_ADT_IMMUTABLESET_H
#define LLVM_ADT_IMMUTABLESET_H
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
@ -1054,18 +1054,27 @@ class ImmutableSet {
class iterator {
typename TreeTy::iterator itr;
iterator() {}
iterator(TreeTy* t) : itr(t) {}
friend class ImmutableSet<ValT,ValInfo>;
public:
iterator() {}
inline value_type_ref operator*() const { return itr->getValue(); }
inline iterator& operator++() { ++itr; return *this; }
inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
inline iterator& operator--() { --itr; return *this; }
inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
inline value_type *operator->() const { return &(operator*()); }
typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type;
typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference;
typedef typename iterator::value_type *pointer;
typedef std::bidirectional_iterator_tag iterator_category;
typename iterator::reference operator*() const { return itr->getValue(); }
typename iterator::pointer operator->() const { return &(operator*()); }
iterator& operator++() { ++itr; return *this; }
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
iterator& operator--() { --itr; return *this; }
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
};
iterator begin() const { return iterator(Root); }

View File

@ -99,8 +99,8 @@
#ifndef LLVM_ADT_INTERVALMAP_H
#define LLVM_ADT_INTERVALMAP_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include <iterator>
@ -151,6 +151,26 @@ struct IntervalMapInfo {
};
template <typename T>
struct IntervalMapHalfOpenInfo {
/// startLess - Return true if x is not in [a;b).
static inline bool startLess(const T &x, const T &a) {
return x < a;
}
/// stopLess - Return true if x is not in [a;b).
static inline bool stopLess(const T &b, const T &x) {
return b <= x;
}
/// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
static inline bool adjacent(const T &a, const T &b) {
return a == b;
}
};
/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
/// It should be considered private to the implementation.
namespace IntervalMapImpl {

View File

@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@ -123,7 +123,7 @@ namespace llvm {
retain();
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
S.Obj = 0;
}
@ -226,13 +226,13 @@ namespace llvm {
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
return Val.getPtr();
}
};
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
typedef /*const*/ T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
return Val.getPtr();
}
@ -240,4 +240,4 @@ namespace llvm {
} // end namespace llvm
#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include <vector>
namespace llvm {
@ -63,6 +64,11 @@ class MapVector {
return Vector.empty();
}
std::pair<KeyT, ValueT> &front() { return Vector.front(); }
const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
std::pair<KeyT, ValueT> &back() { return Vector.back(); }
const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
void clear() {
Map.clear();
Vector.clear();
@ -79,10 +85,46 @@ class MapVector {
return Vector[I].second;
}
ValueT lookup(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
}
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
unsigned &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(KV.first, KV.second));
I = Vector.size() - 1;
return std::make_pair(llvm::prior(end()), true);
}
return std::make_pair(begin() + I, false);
}
unsigned count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
}
iterator find(const KeyT &Key) {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? Vector.end() :
(Vector.begin() + Pos->second);
}
const_iterator find(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? Vector.end() :
(Vector.begin() + Pos->second);
}
/// \brief Remove the last element from the vector.
void pop_back() {
typename MapType::iterator Pos = Map.find(Vector.back().first);
Map.erase(Pos);
Vector.pop_back();
}
};
}

View 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

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_NULLABLE_PTR_H
#define LLVM_ADT_NULLABLE_PTR_H
#ifndef LLVM_ADT_NULLABLEPTR_H
#define LLVM_ADT_NULLABLEPTR_H
#include <cassert>
#include <cstddef>

View File

@ -13,13 +13,15 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_OPTIONAL
#define LLVM_ADT_OPTIONAL
#ifndef LLVM_ADT_OPTIONAL_H
#define LLVM_ADT_OPTIONAL_H
#include "llvm/ADT/None.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/AlignOf.h"
#include <cassert>
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
#include <utility>
#endif
@ -27,54 +29,116 @@ namespace llvm {
template<typename T>
class Optional {
T x;
unsigned hasVal : 1;
AlignedCharArrayUnion<T> storage;
bool hasVal;
public:
explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
Optional(NoneType) : hasVal(false) {}
explicit Optional() : hasVal(false) {}
Optional(const T &y) : hasVal(true) {
new (storage.buffer) T(y);
}
Optional(const Optional &O) : hasVal(O.hasVal) {
if (hasVal)
new (storage.buffer) T(*O);
}
#if LLVM_USE_RVALUE_REFERENCES
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
#if LLVM_HAS_RVALUE_REFERENCES
Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y));
}
Optional(Optional<T> &&O) : hasVal(O) {
if (O) {
new (storage.buffer) T(std::move(*O));
O.reset();
}
}
Optional &operator=(T &&y) {
if (hasVal)
**this = std::move(y);
else {
new (storage.buffer) T(std::move(y));
hasVal = true;
}
return *this;
}
Optional &operator=(Optional &&O) {
if (!O)
reset();
else {
*this = std::move(*O);
O.reset();
}
return *this;
}
#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
// FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
// could be made more efficient by passing by value, possibly unifying them
// with the rvalue versions above - but this could place a different set of
// requirements (notably: the existence of a default ctor) when implemented
// in that way. Careful SFINAE to avoid such pitfalls would be required.
Optional &operator=(const T &y) {
x = y;
hasVal = true;
if (hasVal)
**this = y;
else {
new (storage.buffer) T(y);
hasVal = true;
}
return *this;
}
const T* getPointer() const { assert(hasVal); return &x; }
const T& getValue() const { assert(hasVal); return x; }
operator bool() const { return hasVal; }
Optional &operator=(const Optional &O) {
if (!O)
reset();
else
*this = *O;
return *this;
}
void reset() {
if (hasVal) {
(**this).~T();
hasVal = false;
}
}
~Optional() {
reset();
}
const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
LLVM_EXPLICIT operator bool() const { return hasVal; }
bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
const T& operator*() const { assert(hasVal); return x; }
T* operator->() { return getPointer(); }
const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
#if LLVM_HAS_RVALUE_REFERENCE_THIS
T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
#endif
};
template<typename T> struct simplify_type;
template <typename T>
struct simplify_type<const Optional<T> > {
typedef const T* SimpleType;
static SimpleType getSimplifiedValue(const Optional<T> &Val) {
return Val.getPointer();
}
template <typename T> struct isPodLike;
template <typename T> struct isPodLike<Optional<T> > {
// An Optional<T> is pod-like if T is.
static const bool value = isPodLike<T>::value;
};
template <typename T>
struct simplify_type<Optional<T> >
: public simplify_type<const Optional<T> > {};
/// \brief Poison comparison between two \c Optional objects. Clients needs to
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator==(const Optional<T> &X, const Optional<U> &Y);
@ -83,7 +147,7 @@ void operator==(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator!=(const Optional<T> &X, const Optional<U> &Y);
@ -92,7 +156,7 @@ void operator!=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator<(const Optional<T> &X, const Optional<U> &Y);
@ -101,7 +165,7 @@ void operator<(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator<=(const Optional<T> &X, const Optional<U> &Y);
@ -110,7 +174,7 @@ void operator<=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator>=(const Optional<T> &X, const Optional<U> &Y);
@ -119,7 +183,7 @@ void operator>=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
/// This routine will never be defined. It returns \c void to help diagnose
/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator>(const Optional<T> &X, const Optional<U> &Y);

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_OWNING_PTR_H
#define LLVM_ADT_OWNING_PTR_H
#ifndef LLVM_ADT_OWNINGPTR_H
#define LLVM_ADT_OWNINGPTR_H
#include "llvm/Support/Compiler.h"
#include <cassert>
@ -32,7 +32,7 @@ class OwningPtr {
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
OwningPtr &operator=(OwningPtr &&Other) {
@ -95,7 +95,7 @@ class OwningArrayPtr {
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {

View File

@ -57,11 +57,13 @@ class PointerIntPair {
};
public:
PointerIntPair() : Value(0) {}
PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
PointerIntPair(PointerTy Ptr, IntType Int) {
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
"PointerIntPair formed with integer size too large for pointer");
setPointer(Ptr);
setInt(Int);
setPointerAndInt(Ptr, Int);
}
explicit PointerIntPair(PointerTy Ptr) {
initWithPointer(Ptr);
}
PointerTy getPointer() const {
@ -91,6 +93,25 @@ class PointerIntPair {
Value |= IntVal << IntShift; // Set new integer.
}
void initWithPointer(PointerTy Ptr) {
intptr_t PtrVal
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
"Pointer is not sufficiently aligned");
Value = PtrVal;
}
void setPointerAndInt(PointerTy Ptr, IntType Int) {
intptr_t PtrVal
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
"Pointer is not sufficiently aligned");
intptr_t IntVal = Int;
assert(IntVal < (1 << IntBits) && "Integer too large for field");
Value = PtrVal | (IntVal << IntShift);
}
PointerTy const *getAddrOfPointer() const {
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
}

View File

@ -95,15 +95,11 @@ namespace llvm {
public:
PointerUnion() {}
PointerUnion(PT1 V) {
Val.setPointer(
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
Val.setInt(0);
PointerUnion(PT1 V) : Val(
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
}
PointerUnion(PT2 V) {
Val.setPointer(
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
Val.setInt(1);
PointerUnion(PT2 V) : Val(
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
}
/// isNull - Return true if the pointer held in the union is null,
@ -160,15 +156,14 @@ namespace llvm {
/// Assignment operators - Allow assigning into this union from either
/// pointer type, setting the discriminator to remember what it came from.
const PointerUnion &operator=(const PT1 &RHS) {
Val.setPointer(
Val.initWithPointer(
const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
Val.setInt(0);
return *this;
}
const PointerUnion &operator=(const PT2 &RHS) {
Val.setPointer(
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)));
Val.setInt(1);
Val.setPointerAndInt(
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
1);
return *this;
}

View File

@ -260,7 +260,7 @@ class ReversePostOrderTraversal {
typedef typename GT::NodeType NodeType;
std::vector<NodeType*> Blocks; // Block list in normal PO order
inline void Initialize(NodeType *BB) {
copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
}
public:
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_PRIORITY_QUEUE_H
#define LLVM_ADT_PRIORITY_QUEUE_H
#ifndef LLVM_ADT_PRIORITYQUEUE_H
#define LLVM_ADT_PRIORITYQUEUE_H
#include <algorithm>
#include <queue>

View File

@ -21,8 +21,8 @@
#ifndef LLVM_ADT_SCCITERATOR_H
#define LLVM_ADT_SCCITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include <vector>
namespace llvm {

View File

@ -246,10 +246,10 @@ inline int array_pod_sort_comparator(const void *P1, const void *P2) {
return 0;
}
/// get_array_pad_sort_comparator - This is an internal helper function used to
/// get_array_pod_sort_comparator - This is an internal helper function used to
/// get type deduction of T right.
template<typename T>
inline int (*get_array_pad_sort_comparator(const T &))
inline int (*get_array_pod_sort_comparator(const T &))
(const void*, const void*) {
return array_pod_sort_comparator<T>;
}
@ -274,7 +274,7 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
// Don't dereference start iterator of empty sequence.
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start),
get_array_pad_sort_comparator(*Start));
get_array_pod_sort_comparator(*Start));
}
template<class IteratorTy>

View File

@ -153,7 +153,7 @@ class SmallBitVector {
switchToLarge(new BitVector(*RHS.getPointer()));
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
RHS.X = 1;
}
@ -178,9 +178,9 @@ class SmallBitVector {
unsigned count() const {
if (isSmall()) {
uintptr_t Bits = getSmallBits();
if (sizeof(uintptr_t) * CHAR_BIT == 32)
if (NumBaseBits == 32)
return CountPopulation_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
if (NumBaseBits == 64)
return CountPopulation_64(Bits);
llvm_unreachable("Unsupported!");
}
@ -215,9 +215,9 @@ class SmallBitVector {
uintptr_t Bits = getSmallBits();
if (Bits == 0)
return -1;
if (sizeof(uintptr_t) * CHAR_BIT == 32)
if (NumBaseBits == 32)
return CountTrailingZeros_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
if (NumBaseBits == 64)
return CountTrailingZeros_64(Bits);
llvm_unreachable("Unsupported!");
}
@ -233,9 +233,9 @@ class SmallBitVector {
Bits &= ~uintptr_t(0) << (Prev + 1);
if (Bits == 0 || Prev + 1 >= getSmallSize())
return -1;
if (sizeof(uintptr_t) * CHAR_BIT == 32)
if (NumBaseBits == 32)
return CountTrailingZeros_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
if (NumBaseBits == 64)
return CountTrailingZeros_64(Bits);
llvm_unreachable("Unsupported!");
}
@ -472,7 +472,7 @@ class SmallBitVector {
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
const SmallBitVector &operator=(SmallBitVector &&RHS) {
if (this != &RHS) {
clear();

View File

@ -54,8 +54,6 @@ class SmallPtrSetImpl {
/// then the set is in 'small mode'.
const void **CurArray;
/// CurArraySize - The allocated size of CurArray, always a power of two.
/// Note that CurArray points to an array that has CurArraySize+1 elements in
/// it, so that the end iterator actually points to valid memory.
unsigned CurArraySize;
// If small, this is # elts allocated consecutively
@ -68,9 +66,6 @@ class SmallPtrSetImpl {
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
"Initial size must be a power of two!");
// The end pointer, always valid, is set to a valid element to help the
// iterator.
CurArray[SmallSize] = 0;
clear();
}
~SmallPtrSetImpl();
@ -147,9 +142,11 @@ class SmallPtrSetImpl {
class SmallPtrSetIteratorImpl {
protected:
const void *const *Bucket;
const void *const *End;
public:
explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
AdvanceIfNotValid();
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
: Bucket(BP), End(E) {
AdvanceIfNotValid();
}
bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
@ -164,8 +161,10 @@ class SmallPtrSetIteratorImpl {
/// that is. This is guaranteed to stop because the end() bucket is marked
/// valid.
void AdvanceIfNotValid() {
while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
*Bucket == SmallPtrSetImpl::getTombstoneMarker())
assert(Bucket <= End);
while (Bucket != End &&
(*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
*Bucket == SmallPtrSetImpl::getTombstoneMarker()))
++Bucket;
}
};
@ -182,12 +181,13 @@ class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
explicit SmallPtrSetIterator(const void *const *BP)
: SmallPtrSetIteratorImpl(BP) {}
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
: SmallPtrSetIteratorImpl(BP, E) {}
// Most methods provided by baseclass.
const PtrTy operator*() const {
assert(Bucket < End);
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
}
@ -236,9 +236,8 @@ template<class PtrType, unsigned SmallSize>
class SmallPtrSet : public SmallPtrSetImpl {
// Make sure that SmallSize is a power of two, round up if not.
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
/// SmallStorage - Fixed size storage used in 'small mode'. The extra element
/// ensures that the end iterator actually points to valid memory.
const void *SmallStorage[SmallSizePowTwo+1];
/// SmallStorage - Fixed size storage used in 'small mode'.
const void *SmallStorage[SmallSizePowTwo];
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
public:
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
@ -275,10 +274,10 @@ class SmallPtrSet : public SmallPtrSetImpl {
typedef SmallPtrSetIterator<PtrType> iterator;
typedef SmallPtrSetIterator<PtrType> const_iterator;
inline iterator begin() const {
return iterator(CurArray);
return iterator(CurArray, CurArray+CurArraySize);
}
inline iterator end() const {
return iterator(CurArray+CurArraySize);
return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
}
// Allow assignment from any smallptrset with the same element type even if it

View File

@ -14,8 +14,8 @@
#ifndef LLVM_ADT_SMALLSET_H
#define LLVM_ADT_SMALLSET_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include <set>
namespace llvm {
@ -55,6 +55,7 @@ class SmallSet {
}
/// insert - Insert an element into the set if it isn't already there.
/// Returns true if the element is inserted (it was not in the set before).
bool insert(const T &V) {
if (!isSmall())
return Set.insert(V).second;

View File

@ -77,7 +77,7 @@ class SmallString : public SmallVector<char, InternalLen> {
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
}
void append(size_t NumInputs, char Elt) {
SmallVectorImpl<char>::append(NumInputs, Elt);
}

View File

@ -16,6 +16,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
@ -145,16 +146,20 @@ class SmallVectorTemplateCommon : public SmallVectorBase {
}
reference front() {
assert(!empty());
return begin()[0];
}
const_reference front() const {
assert(!empty());
return begin()[0];
}
reference back() {
assert(!empty());
return end()[-1];
}
const_reference back() const {
assert(!empty());
return end()[-1];
}
};
@ -178,7 +183,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
/// std::move, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move(It1 I, It1 E, It2 Dest) {
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
*Dest = ::std::move(*I);
return Dest;
@ -193,7 +198,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
/// std::move_backward, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move_backward(It1 I, It1 E, It2 Dest) {
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
while (I != E)
*--Dest = ::std::move(*--E);
return Dest;
@ -206,7 +211,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
/// memory starting with "Dest", constructing elements as needed.
template<typename It1, typename It2>
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
::new ((void*) &*Dest) T(::std::move(*I));
#else
@ -239,7 +244,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
goto Retry;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
void push_back(T &&Elt) {
if (this->EndX < this->CapacityX) {
Retry:
@ -263,7 +268,8 @@ template <typename T, bool isPodLike>
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
size_t CurCapacity = this->capacity();
size_t CurSize = this->size();
size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
// Always grow, even from zero.
size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
if (NewCapacity < MinSize)
NewCapacity = MinSize;
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
@ -365,7 +371,7 @@ template <typename T>
class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
public:
typedef typename SuperClass::iterator iterator;
typedef typename SuperClass::size_type size_type;
@ -422,7 +428,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
}
T pop_back_val() {
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
T Result = ::std::move(this->back());
#else
T Result = this->back();
@ -495,7 +501,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
return(N);
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
iterator insert(iterator I, T &&Elt) {
if (I == this->end()) { // Important special case for empty vector.
this->push_back(::std::move(Elt));
@ -667,7 +673,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
#endif
@ -787,7 +793,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
template <typename T>
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// Avoid self-assignment.
@ -898,7 +904,7 @@ class SmallVector : public SmallVectorImpl<T> {
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));

View 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

View File

@ -20,8 +20,8 @@
#ifndef LLVM_ADT_SPARSESET_H
#define LLVM_ADT_SPARSESET_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include <limits>

View File

@ -51,7 +51,9 @@ class Statistic {
// Allow use of this class as the value itself.
operator unsigned() const { return Value; }
const Statistic &operator=(unsigned Val) {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
const Statistic &operator=(unsigned Val) {
Value = Val;
return init();
}
@ -106,6 +108,46 @@ class Statistic {
return init();
}
#else // Statistics are disabled in release builds.
const Statistic &operator=(unsigned Val) {
return *this;
}
const Statistic &operator++() {
return *this;
}
unsigned operator++(int) {
return 0;
}
const Statistic &operator--() {
return *this;
}
unsigned operator--(int) {
return 0;
}
const Statistic &operator+=(const unsigned &V) {
return *this;
}
const Statistic &operator-=(const unsigned &V) {
return *this;
}
const Statistic &operator*=(const unsigned &V) {
return *this;
}
const Statistic &operator/=(const unsigned &V) {
return *this;
}
#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
protected:
Statistic &init() {
bool tmp = Initialized;

View File

@ -14,8 +14,8 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
template<typename T> class SmallVectorImpl;
@ -27,6 +27,17 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
/// Interpret the given character \p C as a hexadecimal digit and return its
/// value.
///
/// If \p C is not a valid hex digit, -1U is returned.
static inline unsigned hexDigitValue(char C) {
if (C >= '0' && C <= '9') return C-'0';
if (C >= 'a' && C <= 'f') return C-'a'+10U;
if (C >= 'A' && C <= 'F') return C-'A'+10U;
return -1U;
}
/// utohex_buffer - Emit the specified number into the buffer specified by
/// BufferEnd, returning a pointer to the start of the string. This can be used
/// like this: (note that the buffer must be large enough to handle any number):

View File

@ -53,7 +53,7 @@ class StringMapEntryBase {
class StringMapImpl {
protected:
// Array of NumBuckets pointers to entries, null pointers are holes.
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
// by an array of the actual hash values as unsigned integers.
StringMapEntryBase **TheTable;
unsigned NumBuckets;
@ -171,7 +171,6 @@ class StringMapEntry : public StringMapEntryBase {
return Create(KeyStart, KeyEnd, Allocator, 0);
}
/// Create - Create a StringMapEntry with normal malloc/free.
template<typename InitType>
static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
@ -204,7 +203,6 @@ class StringMapEntry : public StringMapEntryBase {
return *reinterpret_cast<StringMapEntry*>(Ptr);
}
/// Destroy - Destroy this StringMapEntry, releasing memory back to the
/// specified allocator.
template<typename AllocatorTy>
@ -239,6 +237,10 @@ class StringMap : public StringMapImpl {
explicit StringMap(AllocatorTy A)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
StringMap(unsigned InitialSize, AllocatorTy A)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
Allocator(A) {}
StringMap(const StringMap &RHS)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
assert(RHS.empty() &&
@ -290,7 +292,7 @@ class StringMap : public StringMapImpl {
return const_iterator(TheTable+Bucket, true);
}
/// lookup - Return the entry for the specified key, or a default
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueTy lookup(StringRef Key) const {
const_iterator it = find(Key);
@ -336,8 +338,8 @@ class StringMap : public StringMapImpl {
StringMapEntryBase *&Bucket = TheTable[I];
if (Bucket && Bucket != getTombstoneVal()) {
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
Bucket = 0;
}
Bucket = 0;
}
NumItems = 0;
@ -427,7 +429,7 @@ class StringMapConstIterator {
return Ptr != RHS.Ptr;
}
inline StringMapConstIterator& operator++() { // Preincrement
inline StringMapConstIterator& operator++() { // Preincrement
++Ptr;
AdvancePastEmptyBuckets();
return *this;

View File

@ -11,7 +11,6 @@
#define LLVM_ADT_STRINGREF_H
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@ -58,14 +57,14 @@ namespace llvm {
// integer works around this bug.
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
static size_t max(size_t a, size_t b) { return a > b ? a : b; }
// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
if (Length == 0) { return 0; }
return ::memcmp(Lhs,Rhs,Length);
}
public:
/// @name Constructors
/// @{
@ -388,7 +387,7 @@ namespace llvm {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
StringRef drop_front(unsigned N = 1) const {
@ -536,7 +535,7 @@ namespace llvm {
return LHS.compare(RHS) != -1;
}
inline std::string &operator+=(std::string &buffer, llvm::StringRef string) {
inline std::string &operator+=(std::string &buffer, StringRef string) {
return buffer.append(string.data(), string.size());
}

View File

@ -18,23 +18,25 @@
namespace llvm {
/// StringSet - A wrapper for StringMap that provides set-like
/// functionality. Only insert() and count() methods are used by my
/// code.
/// StringSet - A wrapper for StringMap that provides set-like functionality.
template <class AllocatorTy = llvm::MallocAllocator>
class StringSet : public llvm::StringMap<char, AllocatorTy> {
typedef llvm::StringMap<char, AllocatorTy> base;
public:
bool insert(StringRef InLang) {
assert(!InLang.empty());
const char *KeyStart = InLang.data();
const char *KeyEnd = KeyStart + InLang.size();
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+');
if (!base::insert(Entry)) {
Entry->Destroy(base::getAllocator());
/// insert - Insert the specified key into the set. If the key already
/// exists in the set, return false and ignore the request, otherwise insert
/// it and return true.
bool insert(StringRef Key) {
// Get or create the map entry for the key; if it doesn't exist the value
// type will be default constructed which we use to detect insert.
//
// We use '+' as the sentinel value in the map.
assert(!Key.empty());
StringMapEntry<char> &Entry = this->GetOrCreateValue(Key);
if (Entry.getValue() == '+')
return false;
}
Entry.setValue('+');
return true;
}
};

View File

@ -70,7 +70,7 @@ class TinyPtrVector {
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
#if LLVM_HAS_RVALUE_REFERENCES
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
RHS.Val = (EltTy)0;
}

View File

@ -44,7 +44,7 @@ class Triple {
UnknownArch,
arm, // ARM; arm, armv.*, xscale
cellspu, // CellSPU: spu, cellspu
aarch64, // AArch64: aarch64
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
@ -101,8 +101,8 @@ class Triple {
Haiku,
Minix,
RTEMS,
NativeClient,
CNK, // BG/P Compute-Node Kernel
NaCl, // Native Client
CNK, // BG/P Compute-Node Kernel
Bitrig,
AIX
};
@ -112,6 +112,7 @@ class Triple {
GNU,
GNUEABI,
GNUEABIHF,
GNUX32,
EABI,
MachO,
Android,
@ -296,9 +297,14 @@ class Triple {
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
}
/// Is this an iOS triple.
bool isiOS() const {
return getOS() == Triple::IOS;
}
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const {
return isMacOSX() || getOS() == Triple::IOS;
return isMacOSX() || isiOS();
}
/// \brief Tests for either Cygwin or MinGW OS
@ -311,6 +317,11 @@ class Triple {
return getOS() == Triple::Win32 || isOSCygMing();
}
/// \brief Tests whether the OS is NaCl (Native Client)
bool isOSNaCl() const {
return getOS() == Triple::NaCl;
}
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return !isOSDarwin() && !isOSWindows();

View File

@ -27,10 +27,9 @@
#define LLVM_ADT_VALUEMAP_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
#include "llvm/Support/Mutex.h"
#include <iterator>
namespace llvm {

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
#define LLVM_ADT_VARIADIC_FUNCTION_H
#ifndef LLVM_ADT_VARIADICFUNCTION_H
#define LLVM_ADT_VARIADICFUNCTION_H
#include "llvm/ADT/ArrayRef.h"
@ -328,4 +328,4 @@ struct VariadicFunction3 {
} // end namespace llvm
#endif // LLVM_ADT_VARIADIC_FUNCTION_H
#endif // LLVM_ADT_VARIADICFUNCTION_H

View File

@ -234,17 +234,17 @@ class ilist_iterator
pointer getNodePtrUnchecked() const { return NodePtr; }
};
// do not implement. this is to catch errors when people try to use
// them as random access iterators
// These are to catch errors when people try to use them as random access
// iterators.
template<typename T>
void operator-(int, ilist_iterator<T>);
void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
template<typename T>
void operator-(ilist_iterator<T>,int);
void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
template<typename T>
void operator+(int, ilist_iterator<T>);
void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
template<typename T>
void operator+(ilist_iterator<T>,int);
void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
// operator!=/operator== - Allow mixed comparisons without dereferencing
// the iterator, which could very likely be pointing to end().
@ -274,12 +274,12 @@ template<typename From> struct simplify_type;
template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
typedef NodeTy* SimpleType;
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
return &*Node;
}
};
template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
typedef NodeTy* SimpleType;
typedef /*const*/ NodeTy* SimpleType;
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
return &*Node;
@ -465,6 +465,17 @@ class iplist : public Traits {
return where;
}
/// Remove all nodes from the list like clear(), but do not call
/// removeNodeFromList() or deleteNode().
///
/// This should only be used immediately before freeing nodes in bulk to
/// avoid traversing the list and bringing all the nodes into cache.
void clearAndLeakNodesUnsafely() {
if (Head) {
Head = getTail();
this->setPrev(Head, Head);
}
}
private:
// transfer - The heart of the splice function. Move linked list nodes from
@ -472,6 +483,10 @@ class iplist : public Traits {
//
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
assert(first != last && "Should be checked by callers");
// Position cannot be contained in the range to be transferred.
// Check for the most common mistake.
assert(position != first &&
"Insertion point can't be one of the transferred nodes");
if (position != last) {
// Note: we have to be careful about the case when we move the first node

View File

@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ILIST_NODE_H
#define LLVM_ADT_ILIST_NODE_H
#ifndef LLVM_ADT_ILISTNODE_H
#define LLVM_ADT_ILISTNODE_H
namespace llvm {

View File

@ -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

View File

@ -34,11 +34,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
#define LLVM_ANALYSIS_ALIASANALYSIS_H
#include "llvm/Support/CallSite.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
@ -373,7 +373,7 @@ class AliasAnalysis {
return getModRefInfo(I, Location(P, Size));
}
/// getModRefInfo (for call sites) - Return whether information about whether
/// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc);
@ -384,7 +384,7 @@ class AliasAnalysis {
return getModRefInfo(CS, Location(P, Size));
}
/// getModRefInfo (for calls) - Return whether information about whether
/// getModRefInfo (for calls) - Return information about whether
/// a particular call modifies or reads the specified memory location.
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
return getModRefInfo(ImmutableCallSite(C), Loc);
@ -395,7 +395,7 @@ class AliasAnalysis {
return getModRefInfo(C, Location(P, Size));
}
/// getModRefInfo (for invokes) - Return whether information about whether
/// getModRefInfo (for invokes) - Return information about whether
/// a particular invoke modifies or reads the specified memory location.
ModRefResult getModRefInfo(const InvokeInst *I,
const Location &Loc) {
@ -408,7 +408,7 @@ class AliasAnalysis {
return getModRefInfo(I, Location(P, Size));
}
/// getModRefInfo (for loads) - Return whether information about whether
/// getModRefInfo (for loads) - Return information about whether
/// a particular load modifies or reads the specified memory location.
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
@ -417,7 +417,7 @@ class AliasAnalysis {
return getModRefInfo(L, Location(P, Size));
}
/// getModRefInfo (for stores) - Return whether information about whether
/// getModRefInfo (for stores) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
@ -426,7 +426,7 @@ class AliasAnalysis {
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for fences) - Return whether information about whether
/// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
// Conservatively correct. (We could possibly be a bit smarter if
@ -439,7 +439,7 @@ class AliasAnalysis {
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for cmpxchges) - Return whether information about whether
/// getModRefInfo (for cmpxchges) - Return information about whether
/// a particular cmpxchg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
@ -449,7 +449,7 @@ class AliasAnalysis {
return getModRefInfo(CX, Location(P, Size));
}
/// getModRefInfo (for atomicrmws) - Return whether information about whether
/// getModRefInfo (for atomicrmws) - Return information about whether
/// a particular atomicrmw modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
@ -459,7 +459,7 @@ class AliasAnalysis {
return getModRefInfo(RMW, Location(P, Size));
}
/// getModRefInfo (for va_args) - Return whether information about whether
/// getModRefInfo (for va_args) - Return information about whether
/// a particular va_arg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
@ -587,17 +587,12 @@ bool isNoAliasCall(const Value *V);
/// isIdentifiedObject - Return true if this pointer refers to a distinct and
/// identifiable object. This returns true for:
/// Global Variables and Functions (but not Global Aliases)
/// Allocas and Mallocs
/// Allocas
/// ByVal and NoAlias Arguments
/// NoAlias returns
/// NoAlias returns (e.g. calls to malloc)
///
bool isIdentifiedObject(const Value *V);
/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
/// its definition. This returns true for allocas, non-extern-weak globals and
/// byval arguments.
bool isKnownNonNull(const Value *V);
} // End llvm namespace
#endif

View File

@ -17,11 +17,10 @@
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/ValueHandle.h"
#include <vector>
namespace llvm {

View File

@ -14,17 +14,17 @@
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#include "llvm/BasicBlock.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <vector>
#include <string>
#include <vector>
namespace llvm {
@ -271,7 +271,7 @@ class BlockFrequencyImpl {
BlockT *EntryBlock = fn->begin();
copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT));
unsigned RPOidx = 0;
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {

View File

@ -14,10 +14,10 @@
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
namespace llvm {

View File

@ -15,10 +15,10 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/GraphWriter.h"

View File

@ -51,13 +51,13 @@
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
#define LLVM_ANALYSIS_CALLGRAPH_H
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/IncludeFile.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {

View File

@ -18,11 +18,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
#define LLVM_CALL_GRAPH_SCC_PASS_H
#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#include "llvm/Pass.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Pass.h"
namespace llvm {
@ -39,6 +39,9 @@ class CallGraphSCCPass : public Pass {
/// corresponding to a CallGraph.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
virtual bool doInitialization(CallGraph &CG) {

View 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

View File

@ -14,12 +14,11 @@
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
#define LLVM_ANALYSIS_CAPTURETRACKING_H
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
class Value;
class Use;
/// PointerMayBeCaptured - Return true if this pointer value may be captured
/// by the enclosing function (which is required to exist). This routine can
/// be expensive, so consider caching the results. The boolean ReturnCaptures

View File

@ -19,77 +19,75 @@
#include "llvm/Support/CallSite.h"
namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class DataLayout;
class Value;
class BasicBlock;
class Function;
class Instruction;
class DataLayout;
class TargetTransformInfo;
class Value;
/// \brief Check whether an instruction is likely to be "free" when lowered.
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
/// \brief Check whether a call will lower to something small.
///
/// This tests checks whether this callsite will lower to something
/// significantly cheaper than a traditional call, often a single
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
/// return true, so will this function.
bool callIsSmall(ImmutableCallSite CS);
/// \brief Check whether a call will lower to something small.
/// \brief Utility to calculate the size and a few similar metrics for a set
/// of basic blocks.
struct CodeMetrics {
/// \brief True if this function contains a call to setjmp or other functions
/// with attribute "returns twice" without having the attribute itself.
bool exposesReturnsTwice;
/// \brief True if this function calls itself.
bool isRecursive;
/// \brief True if this function cannot be duplicated.
///
/// This tests checks whether this callsite will lower to something
/// significantly cheaper than a traditional call, often a single
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
/// return true, so will this function.
bool callIsSmall(ImmutableCallSite CS);
/// True if this function contains one or more indirect branches, or it contains
/// one or more 'noduplicate' instructions.
bool notDuplicatable;
/// \brief Utility to calculate the size and a few similar metrics for a set
/// of basic blocks.
struct CodeMetrics {
/// \brief True if this function contains a call to setjmp or other functions
/// with attribute "returns twice" without having the attribute itself.
bool exposesReturnsTwice;
/// \brief True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
/// \brief True if this function calls itself.
bool isRecursive;
/// \brief Number of instructions in the analyzed blocks.
unsigned NumInsts;
/// \brief True if this function contains one or more indirect branches.
bool containsIndirectBr;
/// \brief Number of analyzed blocks.
unsigned NumBlocks;
/// \brief True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
/// \brief Keeps track of basic block code size estimates.
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
/// \brief Number of instructions in the analyzed blocks.
unsigned NumInsts;
/// \brief Keep track of the number of calls to 'big' functions.
unsigned NumCalls;
/// \brief Number of analyzed blocks.
unsigned NumBlocks;
/// \brief The number of calls to internal functions with a single caller.
///
/// These are likely targets for future inlining, likely exposed by
/// interleaved devirtualization.
unsigned NumInlineCandidates;
/// \brief Keeps track of basic block code size estimates.
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
/// \brief How many instructions produce vector values.
///
/// The inliner is more aggressive with inlining vector kernels.
unsigned NumVectorInsts;
/// \brief Keep track of the number of calls to 'big' functions.
unsigned NumCalls;
/// \brief How many 'ret' instructions the blocks contain.
unsigned NumRets;
/// \brief The number of calls to internal functions with a single caller.
///
/// These are likely targets for future inlining, likely exposed by
/// interleaved devirtualization.
unsigned NumInlineCandidates;
CodeMetrics()
: exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
/// \brief How many instructions produce vector values.
///
/// The inliner is more aggressive with inlining vector kernels.
unsigned NumVectorInsts;
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
};
/// \brief How many 'ret' instructions the blocks contain.
unsigned NumRets;
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
containsIndirectBr(false), usesDynamicAlloca(false),
NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0),
NumRets(0) {}
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
/// \brief Add information about a function to the current state.
void analyzeFunction(Function *F, const DataLayout *TD = 0);
};
}
#endif

View File

@ -11,27 +11,25 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#include "llvm/Pass.h"
#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
namespace llvm {
template <class Analysis, bool Simple>
struct DOTGraphTraitsViewer : public FunctionPass {
std::string Name;
DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
Name = GraphName;
}
template <class Analysis, bool Simple>
class DOTGraphTraitsViewer : public FunctionPass {
public:
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
virtual bool runOnFunction(Function &F) {
Analysis *Graph;
std::string Title, GraphName;
Graph = &getAnalysis<Analysis>();
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
Title = GraphName + " for '" + F.getName().str() + "' function";
Analysis *Graph = &getAnalysis<Analysis>();
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
ViewGraph(Graph, Name, Simple, Title);
return false;
@ -41,36 +39,34 @@ struct DOTGraphTraitsViewer : public FunctionPass {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
template <class Analysis, bool Simple>
struct DOTGraphTraitsPrinter : public FunctionPass {
std::string Name;
DOTGraphTraitsPrinter(std::string GraphName, char &ID)
: FunctionPass(ID) {
Name = GraphName;
}
class DOTGraphTraitsPrinter : public FunctionPass {
public:
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
virtual bool runOnFunction(Function &F) {
Analysis *Graph;
Analysis *Graph = &getAnalysis<Analysis>();
std::string Filename = Name + "." + F.getName().str() + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
std::string ErrorInfo;
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
Graph = &getAnalysis<Analysis>();
std::string Title, GraphName;
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
Title = GraphName + " for '" + F.getName().str() + "' function";
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
return false;
}
@ -78,6 +74,69 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
}
template <class Analysis, bool Simple>
class DOTGraphTraitsModuleViewer : public ModulePass {
public:
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
virtual bool runOnModule(Module &M) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
ViewGraph(Graph, Name, Simple, Title);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
template <class Analysis, bool Simple>
class DOTGraphTraitsModulePrinter : public ModulePass {
public:
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
virtual bool runOnModule(Module &M) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string Filename = Name + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
} // end namespace llvm
#endif

View File

@ -18,6 +18,16 @@
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// This pass exists to support the DependenceGraph pass. There are two separate
// passes because there's a useful separation of concerns. A dependence exists
// if two conditions are met:
//
// 1) Two instructions reference the same memory location, and
// 2) There is a flow of control leading from one instruction to the other.
//
// DependenceAnalysis attacks the first condition; DependenceGraph will attack
// the second (it's not yet ready).
//
// Please note that this is work in progress and the interface is subject to
// change.
//
@ -30,9 +40,9 @@
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
namespace llvm {
class AliasAnalysis;
@ -53,8 +63,8 @@ namespace llvm {
/// input dependences are unordered.
class Dependence {
public:
Dependence(const Instruction *Source,
const Instruction *Destination) :
Dependence(Instruction *Source,
Instruction *Destination) :
Src(Source), Dst(Destination) {}
virtual ~Dependence() {}
@ -82,11 +92,11 @@ namespace llvm {
/// getSrc - Returns the source instruction for this dependence.
///
const Instruction *getSrc() const { return Src; }
Instruction *getSrc() const { return Src; }
/// getDst - Returns the destination instruction for this dependence.
///
const Instruction *getDst() const { return Dst; }
Instruction *getDst() const { return Dst; }
/// isInput - Returns true if this is an input dependence.
///
@ -158,14 +168,14 @@ namespace llvm {
///
void dump(raw_ostream &OS) const;
private:
const Instruction *Src, *Dst;
Instruction *Src, *Dst;
friend class DependenceAnalysis;
};
/// FullDependence - This class represents a dependence between two memory
/// references in a function. It contains detailed information about the
/// dependence (direction vectors, etc) and is used when the compiler is
/// dependence (direction vectors, etc.) and is used when the compiler is
/// able to accurately analyze the interaction of the references; that is,
/// it is not a confused dependence (see Dependence). In most cases
/// (for output, flow, and anti dependences), the dependence implies an
@ -173,12 +183,12 @@ namespace llvm {
/// input dependences are unordered.
class FullDependence : public Dependence {
public:
FullDependence(const Instruction *Src,
const Instruction *Dst,
FullDependence(Instruction *Src,
Instruction *Dst,
bool LoopIndependent,
unsigned Levels);
~FullDependence() {
delete DV;
delete[] DV;
}
/// isLoopIndependent - Returns true if this is a loop-independent
@ -234,8 +244,8 @@ namespace llvm {
/// DependenceAnalysis - This class is the main dependence-analysis driver.
///
class DependenceAnalysis : public FunctionPass {
void operator=(const DependenceAnalysis &); // do not implement
DependenceAnalysis(const DependenceAnalysis &); // do not implement
void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
public:
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
@ -243,11 +253,11 @@ namespace llvm {
/// The flag PossiblyLoopIndependent should be set by the caller
/// if it appears that control flow can reach from Src to Dst
/// without traversing a loop back edge.
Dependence *depends(const Instruction *Src,
const Instruction *Dst,
Dependence *depends(Instruction *Src,
Instruction *Dst,
bool PossiblyLoopIndependent);
/// getSplitIteration - Give a dependence that's splitable at some
/// getSplitIteration - Give a dependence that's splittable at some
/// particular level, return the iteration that should be used to split
/// the loop.
///

View File

@ -10,8 +10,8 @@
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#include "llvm/Analysis/Dominators.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/Dominators.h"
//===----------------------------------------------------------------------===//
//

View File

@ -15,13 +15,13 @@
#ifndef LLVM_ANALYSIS_DOMINATORS_H
#define LLVM_ANALYSIS_DOMINATORS_H
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
@ -101,18 +101,18 @@ class DomTreeNodeBase {
Children.clear();
}
bool compare(DomTreeNodeBase<NodeT> *Other) {
bool compare(const DomTreeNodeBase<NodeT> *Other) const {
if (getNumChildren() != Other->getNumChildren())
return true;
SmallPtrSet<NodeT *, 4> OtherChildren;
for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
NodeT *Nd = (*I)->getBlock();
SmallPtrSet<const NodeT *, 4> OtherChildren;
for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
const NodeT *Nd = (*I)->getBlock();
OtherChildren.insert(Nd);
}
for (iterator I = begin(), E = end(); I != E; ++I) {
NodeT *N = (*I)->getBlock();
for (const_iterator I = begin(), E = end(); I != E; ++I) {
const NodeT *N = (*I)->getBlock();
if (OtherChildren.count(N) == 0)
return true;
}
@ -663,8 +663,7 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
// Initialize the roots list
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
E = TraitsTy::nodes_end(&F); I != E; ++I) {
if (std::distance(TraitsTy::child_begin(I),
TraitsTy::child_end(I)) == 0)
if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
addRoot(I);
// Prepopulate maps so that we don't get iterator invalidation issues later.

View File

@ -24,7 +24,6 @@ namespace llvm {
class DominatorTree;
class Instruction;
class Value;
class IVUsers;
class ScalarEvolution;
class SCEV;
class IVUsers;

View File

@ -14,122 +14,130 @@
#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H
#include "llvm/Function.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include <cassert>
#include <climits>
#include <vector>
namespace llvm {
class CallSite;
class DataLayout;
class Function;
class TargetTransformInfo;
class CallSite;
class DataLayout;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
const int InstrCost = 5;
const int IndirectCallThreshold = 100;
const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
}
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
const int InstrCost = 5;
const int IndirectCallThreshold = 100;
const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
/// \brief Represents the cost of inlining a function.
///
/// This supports special values for functions which should "always" or
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
/// smaller values increase the likelihood of the function being inlined.
///
/// Objects of this type also provide the adjusted threshold for inlining
/// based on the information available for a particular callsite. They can be
/// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric.
class InlineCost {
enum SentinelValues {
AlwaysInlineCost = INT_MIN,
NeverInlineCost = INT_MAX
};
/// \brief The estimated cost of inlining this callsite.
const int Cost;
/// \brief The adjusted threshold against which this cost was computed.
const int Threshold;
// Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {}
public:
static InlineCost get(int Cost, int Threshold) {
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
return InlineCost(Cost, Threshold);
}
static InlineCost getAlways() {
return InlineCost(AlwaysInlineCost, 0);
}
static InlineCost getNever() {
return InlineCost(NeverInlineCost, 0);
}
/// \brief Represents the cost of inlining a function.
/// \brief Test whether the inline cost is low enough for inlining.
operator bool() const {
return Cost < Threshold;
}
bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isNever() const { return Cost == NeverInlineCost; }
bool isVariable() const { return !isAlways() && !isNever(); }
/// \brief Get the inline cost estimate.
/// It is an error to call this on an "always" or "never" InlineCost.
int getCost() const {
assert(isVariable() && "Invalid access of InlineCost");
return Cost;
}
/// \brief Get the cost delta from the threshold for inlining.
/// Only valid if the cost is of the variable kind. Returns a negative
/// value if the cost is too high to inline.
int getCostDelta() const { return Threshold - getCost(); }
};
/// \brief Cost analyzer used by inliner.
class InlineCostAnalysis : public CallGraphSCCPass {
const DataLayout *TD;
const TargetTransformInfo *TTI;
public:
static char ID;
InlineCostAnalysis();
~InlineCostAnalysis();
// Pass interface implementation.
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnSCC(CallGraphSCC &SCC);
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
///
/// This supports special values for functions which should "always" or
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
/// smaller values increase the likelihood of the function being inlined.
/// Note that threshold is passed into this function. Only costs below the
/// threshold are computed with any accuracy. The threshold can be used to
/// bound the computation necessary to determine whether the cost is
/// sufficiently low to warrant inlining.
///
/// Objects of this type also provide the adjusted threshold for inlining
/// based on the information available for a particular callsite. They can be
/// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric.
class InlineCost {
enum SentinelValues {
AlwaysInlineCost = INT_MIN,
NeverInlineCost = INT_MAX
};
/// Also note that calling this function *dynamically* computes the cost of
/// inlining the callsite. It is an expensive, heavyweight call.
InlineCost getInlineCost(CallSite CS, int Threshold);
/// \brief The estimated cost of inlining this callsite.
const int Cost;
/// \brief Get an InlineCost with the callee explicitly specified.
/// This allows you to calculate the cost of inlining a function via a
/// pointer. This behaves exactly as the version with no explicit callee
/// parameter in all other respects.
//
// Note: This is used by out-of-tree passes, please do not remove without
// adding a replacement API.
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
/// \brief The adjusted threshold against which this cost was computed.
const int Threshold;
/// \brief Minimal filter to detect invalid constructs for inlining.
bool isInlineViable(Function &Callee);
};
// Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, int Threshold)
: Cost(Cost), Threshold(Threshold) {}
public:
static InlineCost get(int Cost, int Threshold) {
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
return InlineCost(Cost, Threshold);
}
static InlineCost getAlways() {
return InlineCost(AlwaysInlineCost, 0);
}
static InlineCost getNever() {
return InlineCost(NeverInlineCost, 0);
}
/// \brief Test whether the inline cost is low enough for inlining.
operator bool() const {
return Cost < Threshold;
}
bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isNever() const { return Cost == NeverInlineCost; }
bool isVariable() const { return !isAlways() && !isNever(); }
/// \brief Get the inline cost estimate.
/// It is an error to call this on an "always" or "never" InlineCost.
int getCost() const {
assert(isVariable() && "Invalid access of InlineCost");
return Cost;
}
/// \brief Get the cost delta from the threshold for inlining.
/// Only valid if the cost is of the variable kind. Returns a negative
/// value if the cost is too high to inline.
int getCostDelta() const { return Threshold - getCost(); }
};
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
// DataLayout if available, or null.
const DataLayout *TD;
public:
InlineCostAnalyzer(): TD(0) {}
void setDataLayout(const DataLayout *TData) { TD = TData; }
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
///
/// Note that threshold is passed into this function. Only costs below the
/// threshold are computed with any accuracy. The threshold can be used to
/// bound the computation necessary to determine whether the cost is
/// sufficiently low to warrant inlining.
InlineCost getInlineCost(CallSite CS, int Threshold);
/// getCalledFunction - The heuristic used to determine if we should inline
/// the function call or not. The callee is explicitly specified, to allow
/// you to calculate the cost of inlining a function via a pointer. This
/// behaves exactly as the version with no explicit callee parameter in all
/// other respects.
//
// Note: This is used by out-of-tree passes, please do not remove without
// adding a replacement API.
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
};
}
#endif

View File

@ -14,17 +14,33 @@
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
// then it dominates the original instruction.
//
// These routines implicitly resolve undef uses. The easiest way to be safe when
// using these routines to obtain simplified values for existing instructions is
// to always replace all uses of the instructions with the resulting simplified
// values. This will prevent other code from seeing the same undef uses and
// resolving them to different values.
//
// These routines are designed to tolerate moderately incomplete IR, such as
// instructions that are not connected to basic blocks yet. However, they do
// require that all the IR that they encounter be valid. In particular, they
// require that all non-constant values be defined in the same function, and the
// same call context of that function (and not split between caller and callee
// contexts of a directly recursive call, for example).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#include "llvm/IR/User.h"
namespace llvm {
template<typename T>
class ArrayRef;
class DominatorTree;
class Instruction;
class DataLayout;
class FastMathFlags;
class TargetLibraryInfo;
class Type;
class Value;
@ -43,6 +59,28 @@ namespace llvm {
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FAdd, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FSub, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FMul, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFMulInst(Value *LHS, Value *RHS,
FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
@ -57,7 +95,7 @@ namespace llvm {
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -69,7 +107,7 @@ namespace llvm {
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -88,7 +126,7 @@ namespace llvm {
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -127,14 +165,14 @@ namespace llvm {
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -178,10 +216,28 @@ namespace llvm {
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Given a function and iterators over arguments, see if we can fold
/// the result.
///
/// If this call could not be simplified returns null.
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
User::op_iterator ArgEnd, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Given a function and set of arguments, see if we can fold the
/// result.
///
/// If this call could not be simplified returns null.
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,

View File

@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INTERVAL_H
#define LLVM_INTERVAL_H
#ifndef LLVM_ANALYSIS_INTERVAL_H
#define LLVM_ANALYSIS_INTERVAL_H
#include "llvm/ADT/GraphTraits.h"
#include <vector>

View File

@ -30,11 +30,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INTERVAL_ITERATOR_H
#define LLVM_INTERVAL_ITERATOR_H
#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
#define LLVM_ANALYSIS_INTERVALITERATOR_H
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/Function.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <set>
@ -157,7 +157,7 @@ class IntervalIterator {
private:
// ProcessInterval - This method is used during the construction of the
// interval graph. It walks through the source graph, recursively creating
// an interval per invokation until the entire graph is covered. This uses
// an interval per invocation until the entire graph is covered. This uses
// the ProcessNode method to add all of the nodes to the interval.
//
// This method is templated because it may operate on two different source

View File

@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INTERVAL_PARTITION_H
#define LLVM_INTERVAL_PARTITION_H
#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
#define LLVM_ANALYSIS_INTERVALPARTITION_H
#include "llvm/Analysis/Interval.h"
#include "llvm/Pass.h"

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LIBCALL_AA_H
#define LLVM_ANALYSIS_LIBCALL_AA_H
#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Pass.h"

View File

@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_LOADS_H
#define LLVM_ANALYSIS_LOADS_H
#include "llvm/BasicBlock.h"
#include "llvm/IR/BasicBlock.h"
namespace llvm {

View File

@ -27,21 +27,16 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_INFO_H
#define LLVM_ANALYSIS_LOOP_INFO_H
#ifndef LLVM_ANALYSIS_LOOPINFO_H
#define LLVM_ANALYSIS_LOOPINFO_H
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Pass.h"
#include <algorithm>
#include <map>
namespace llvm {
@ -56,6 +51,7 @@ class DominatorTree;
class LoopInfo;
class Loop;
class PHINode;
class raw_ostream;
template<class N, class M> class LoopInfoBase;
template<class N, class M> class LoopBase;
@ -151,10 +147,10 @@ class LoopBase {
/// block that is outside of the current loop.
///
bool isLoopExiting(const BlockT *BB) const {
typedef GraphTraits<BlockT*> BlockTraits;
typedef GraphTraits<const BlockT*> BlockTraits;
for (typename BlockTraits::ChildIteratorType SI =
BlockTraits::child_begin(const_cast<BlockT*>(BB)),
SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++SI) {
BlockTraits::child_begin(BB),
SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
if (!contains(*SI))
return true;
}
@ -169,8 +165,8 @@ class LoopBase {
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType I =
InvBlockTraits::child_begin(const_cast<BlockT*>(H)),
E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I)
InvBlockTraits::child_begin(H),
E = InvBlockTraits::child_end(H); I != E; ++I)
if (contains(*I))
++NumBackEdges;
@ -381,6 +377,20 @@ class Loop : public LoopBase<BasicBlock, Loop> {
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
bool isSafeToClone() const;
/// Returns true if the loop is annotated parallel.
///
/// A parallel loop can be assumed to not contain any dependencies between
/// iterations by the compiler. That is, any loop-carried dependency checking
/// can be skipped completely when parallelizing the loop on the target
/// machine. Thus, if the parallel loop information originates from the
/// programmer, e.g. via the OpenMP parallel for pragma, it is the
/// programmer's responsibility to ensure there are no loop-carried
/// dependencies. The final execution order of the instructions across
/// iterations is not guaranteed, thus, the end result might or might not
/// implement actual concurrent execution of instructions across multiple
/// iterations.
bool isAnnotatedParallel() const;
/// hasDedicatedExits - Return true if no exit block for the loop
/// has a predecessor that is outside the loop.
bool hasDedicatedExits() const;

View File

@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
#define LLVM_ANALYSIS_LOOPINFOIMPL_H
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm {

View File

@ -21,10 +21,9 @@
// reachable from the loop header.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
#define LLVM_ANALYSIS_LOOP_ITERATOR_H
#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
#define LLVM_ANALYSIS_LOOPITERATOR_H
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Analysis/LoopInfo.h"

View File

@ -12,13 +12,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LOOP_PASS_H
#define LLVM_LOOP_PASS_H
#ifndef LLVM_ANALYSIS_LOOPPASS_H
#define LLVM_ANALYSIS_LOOPPASS_H
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
#include "llvm/Function.h"
#include <deque>
namespace llvm {
@ -39,6 +38,9 @@ class LoopPass : public Pass {
// whatever action is necessary for the specified Loop.
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
// Initialization and finalization hooks.
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
return false;

View File

@ -15,12 +15,12 @@
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
#define LLVM_ANALYSIS_MEMORYBUILTINS_H
#include "llvm/IRBuilder.h"
#include "llvm/Operator.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
#include "llvm/InstVisitor.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
@ -138,12 +138,22 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
//
/// \brief Compute the size of the object pointed by Ptr. Returns true and the
/// object size in Size if successful, and false otherwise.
/// object size in Size if successful, and false otherwise. In this context, by
/// object we mean the region of memory starting at Ptr to the end of the
/// underlying object pointed to by Ptr.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
/// \brief Compute the size of the underlying object pointed by Ptr. Returns
/// true and the object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
const DataLayout *TD, const TargetLibraryInfo *TLI,
bool RoundToAlign = false);
typedef std::pair<APInt, APInt> SizeOffsetType;
@ -153,12 +163,14 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
typedef DenseMap<const Value*, SizeOffsetType> CacheMapTy;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
SmallPtrSet<Instruction *, 8> SeenInsts;
CacheMapTy CacheMap;
APInt align(APInt Size, uint64_t Align);
@ -191,6 +203,7 @@ class ObjectSizeOffsetVisitor
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
SizeOffsetType visitLoadInst(LoadInst &I);

View File

@ -11,17 +11,17 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Support/ValueHandle.h"
namespace llvm {
class Function;
@ -34,14 +34,14 @@ namespace llvm {
class PredIteratorCache;
class DominatorTree;
class PHITransAddr;
/// MemDepResult - A memory dependence query can return one of three different
/// answers, described below.
class MemDepResult {
enum DepType {
/// Invalid - Clients of MemDep never see this.
Invalid = 0,
/// Clobber - This is a dependence on the specified instruction which
/// clobbers the desired value. The pointer member of the MemDepResult
/// pair holds the instruction that clobbers the memory. For example,
@ -72,7 +72,7 @@ namespace llvm {
/// and no intervening clobbers. No validation is done that the
/// operands to the calls are the same.
Def,
/// Other - This marker indicates that the query has no known dependency
/// in the specified block. More detailed state info is encoded in the
/// upper part of the pair (i.e. the Instruction*)
@ -99,7 +99,7 @@ namespace llvm {
explicit MemDepResult(PairTy V) : Value(V) {}
public:
MemDepResult() : Value(0, Invalid) {}
/// get methods: These are static ctor methods for creating various
/// MemDepResult kinds.
static MemDepResult getDef(Instruction *Inst) {
@ -130,7 +130,7 @@ namespace llvm {
/// isDef - Return true if this MemDepResult represents a query that is
/// an instruction definition dependency.
bool isDef() const { return Value.getInt() == Def; }
/// isNonLocal - Return true if this MemDepResult represents a query that
/// is transparent to the start of the block, but where a non-local hasn't
/// been done.
@ -145,7 +145,7 @@ namespace llvm {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
}
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const {
@ -159,7 +159,7 @@ namespace llvm {
if (Value.getInt() == Other) return NULL;
return Value.getPointer();
}
bool operator==(const MemDepResult &M) const { return Value == M.Value; }
bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
bool operator<(const MemDepResult &M) const { return Value < M.Value; }
@ -175,11 +175,11 @@ namespace llvm {
/// In a default-constructed MemDepResult object, the type will be Dirty
/// and the instruction pointer will be null.
///
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
/// state.
bool isDirty() const { return Value.getInt() == Invalid; }
static MemDepResult getDirty(Instruction *Inst) {
return MemDepResult(PairTy(Inst, Invalid));
}
@ -199,16 +199,16 @@ namespace llvm {
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return BB; }
void setResult(const MemDepResult &R) { Result = R; }
const MemDepResult &getResult() const { return Result; }
bool operator<(const NonLocalDepEntry &RHS) const {
return BB < RHS.BB;
}
};
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
/// (potentially phi translated) address that was live in the block.
@ -218,17 +218,17 @@ namespace llvm {
public:
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
: Entry(bb, result), Address(address) {}
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return Entry.getBB(); }
void setResult(const MemDepResult &R, Value *Addr) {
Entry.setResult(R);
Address = Addr;
}
const MemDepResult &getResult() const { return Entry.getResult(); }
/// getAddress - Return the address of this pointer in this block. This can
/// be different than the address queried for the non-local result because
/// of phi translation. This returns null if the address was not available
@ -238,7 +238,7 @@ namespace llvm {
/// The address is always null for a non-local 'call' dependence.
Value *getAddress() const { return Address; }
};
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
/// given memory operation, what preceding memory operations it depends on.
/// It builds on alias analysis information, and tries to provide a lazy,
@ -297,30 +297,30 @@ namespace llvm {
CachedNonLocalPointerInfo NonLocalPointerDeps;
// A map from instructions to their non-local pointer dependencies.
typedef DenseMap<Instruction*,
typedef DenseMap<Instruction*,
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
/// PerInstNLInfo - This is the instruction we keep for each cached access
/// that we have for an instruction. The pointer is an owning pointer and
/// the bool indicates whether we have any dirty bits in the set.
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
// A map from instructions to their non-local dependencies.
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
NonLocalDepMapType NonLocalDeps;
// A reverse mapping from dependencies to the dependees. This is
// used when removing instructions to keep the cache coherent.
typedef DenseMap<Instruction*,
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
ReverseDepMapType ReverseLocalDeps;
// A reverse mapping from dependencies to the non-local dependees.
ReverseDepMapType ReverseNonLocalDeps;
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
DataLayout *TD;
@ -333,15 +333,15 @@ namespace llvm {
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
bool runOnFunction(Function &);
/// Clean up memory in between runs
void releaseMemory();
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
/// and Alias Analysis.
///
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// getDependency - Return the instruction on which a memory operation
/// depends. See the class comment for more details. It is illegal to call
/// this on non-memory instructions.
@ -360,8 +360,8 @@ namespace llvm {
/// removed. Clients must copy this data if they want it around longer than
/// that.
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
/// getNonLocalPointerDependency - Perform a full dependency query for an
/// access to the specified (non-volatile) memory location, returning the
/// set of instructions that either define or clobber the value.
@ -374,7 +374,7 @@ namespace llvm {
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
/// invalidateCachedPointerInfo - This method is used to invalidate cached
/// information about the specified pointer, because it may be too
/// conservative in memdep. This is an optional call that can be used when
@ -387,20 +387,23 @@ namespace llvm {
/// This needs to be done when the CFG changes, e.g., due to splitting
/// critical edges.
void invalidateCachedPredecessors();
/// getPointerDependencyFrom - Return the instruction on which a memory
/// location depends. If isLoad is true, this routine ignores may-aliases
/// with read-only operations. If isLoad is false, this routine ignores
/// may-aliases with reads from read-only locations.
/// may-aliases with reads from read-only locations. If possible, pass
/// the query instruction as well; this function may take advantage of
/// the metadata annotated to the query instruction to refine the result.
///
/// Note that this is an uncached query, and thus may be inefficient.
///
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
bool isLoad,
bool isLoad,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
BasicBlock *BB,
Instruction *QueryInst = 0);
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
/// looks at a memory location for a load (specified by MemLocBase, Offs,
/// and Size) and compares it against a load. If the specified load could
@ -413,7 +416,7 @@ namespace llvm {
unsigned MemLocSize,
const LoadInst *LI,
const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt,
@ -430,11 +433,11 @@ namespace llvm {
unsigned NumSortedEntries);
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;
};
} // End llvm namespace

View File

@ -14,8 +14,8 @@
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
#define LLVM_ANALYSIS_PHITRANSADDR_H
#include "llvm/Instruction.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Instruction.h"
namespace llvm {
class DominatorTree;

View File

@ -198,9 +198,6 @@ namespace llvm {
// analyze.
FunctionPass *createInstCountPass();
// print debug info intrinsics in human readable form
FunctionPass *createDbgInfoPrinterPass();
//===--------------------------------------------------------------------===//
//
// createRegionInfoPass - This pass finds all single entry single exit regions

View File

@ -23,14 +23,14 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PATH_NUMBERING_H
#define LLVM_PATH_NUMBERING_H
#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
#define LLVM_ANALYSIS_PATHNUMBERING_H
#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/ProfileInfoTypes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Analysis/ProfileInfoTypes.h"
#include <map>
#include <stack>
#include <vector>

View File

@ -11,11 +11,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PATHPROFILEINFO_H
#define LLVM_PATHPROFILEINFO_H
#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
#define LLVM_ANALYSIS_PATHPROFILEINFO_H
#include "llvm/BasicBlock.h"
#include "llvm/Analysis/PathNumbering.h"
#include "llvm/IR/BasicBlock.h"
namespace llvm {

View File

@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
#define LLVM_ANALYSIS_POST_DOMINATORS_H
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
#define LLVM_ANALYSIS_POSTDOMINATORS_H
#include "llvm/Analysis/Dominators.h"

View File

@ -16,6 +16,7 @@
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"

View File

@ -26,9 +26,9 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <string>
#include <map>
#include <set>
#include <string>
namespace llvm {
class Pass;

View File

@ -16,9 +16,9 @@
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
#include <vector>
#include <string>
#include <utility>
#include <vector>
namespace llvm {

View 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

View File

@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGION_INFO_H
#define LLVM_ANALYSIS_REGION_INFO_H
#ifndef LLVM_ANALYSIS_REGIONINFO_H
#define LLVM_ANALYSIS_REGIONINFO_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/DominanceFrontier.h"

View File

@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
#define LLVM_ANALYSIS_REGION_ITERATOR_H
#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
#define LLVM_ANALYSIS_REGIONITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"

View File

@ -13,15 +13,13 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_REGION_PASS_H
#define LLVM_REGION_PASS_H
#ifndef LLVM_ANALYSIS_REGIONPASS_H
#define LLVM_ANALYSIS_REGIONPASS_H
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
#include "llvm/Function.h"
#include <deque>
namespace llvm {
@ -59,6 +57,9 @@ class RegionPass : public Pass {
/// @return The pass to print the LLVM IR in the region.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
virtual bool doFinalization() { return false; }
//@}

View File

@ -21,16 +21,16 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/Operator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
@ -338,6 +338,10 @@ namespace llvm {
/// getMax - Get the max backedge taken count for the loop.
const SCEV *getMax(ScalarEvolution *SE) const;
/// Return true if any backedge taken count expressions refer to the given
/// subexpression.
bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
/// clear - Invalidate this result and free associated memory.
void clear();
};
@ -831,7 +835,7 @@ namespace llvm {
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
/// predicate Pred. Return true iff any changes were made. If the
/// operands are provably equal or inequal, LHS and RHS are set to
/// operands are provably equal or unequal, LHS and RHS are set to
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
///
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,

View File

@ -11,18 +11,18 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#include "llvm/IRBuilder.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
#include <set>
namespace llvm {
class TargetLowering;
class TargetTransformInfo;
/// Return true if the given expression is safe to expand in the sense that
/// all materialized values are safe to speculate.
@ -40,8 +40,10 @@ namespace llvm {
// New instructions receive a name to identifies them with the current pass.
const char* IVName;
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
// InsertedExpressions caches Values for reuse, so must track RAUW.
std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
InsertedExpressions;
// InsertedValues only flags inserted instructions so needs no RAUW.
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
@ -129,7 +131,7 @@ namespace llvm {
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
const TargetLowering *TLI = NULL);
const TargetTransformInfo *TTI = NULL);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the

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