Upgrade our copy of llvm/clang to trunk r154661, in preparation of the

upcoming 3.1 release (expected in a few weeks).  Preliminary release
notes can be found at: <http://llvm.org/docs/ReleaseNotes.html>

MFC after:	2 weeks
This commit is contained in:
Dimitry Andric 2012-04-16 21:23:25 +00:00
commit dff0c46c97
2267 changed files with 249615 additions and 121903 deletions

View file

@ -38,6 +38,22 @@
# xargs -n1 | sort | uniq -d;
# done
# 20120415: new clang import which bumps version from 3.0 to 3.1
OLD_FILES+=usr/include/clang/3.0/altivec.h
OLD_FILES+=usr/include/clang/3.0/avxintrin.h
OLD_FILES+=usr/include/clang/3.0/emmintrin.h
OLD_FILES+=usr/include/clang/3.0/immintrin.h
OLD_FILES+=usr/include/clang/3.0/mm3dnow.h
OLD_FILES+=usr/include/clang/3.0/mm_malloc.h
OLD_FILES+=usr/include/clang/3.0/mmintrin.h
OLD_FILES+=usr/include/clang/3.0/nmmintrin.h
OLD_FILES+=usr/include/clang/3.0/pmmintrin.h
OLD_FILES+=usr/include/clang/3.0/smmintrin.h
OLD_FILES+=usr/include/clang/3.0/tmmintrin.h
OLD_FILES+=usr/include/clang/3.0/wmmintrin.h
OLD_FILES+=usr/include/clang/3.0/x86intrin.h
OLD_FILES+=usr/include/clang/3.0/xmmintrin.h
OLD_DIRS+=usr/include/clang/3.0
# 20120322: Update heimdal to 1.5.1.
OLD_FILES+=usr/include/krb5-v4compat.h \
usr/include/krb_err.h \

View file

@ -4,7 +4,7 @@ LLVM Release License
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
@ -67,3 +67,4 @@ Autoconf llvm/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}

View file

@ -25,6 +25,12 @@
extern "C" {
#endif
/**
* @defgroup LLVMCAnalysis Analysis
* @ingroup LLVMC
*
* @{
*/
typedef enum {
LLVMAbortProcessAction, /* verifier will print to stderr and abort() */
@ -48,6 +54,10 @@ LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
void LLVMViewFunctionCFG(LLVMValueRef Fn);
void LLVMViewFunctionCFGOnly(LLVMValueRef Fn);
/**
* @}
*/
#ifdef __cplusplus
}
#endif

View file

@ -25,6 +25,12 @@
extern "C" {
#endif
/**
* @defgroup LLVMCBitReader Bit Reader
* @ingroup LLVMC
*
* @{
*/
/* Builds a module from the bitcode in the specified memory buffer, returning a
reference to the module via the OutModule parameter. Returns 0 on success.
@ -59,6 +65,10 @@ LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
LLVMModuleProviderRef *OutMP,
char **OutMessage);
/**
* @}
*/
#ifdef __cplusplus
}
#endif

View file

@ -25,6 +25,12 @@
extern "C" {
#endif
/**
* @defgroup LLVMCBitWriter Bit Writer
* @ingroup LLVMC
*
* @{
*/
/*===-- Operations on modules ---------------------------------------------===*/
@ -39,6 +45,10 @@ int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
descriptor. Returns 0 on success. Closes the Handle. */
int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
/**
* @}
*/
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,13 @@
#include "llvm/Support/DataTypes.h"
#include <stddef.h>
/**
* @defgroup LLVMCDisassembler Disassembler
* @ingroup LLVMC
*
* @{
*/
/**
* An opaque reference to a disassembler context.
*/
@ -157,6 +164,10 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DC, uint8_t *Bytes,
uint64_t BytesSize, uint64_t PC,
char *OutString, size_t OutStringSize);
/**
* @}
*/
#ifdef __cplusplus
}
#endif /* !defined(__cplusplus) */

View file

@ -25,6 +25,19 @@
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.
@ -504,6 +517,10 @@ int EDBlockEvaluateOperand(uint64_t *result,
int EDBlockVisitTokens(EDInstRef inst,
EDTokenVisitor_t visitor);
/**
* @}
*/
#endif
#ifdef __cplusplus

View file

@ -26,6 +26,13 @@
extern "C" {
#endif
/**
* @defgroup LLVMCExecutionEngine Execution Engine
* @ingroup LLVMC
*
* @{
*/
void LLVMLinkInJIT(void);
void LLVMLinkInInterpreter(void);
@ -125,6 +132,10 @@ void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global);
/**
* @}
*/
#ifdef __cplusplus
}

View file

@ -22,9 +22,19 @@
extern "C" {
#endif
/**
* @defgroup LLVMCInitialization Initialization Routines
* @ingroup LLVMC
*
* This module contains routines used to initialize the LLVM system.
*
* @{
*/
void LLVMInitializeCore(LLVMPassRegistryRef R);
void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
void LLVMInitializeVectorization(LLVMPassRegistryRef R);
void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
void LLVMInitializeIPO(LLVMPassRegistryRef R);
void LLVMInitializeInstrumentation(LLVMPassRegistryRef R);
@ -33,6 +43,10 @@ void LLVMInitializeIPA(LLVMPassRegistryRef R);
void LLVMInitializeCodeGen(LLVMPassRegistryRef R);
void LLVMInitializeTarget(LLVMPassRegistryRef R);
/**
* @}
*/
#ifdef __cplusplus
}
#endif

View file

@ -20,6 +20,13 @@
extern "C" {
#endif
/**
* @defgroup LLVMCLinkTimeOptimizer Link Time Optimization
* @ingroup LLVMC
*
* @{
*/
/// This provides a dummy type for pointers to the LTO object.
typedef void* llvm_lto_t;
@ -51,6 +58,10 @@ extern "C" {
extern llvm_lto_status_t llvm_optimize_modules
(llvm_lto_t lto, const char* output_filename);
/**
* @}
*/
#ifdef __cplusplus
}
#endif

View file

@ -28,23 +28,74 @@
extern "C" {
#endif
/**
* @defgroup LLVMCObject Object file reading and writing
* @ingroup LLVMC
*
* @{
*/
// Opaque type wrappers
typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef;
typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef;
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf);
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
// ObjectFile Section iterators
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
LLVMSectionIteratorRef SI);
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
LLVMSymbolIteratorRef Sym);
// ObjectFile Symbol iterators
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile);
void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI);
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
LLVMSymbolIteratorRef SI);
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI);
// SectionRef accessors
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI);
LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
LLVMSymbolIteratorRef Sym);
// Section Relocation iterators
LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section);
void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef RI);
LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
LLVMRelocationIteratorRef RI);
void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef RI);
// SymbolRef accessors
const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI);
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI);
uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI);
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI);
// RelocationRef accessors
uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI);
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI);
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI);
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI);
// NOTE: Caller takes ownership of returned string of the two
// following functions.
const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI);
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI);
/**
* @}
*/
#ifdef __cplusplus
}
@ -68,6 +119,27 @@ namespace llvm {
return reinterpret_cast<LLVMSectionIteratorRef>
(const_cast<section_iterator*>(SI));
}
inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
return reinterpret_cast<symbol_iterator*>(SI);
}
inline LLVMSymbolIteratorRef
wrap(const symbol_iterator *SI) {
return reinterpret_cast<LLVMSymbolIteratorRef>
(const_cast<symbol_iterator*>(SI));
}
inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
return reinterpret_cast<relocation_iterator*>(SI);
}
inline LLVMRelocationIteratorRef
wrap(const relocation_iterator *SI) {
return reinterpret_cast<LLVMRelocationIteratorRef>
(const_cast<relocation_iterator*>(SI));
}
}
}

View file

@ -26,6 +26,13 @@
extern "C" {
#endif
/**
* @defgroup LLVMCTarget Target information
* @ingroup LLVMC
*
* @{
*/
enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
@ -47,6 +54,24 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef;
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
/* Declare all of the available assembly printer initialization functions. */
#define LLVM_ASM_PRINTER(TargetName) \
void LLVMInitialize##TargetName##AsmPrinter();
#include "llvm/Config/AsmPrinters.def"
#undef LLVM_ASM_PRINTER /* Explicit undef to make SWIG happier */
/* Declare all of the available assembly parser initialization functions. */
#define LLVM_ASM_PARSER(TargetName) \
void LLVMInitialize##TargetName##AsmParser();
#include "llvm/Config/AsmParsers.def"
#undef LLVM_ASM_PARSER /* Explicit undef to make SWIG happier */
/* Declare all of the available disassembler initialization functions. */
#define LLVM_DISASSEMBLER(TargetName) \
void LLVMInitialize##TargetName##Disassembler();
#include "llvm/Config/Disassemblers.def"
#undef LLVM_DISASSEMBLER /* Explicit undef to make SWIG happier */
/** LLVMInitializeAllTargetInfos - The main program should call this function if
it wants access to all available targets that LLVM is configured to
support. */
@ -64,6 +89,43 @@ static inline void LLVMInitializeAllTargets(void) {
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
}
/** LLVMInitializeAllTargetMCs - The main program should call this function if
it wants access to all available target MC that LLVM is configured to
support. */
static inline void LLVMInitializeAllTargetMCs(void) {
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
}
/** LLVMInitializeAllAsmPrinters - The main program should call this function if
it wants all asm printers that LLVM is configured to support, to make them
available via the TargetRegistry. */
static inline void LLVMInitializeAllAsmPrinters() {
#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
#include "llvm/Config/AsmPrinters.def"
#undef LLVM_ASM_PRINTER /* Explicit undef to make SWIG happier */
}
/** LLVMInitializeAllAsmParsers - The main program should call this function if
it wants all asm parsers that LLVM is configured to support, to make them
available via the TargetRegistry. */
static inline void LLVMInitializeAllAsmParsers() {
#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
#include "llvm/Config/AsmParsers.def"
#undef LLVM_ASM_PARSER /* Explicit undef to make SWIG happier */
}
/** LLVMInitializeAllDisassemblers - The main program should call this function
if it wants all disassemblers that LLVM is configured to support, to make
them available via the TargetRegistry. */
static inline void LLVMInitializeAllDisassemblers() {
#define LLVM_DISASSEMBLER(TargetName) \
LLVMInitialize##TargetName##Disassembler();
#include "llvm/Config/Disassemblers.def"
#undef LLVM_DISASSEMBLER /* Explicit undef to make SWIG happier */
}
/** LLVMInitializeNativeTarget - The main program should call this function to
initialize the native target corresponding to the host. This is useful
@ -157,6 +219,9 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
See the destructor llvm::TargetData::~TargetData. */
void LLVMDisposeTargetData(LLVMTargetDataRef);
/**
* @}
*/
#ifdef __cplusplus
}

View file

@ -0,0 +1,142 @@
/*===-- llvm-c/TargetMachine.h - Target Machine Library 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 the Target and TargetMachine *|
|* classes, which can be used to generate assembly or object files. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_TARGETMACHINE_H
#define LLVM_C_TARGETMACHINE_H
#include "llvm-c/Core.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct LLVMTargetMachine *LLVMTargetMachineRef;
typedef struct LLVMTarget *LLVMTargetRef;
typedef enum {
LLVMCodeGenLevelNone,
LLVMCodeGenLevelLess,
LLVMCodeGenLevelDefault,
LLVMCodeGenLevelAggressive
} LLVMCodeGenOptLevel;
typedef enum {
LLVMRelocDefault,
LLVMRelocStatic,
LLVMRelocPIC,
LLVMRelocDynamicNoPic
} LLVMRelocMode;
typedef enum {
LLVMCodeModelDefault,
LLVMCodeModelJITDefault,
LLVMCodeModelSmall,
LLVMCodeModelKernel,
LLVMCodeModelMedium,
LLVMCodeModelLarge
} LLVMCodeModel;
typedef enum {
LLVMAssemblyFile,
LLVMObjectFile
} LLVMCodeGenFileType;
/** Returns the first llvm::Target in the registered targets list. */
LLVMTargetRef LLVMGetFirstTarget();
/** Returns the next llvm::Target given a previous one (or null if there's none) */
LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
/*===-- Target ------------------------------------------------------------===*/
/** Returns the name of a target. See llvm::Target::getName */
const char *LLVMGetTargetName(LLVMTargetRef T);
/** Returns the description of a target. See llvm::Target::getDescription */
const char *LLVMGetTargetDescription(LLVMTargetRef T);
/** Returns if the target has a JIT */
LLVMBool LLVMTargetHasJIT(LLVMTargetRef T);
/** Returns if the target has a TargetMachine associated */
LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T);
/** Returns if the target as an ASM backend (required for emitting output) */
LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T);
/*===-- Target Machine ----------------------------------------------------===*/
/** Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine */
LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char *Triple,
char *CPU, char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
LLVMCodeModel CodeModel);
/** Dispose the LLVMTargetMachineRef instance generated by
LLVMCreateTargetMachine. */
void LLVMDisposeTargetMachine(LLVMTargetMachineRef T);
/** Returns the Target used in a TargetMachine */
LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T);
/** Returns the triple used creating this target machine. See
llvm::TargetMachine::getTriple. The result needs to be disposed with
LLVMDisposeMessage. */
char *LLVMGetTargetMachineTriple(LLVMTargetMachineRef T);
/** Returns the cpu used creating this target machine. See
llvm::TargetMachine::getCPU. The result needs to be disposed with
LLVMDisposeMessage. */
char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
/** Returns the feature string used creating this target machine. See
llvm::TargetMachine::getFeatureString. The result needs to be disposed with
LLVMDisposeMessage. */
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
/** Emits an asm or object file for the given module to the filename. This
wraps several c++ only classes (among them a file stream). Returns any
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
#ifdef __cplusplus
}
namespace llvm {
class TargetMachine;
class Target;
inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
return reinterpret_cast<TargetMachine*>(P);
}
inline Target *unwrap(LLVMTargetRef P) {
return reinterpret_cast<Target*>(P);
}
inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
return reinterpret_cast<LLVMTargetMachineRef>(
const_cast<TargetMachine*>(P));
}
inline LLVMTargetRef wrap(const Target * P) {
return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
}
}
#endif
#endif

View file

@ -21,6 +21,13 @@
extern "C" {
#endif
/**
* @defgroup LLVMCTransformsIPO Interprocedural transformations
* @ingroup LLVMCTransforms
*
* @{
*/
/** See llvm::createArgumentPromotionPass function. */
void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM);
@ -63,6 +70,10 @@ void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM);
/** See llvm::createStripSymbolsPass function. */
void LLVMAddStripSymbolsPass(LLVMPassManagerRef PM);
/**
* @}
*/
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */

View file

@ -23,6 +23,13 @@ typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef;
extern "C" {
#endif
/**
* @defgroup LLVMCTransformsPassManagerBuilder Pass manager builder
* @ingroup LLVMCTransforms
*
* @{
*/
/** See llvm::PassManagerBuilder. */
LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void);
void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB);
@ -73,6 +80,10 @@ void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
bool Internalize,
bool RunInliner);
/**
* @}
*/
#ifdef __cplusplus
}

View file

@ -25,6 +25,13 @@
extern "C" {
#endif
/**
* @defgroup LLVMCTransformsScalar Scalar transformations
* @ingroup LLVMCTransforms
*
* @{
*/
/** See llvm::createAggressiveDCEPass function. */
void LLVMAddAggressiveDCEPass(LLVMPassManagerRef PM);
@ -116,6 +123,9 @@ void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
/** See llvm::createBasicAliasAnalysisPass function */
void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
/**
* @}
*/
#ifdef __cplusplus
}

View file

@ -0,0 +1,48 @@
/*===---------------------------Vectorize.h --------------------- -*- C -*-===*\
|*===----------- Vectorization Transformation Library C Interface ---------===*|
|* *|
|* 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 libLLVMVectorize.a, which *|
|* implements various vectorization transformations of the LLVM IR. *|
|* *|
|* Many exotic languages can interoperate with C code but have a harder time *|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|* tools written in such languages. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_TRANSFORMS_VECTORIZE_H
#define LLVM_C_TRANSFORMS_VECTORIZE_H
#include "llvm-c/Core.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup LLVMCTransformsVectorize Vectorization transformations
* @ingroup LLVMCTransforms
*
* @{
*/
/** See llvm::createBBVectorizePass function. */
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
/**
* @}
*/
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif

View file

@ -20,24 +20,31 @@
#include <stddef.h>
#include <unistd.h>
/**
* @defgroup LLVMCLTO LTO
* @ingroup LLVMC
*
* @{
*/
#define LTO_API_VERSION 4
typedef enum {
LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */
LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0,
LTO_SYMBOL_PERMISSIONS_CODE = 0x000000A0,
LTO_SYMBOL_PERMISSIONS_DATA = 0x000000C0,
LTO_SYMBOL_PERMISSIONS_RODATA = 0x00000080,
LTO_SYMBOL_DEFINITION_MASK = 0x00000700,
LTO_SYMBOL_DEFINITION_REGULAR = 0x00000100,
LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200,
LTO_SYMBOL_DEFINITION_WEAK = 0x00000300,
LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400,
LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0,
LTO_SYMBOL_PERMISSIONS_CODE = 0x000000A0,
LTO_SYMBOL_PERMISSIONS_DATA = 0x000000C0,
LTO_SYMBOL_PERMISSIONS_RODATA = 0x00000080,
LTO_SYMBOL_DEFINITION_MASK = 0x00000700,
LTO_SYMBOL_DEFINITION_REGULAR = 0x00000100,
LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200,
LTO_SYMBOL_DEFINITION_WEAK = 0x00000300,
LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400,
LTO_SYMBOL_DEFINITION_WEAKUNDEF = 0x00000500,
LTO_SYMBOL_SCOPE_MASK = 0x00003800,
LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800,
LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000,
LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
LTO_SYMBOL_SCOPE_MASK = 0x00003800,
LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800,
LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000,
LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800,
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800
} lto_symbol_attributes;
@ -88,7 +95,7 @@ lto_module_is_object_file(const char* path);
* Checks if a file is a loadable object compiled for requested target.
*/
extern bool
lto_module_is_object_file_for_target(const char* path,
lto_module_is_object_file_for_target(const char* path,
const char* target_triple_prefix);
@ -103,7 +110,7 @@ lto_module_is_object_file_in_memory(const void* mem, size_t length);
* Checks if a buffer is a loadable object compiled for requested target.
*/
extern bool
lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
const char* target_triple_prefix);
@ -243,6 +250,12 @@ extern void
lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
int nargs);
/**
* Enables the internalize pass during LTO optimizations.
*/
extern void
lto_codegen_set_whole_program_optimization(lto_code_gen_t cg);
/**
* Adds to a list of all global symbols that must exist in the final
* generated code. If a function is not listed, it might be
@ -251,7 +264,6 @@ lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
extern void
lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
/**
* Writes a new object file at the specified path that contains the
* merged contents of all modules added so far.
@ -260,11 +272,10 @@ lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
extern bool
lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
/**
* Generates code for all added modules into one native object file.
* On success returns a pointer to a generated mach-o/ELF buffer and
* length set to the buffer size. The buffer is owned by the
* length set to the buffer size. The buffer is owned by the
* lto_code_gen_t and will be freed when lto_codegen_dispose()
* is called, or lto_codegen_compile() is called again.
* On failure, returns NULL (check lto_get_error_message() for details).
@ -285,9 +296,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 *);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif

View file

@ -320,6 +320,7 @@ namespace llvm {
const fltSemantics &getSemantics() const { return *semantics; }
bool isZero() const { return category == fcZero; }
bool isNonZero() const { return category != fcZero; }
bool isNormal() const { return category == fcNormal; }
bool isNaN() const { return category == fcNaN; }
bool isInfinity() const { return category == fcInfinity; }
bool isNegative() const { return sign; }
@ -328,8 +329,16 @@ namespace llvm {
APFloat& operator=(const APFloat &);
/* Return an arbitrary integer value usable for hashing. */
uint32_t getHashValue() const;
/// \brief Overload to compute a hash code for an APFloat value.
///
/// Note that the use of hash codes for floating point values is in general
/// frought with peril. Equality is hard to define for these values. For
/// example, should negative and positive zero hash to different codes? Are
/// they equal or not? This hash value implementation specifically
/// emphasizes producing different codes for different inputs in order to
/// be used in canonicalization and memoization. As such, equality is
/// bitwiseIsEqual, and 0 != -0.
friend hash_code hash_value(const APFloat &Arg);
/// Converts this value into a decimal string.
///

View file

@ -23,11 +23,12 @@
#include <string>
namespace llvm {
class Serializer;
class Deserializer;
class FoldingSetNodeID;
class raw_ostream;
class Serializer;
class StringRef;
class hash_code;
class raw_ostream;
template<typename T>
class SmallVectorImpl;
@ -497,15 +498,13 @@ public:
if (loBitsSet == APINT_BITS_PER_WORD)
return APInt(numBits, -1ULL);
// For small values, return quickly.
if (numBits < APINT_BITS_PER_WORD)
return APInt(numBits, (1ULL << loBitsSet) - 1);
if (loBitsSet <= APINT_BITS_PER_WORD)
return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet));
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
/// The hash value is computed as the sum of the words and the bit width.
/// @returns A hash value computed from the sum of the APInt words.
/// @brief Get a hash value based on this APInt
uint64_t getHashValue() const;
/// \brief Overload to compute a hash_code for an APInt value.
friend hash_code hash_value(const APInt &Arg);
/// This function returns a pointer to the internal storage of the APInt.
/// This is useful for writing out the APInt in binary form without any
@ -562,7 +561,15 @@ public:
/// Performs logical negation operation on this APInt.
/// @returns true if *this is zero, false otherwise.
/// @brief Logical negation operator.
bool operator!() const;
bool operator!() const {
if (isSingleWord())
return !VAL;
for (unsigned i = 0; i != getNumWords(); ++i)
if (pVal[i])
return false;
return true;
}
/// @}
/// @name Assignment Operators
@ -835,7 +842,11 @@ public:
/// @returns the bit value at bitPosition
/// @brief Array-indexing support.
bool operator[](unsigned bitPosition) const;
bool operator[](unsigned bitPosition) const {
assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
return (maskBit(bitPosition) &
(isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) != 0;
}
/// @}
/// @name Comparison Operators
@ -1056,6 +1067,16 @@ public:
/// @brief Zero extend or truncate to width
APInt zextOrTrunc(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is sign
/// extended, or left alone to make it that width.
/// @brief Sign extend or truncate to width
APInt sextOrSelf(unsigned width) const;
/// Make this APInt have the bit width given by \p width. The value is zero
/// extended, or left alone to make it that width.
/// @brief Zero extend or truncate to width
APInt zextOrSelf(unsigned width) const;
/// @}
/// @name Bit Manipulation Operators
/// @{

View file

@ -14,8 +14,7 @@
#include <vector>
namespace llvm {
class APInt;
/// ArrayRef - Represent a constant reference to an array (0 or more elements
/// consecutively in memory), i.e. a start pointer and a length. It allows
/// various APIs to take consecutive elements easily and conveniently.
@ -33,33 +32,33 @@ namespace llvm {
typedef const T *iterator;
typedef const T *const_iterator;
typedef size_t size_type;
private:
/// The start of the array, in an external buffer.
const T *Data;
/// The number of elements.
size_type Length;
public:
/// @name Constructors
/// @{
/// Construct an empty ArrayRef.
/*implicit*/ ArrayRef() : Data(0), Length(0) {}
/// Construct an ArrayRef from a single element.
/*implicit*/ ArrayRef(const T &OneElt)
: Data(&OneElt), Length(1) {}
/// Construct an ArrayRef from a pointer and length.
/*implicit*/ ArrayRef(const T *data, size_t length)
: Data(data), Length(length) {}
/// Construct an ArrayRef from a range.
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector.
/*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
@ -67,39 +66,39 @@ namespace llvm {
/// Construct an ArrayRef from a std::vector.
/*implicit*/ ArrayRef(const std::vector<T> &Vec)
: Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
/// Construct an ArrayRef from a C array.
template <size_t N>
/*implicit*/ ArrayRef(const T (&Arr)[N])
: Data(Arr), Length(N) {}
/// @}
/// @name Simple Operations
/// @{
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
/// empty - Check if the array is empty.
bool empty() const { return Length == 0; }
const T *data() const { return Data; }
/// size - Get the array size.
size_t size() const { return Length; }
/// front - Get the first element.
const T &front() const {
assert(!empty());
return Data[0];
}
/// back - Get the last element.
const T &back() const {
assert(!empty());
return Data[Length-1];
}
/// equals - Check for element-wise equality.
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
@ -111,18 +110,18 @@ namespace llvm {
}
/// slice(n) - Chop off the first N elements of the array.
ArrayRef<T> slice(unsigned N) {
ArrayRef<T> slice(unsigned N) const {
assert(N <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, size()-N);
}
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
ArrayRef<T> slice(unsigned N, unsigned M) {
ArrayRef<T> slice(unsigned N, unsigned M) const {
assert(N+M <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, M);
}
/// @}
/// @name Operator Overloads
/// @{
@ -130,22 +129,104 @@ namespace llvm {
assert(Index < Length && "Invalid index!");
return Data[Index];
}
/// @}
/// @name Expensive Operations
/// @{
std::vector<T> vec() const {
return std::vector<T>(Data, Data+Length);
}
/// @}
/// @name Conversion operators
/// @{
operator std::vector<T>() const {
return std::vector<T>(Data, Data+Length);
}
/// @}
};
/// MutableArrayRef - Represent a mutable reference to an array (0 or more
/// elements consecutively in memory), i.e. a start pointer and a length. It
/// allows various APIs to take and modify consecutive elements easily and
/// conveniently.
///
/// This class does not own the underlying data, it is expected to be used in
/// situations where the data resides in some other buffer, whose lifetime
/// extends past that of the MutableArrayRef. For this reason, it is not in
/// general safe to store a MutableArrayRef.
///
/// This is intended to be trivially copyable, so it should be passed by
/// value.
template<typename T>
class MutableArrayRef : public ArrayRef<T> {
public:
typedef T *iterator;
/// 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());
return data()[this->size()-1];
}
/// slice(n) - Chop off the first N elements of the array.
MutableArrayRef<T> slice(unsigned N) const {
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
/// @{
T &operator[](size_t Index) const {
assert(Index < this->size() && "Invalid index!");
return data()[Index];
}
};
/// @name ArrayRef Convenience constructors
@ -215,5 +296,5 @@ namespace llvm {
static const bool value = true;
};
}
#endif

View file

@ -14,12 +14,12 @@
#ifndef LLVM_ADT_BITVECTOR_H
#define LLVM_ADT_BITVECTOR_H
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <cstring>
namespace llvm {
@ -116,7 +116,7 @@ public:
else if (sizeof(BitWord) == 8)
NumBits += CountPopulation_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
return NumBits;
}
@ -146,10 +146,9 @@ public:
if (Bits[i] != 0) {
if (sizeof(BitWord) == 4)
return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return -1;
}
@ -170,10 +169,9 @@ public:
if (Copy != 0) {
if (sizeof(BitWord) == 4)
return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
// Check subsequent words.
@ -181,10 +179,9 @@ public:
if (Bits[i] != 0) {
if (sizeof(BitWord) == 4)
return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return -1;
}
@ -318,6 +315,16 @@ public:
return *this;
}
// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
BitVector &reset(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
unsigned i;
for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
Bits[i] &= ~RHS.Bits[i];
return *this;
}
BitVector &operator|=(const BitVector &RHS) {
if (size() < RHS.size())
resize(RHS.size());
@ -365,6 +372,42 @@ public:
std::swap(Capacity, RHS.Capacity);
}
//===--------------------------------------------------------------------===//
// Portable bit mask operations.
//===--------------------------------------------------------------------===//
//
// These methods all operate on arrays of uint32_t, each holding 32 bits. The
// fixed word size makes it easier to work with literal bit vector constants
// in portable code.
//
// The LSB in each word is the lowest numbered bit. The size of a portable
// bit mask is always a whole multiple of 32 bits. If no bit mask size is
// given, the bit mask is assumed to cover the entire BitVector.
/// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
/// This computes "*this |= Mask".
void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
applyMask<true, false>(Mask, MaskWords);
}
/// clearBitsInMask - Clear any bits in this vector that are set in Mask.
/// Don't resize. This computes "*this &= ~Mask".
void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
applyMask<false, false>(Mask, MaskWords);
}
/// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
/// Don't resize. This computes "*this |= ~Mask".
void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
applyMask<true, true>(Mask, MaskWords);
}
/// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
/// Don't resize. This computes "*this &= Mask".
void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
applyMask<false, true>(Mask, MaskWords);
}
private:
unsigned NumBitWords(unsigned S) const {
return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
@ -400,6 +443,33 @@ private:
void init_words(BitWord *B, unsigned NumWords, bool t) {
memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
}
template<bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size.");
MaskWords = std::min(MaskWords, (size() + 31) / 32);
const unsigned Scale = BITWORD_SIZE / 32;
unsigned i;
for (i = 0; MaskWords >= Scale; ++i, MaskWords -= Scale) {
BitWord BW = Bits[i];
// This inner loop should unroll completely when BITWORD_SIZE > 32.
for (unsigned b = 0; b != BITWORD_SIZE; b += 32) {
uint32_t M = *Mask++;
if (InvertMask) M = ~M;
if (AddBits) BW |= BitWord(M) << b;
else BW &= ~(BitWord(M) << b);
}
Bits[i] = BW;
}
for (unsigned b = 0; MaskWords; b += 32, --MaskWords) {
uint32_t M = *Mask++;
if (InvertMask) M = ~M;
if (AddBits) Bits[i] |= BitWord(M) << b;
else Bits[i] &= ~(BitWord(M) << b);
}
if (AddBits)
clear_unused_bits();
}
};
inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {

View file

@ -36,6 +36,7 @@ namespace llvm {
/// for more information on the properties which the predicate function itself
/// should satisfy.
class DAGDeltaAlgorithm {
virtual void anchor();
public:
typedef unsigned change_ty;
typedef std::pair<change_ty, change_ty> edge_ty;

View file

@ -30,12 +30,11 @@ namespace llvm {
template<typename KeyT, typename ValueT,
typename KeyInfoT = DenseMapInfo<KeyT>,
typename ValueInfoT = DenseMapInfo<ValueT>, bool IsConst = false>
bool IsConst = false>
class DenseMapIterator;
template<typename KeyT, typename ValueT,
typename KeyInfoT = DenseMapInfo<KeyT>,
typename ValueInfoT = DenseMapInfo<ValueT> >
typename KeyInfoT = DenseMapInfo<KeyT> >
class DenseMap {
typedef std::pair<KeyT, ValueT> BucketT;
unsigned NumBuckets;
@ -80,19 +79,19 @@ public:
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
typedef DenseMapIterator<KeyT, ValueT,
KeyInfoT, ValueInfoT, true> const_iterator;
KeyInfoT, true> const_iterator;
inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
}
inline iterator end() {
return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
return iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
}
inline const_iterator begin() const {
return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
}
inline const_iterator end() const {
return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
}
bool empty() const { return NumEntries == 0; }
@ -137,13 +136,33 @@ public:
iterator find(const KeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return iterator(TheBucket, Buckets+NumBuckets);
return iterator(TheBucket, Buckets+NumBuckets, true);
return end();
}
const_iterator find(const KeyT &Val) const {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return const_iterator(TheBucket, Buckets+NumBuckets);
return const_iterator(TheBucket, Buckets+NumBuckets, true);
return end();
}
/// Alternate version of find() which allows a different, and possibly
/// less expensive, key type.
/// The DenseMapInfo is responsible for supplying methods
/// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
/// type used.
template<class LookupKeyT>
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return iterator(TheBucket, Buckets+NumBuckets, true);
return end();
}
template<class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
return const_iterator(TheBucket, Buckets+NumBuckets, true);
return end();
}
@ -162,13 +181,12 @@ public:
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
BucketT *TheBucket;
if (LookupBucketFor(KV.first, TheBucket))
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
true);
return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true), true);
}
/// insert - Range insertion of pairs.
@ -237,7 +255,7 @@ public:
private:
void CopyFrom(const DenseMap& other) {
if (NumBuckets != 0 &&
(!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) {
(!isPodLike<KeyT>::value || !isPodLike<ValueT>::value)) {
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
@ -266,7 +284,7 @@ private:
Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value)
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
else
for (size_t i = 0; i < NumBuckets; ++i) {
@ -310,6 +328,10 @@ private:
static unsigned getHashValue(const KeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
template<typename LookupKeyT>
static unsigned getHashValue(const LookupKeyT &Val) {
return KeyInfoT::getHashValue(Val);
}
static const KeyT getEmptyKey() {
return KeyInfoT::getEmptyKey();
}
@ -321,7 +343,8 @@ private:
/// FoundBucket. If the bucket contains the key and a value, this returns
/// true, otherwise it returns a bucket with an empty marker or tombstone and
/// returns false.
bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
template<typename LookupKeyT>
bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) const {
unsigned BucketNo = getHashValue(Val);
unsigned ProbeAmt = 1;
BucketT *BucketsPtr = Buckets;
@ -342,7 +365,7 @@ private:
while (1) {
BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
// Found Val's bucket? If so, return it.
if (KeyInfoT::isEqual(ThisBucket->first, Val)) {
if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
FoundBucket = ThisBucket;
return true;
}
@ -478,12 +501,12 @@ public:
};
template<typename KeyT, typename ValueT,
typename KeyInfoT, typename ValueInfoT, bool IsConst>
typename KeyInfoT, bool IsConst>
class DenseMapIterator {
typedef std::pair<KeyT, ValueT> Bucket;
typedef DenseMapIterator<KeyT, ValueT,
KeyInfoT, ValueInfoT, true> ConstIterator;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, ValueInfoT, true>;
KeyInfoT, true> ConstIterator;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
public:
typedef ptrdiff_t difference_type;
typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
@ -495,15 +518,16 @@ private:
public:
DenseMapIterator() : Ptr(0), End(0) {}
DenseMapIterator(pointer Pos, pointer E) : Ptr(Pos), End(E) {
AdvancePastEmptyBuckets();
DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
: Ptr(Pos), End(E) {
if (!NoAdvance) AdvancePastEmptyBuckets();
}
// If IsConst is true this is a converting constructor from iterator to
// const_iterator and the default copy constructor is used.
// Otherwise this is a copy constructor for iterator.
DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
KeyInfoT, ValueInfoT, false>& I)
KeyInfoT, false>& I)
: Ptr(I.Ptr), End(I.End) {}
reference operator*() const {
@ -541,9 +565,9 @@ private:
}
};
template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
template<typename KeyT, typename ValueT, typename KeyInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) {
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
return X.getMemorySize();
}

View file

@ -59,7 +59,7 @@ template<> struct DenseMapInfo<char> {
// Provide DenseMapInfo for unsigned ints.
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getEmptyKey() { return ~0U; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {

View file

@ -193,12 +193,11 @@ protected:
virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
/// NodeEquals - Instantiations of the FoldingSet template implement
/// this function to compare the given node with the given ID.
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID,
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID) const=0;
/// NodeEquals - Instantiations of the FoldingSet template implement
/// ComputeNodeHash - Instantiations of the FoldingSet template implement
/// this function to compute a hash value for the given node.
virtual unsigned ComputeNodeHash(Node *N,
FoldingSetNodeID &TempID) const = 0;
virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
};
//===----------------------------------------------------------------------===//
@ -220,7 +219,7 @@ template<typename T> struct DefaultFoldingSetTrait {
// to compute a temporary ID if necessary. The default implementation
// just calls Profile and does a regular comparison. Implementations
// can override this to provide more efficient implementations.
static inline bool Equals(T &X, const FoldingSetNodeID &ID,
static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID);
// ComputeHash - Compute a hash value for X, using TempID to
@ -249,7 +248,7 @@ struct DefaultContextualFoldingSetTrait {
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
X.Profile(ID, Context);
}
static inline bool Equals(T &X, const FoldingSetNodeID &ID,
static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID, Ctx Context);
static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
Ctx Context);
@ -344,7 +343,7 @@ template<class T> class FoldingSetBucketIterator;
template<typename T>
inline bool
DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) {
unsigned IDHash, FoldingSetNodeID &TempID) {
FoldingSetTrait<T>::Profile(X, TempID);
return TempID == ID;
}
@ -358,6 +357,7 @@ template<typename T, typename Ctx>
inline bool
DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X,
const FoldingSetNodeID &ID,
unsigned IDHash,
FoldingSetNodeID &TempID,
Ctx Context) {
ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
@ -387,15 +387,14 @@ private:
}
/// NodeEquals - Instantiations may optionally provide a way to compare a
/// node with a specified ID.
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID,
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::Equals(*TN, ID, TempID);
return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
}
/// NodeEquals - Instantiations may optionally provide a way to compute a
/// ComputeNodeHash - Instantiations may optionally provide a way to compute a
/// hash value directly from a node.
virtual unsigned ComputeNodeHash(Node *N,
FoldingSetNodeID &TempID) const {
virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
}
@ -465,10 +464,11 @@ private:
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
}
virtual bool NodeEquals(FoldingSetImpl::Node *N,
const FoldingSetNodeID &ID,
const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, TempID, Context);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
Context);
}
virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
FoldingSetNodeID &TempID) const {

View file

@ -43,9 +43,12 @@ struct GraphTraits {
// typedef ...iterator nodes_iterator;
// static nodes_iterator nodes_begin(GraphType *G)
// static nodes_iterator nodes_end (GraphType *G)
//
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
// static unsigned size (GraphType *G)
// Return total number of nodes in the graph
//
// If anyone tries to use this class without having an appropriate
// specialization, make an error. If you get this error, it's because you

View file

@ -0,0 +1,770 @@
//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the newly proposed standard C++ interfaces for hashing
// arbitrary data and building hash functions for user-defined types. This
// interface was originally proposed in N3333[1] and is currently under review
// for inclusion in a future TR and/or standard.
//
// The primary interfaces provide are comprised of one type and three functions:
//
// -- 'hash_code' class is an opaque type representing the hash code for some
// data. It is the intended product of hashing, and can be used to implement
// hash tables, checksumming, and other common uses of hashes. It is not an
// integer type (although it can be converted to one) because it is risky
// to assume much about the internals of a hash_code. In particular, each
// execution of the program has a high probability of producing a different
// hash_code for a given input. Thus their values are not stable to save or
// persist, and should only be used during the execution for the
// construction of hashing datastructures.
//
// -- 'hash_value' is a function designed to be overloaded for each
// user-defined type which wishes to be used within a hashing context. It
// should be overloaded within the user-defined type's namespace and found
// via ADL. Overloads for primitive types are provided by this library.
//
// -- 'hash_combine' and 'hash_combine_range' are functions designed to aid
// programmers in easily and intuitively combining a set of data into
// a single hash_code for their object. They should only logically be used
// within the implementation of a 'hash_value' routine or similar context.
//
// Note that 'hash_combine_range' contains very special logic for hashing
// a contiguous array of integers or pointers. This logic is *extremely* fast,
// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were
// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys
// under 32-bytes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_HASHING_H
#define LLVM_ADT_HASHING_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iterator>
#include <utility>
// Allow detecting C++11 feature availability when building with Clang without
// breaking other compilers.
#ifndef __has_feature
# define __has_feature(x) 0
#endif
namespace llvm {
/// \brief An opaque object representing a hash code.
///
/// This object represents the result of hashing some entity. It is intended to
/// be used to implement hashtables or other hashing-based data structures.
/// While it wraps and exposes a numeric value, this value should not be
/// trusted to be stable or predictable across processes or executions.
///
/// In order to obtain the hash_code for an object 'x':
/// \code
/// using llvm::hash_value;
/// llvm::hash_code code = hash_value(x);
/// \endcode
///
/// Also note that there are two numerical values which are reserved, and the
/// implementation ensures will never be produced for real hash_codes. These
/// can be used as sentinels within hashing data structures.
class hash_code {
size_t value;
public:
/// \brief Default construct a hash_code.
/// Note that this leaves the value uninitialized.
hash_code() {}
/// \brief Form a hash code directly from a numerical value.
hash_code(size_t value) : value(value) {}
/// \brief Convert the hash code to its numerical value for use.
/*explicit*/ operator size_t() const { return value; }
friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
return lhs.value == rhs.value;
}
friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
return lhs.value != rhs.value;
}
/// \brief Allow a hash_code to be directly run through hash_value.
friend size_t hash_value(const hash_code &code) { return code.value; }
};
/// \brief Compute a hash_code for any integer value.
///
/// Note that this function is intended to compute the same hash_code for
/// a particular value without regard to the pre-promotion type. This is in
/// contrast to hash_combine which may produce different hash_codes for
/// differing argument types even if they would implicit promote to a common
/// type without changing the value.
template <typename T>
typename enable_if<is_integral_or_enum<T>, hash_code>::type hash_value(T value);
/// \brief Compute a hash_code for a pointer's address.
///
/// N.B.: This hashes the *address*. Not the value and not the type.
template <typename T> hash_code hash_value(const T *ptr);
/// \brief Compute a hash_code for a pair of objects.
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg);
/// \brief Compute a hash_code for a standard string.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg);
/// \brief Override the execution seed with a fixed value.
///
/// This hashing library uses a per-execution seed designed to change on each
/// run with high probability in order to ensure that the hash codes are not
/// attackable and to ensure that output which is intended to be stable does
/// not rely on the particulars of the hash codes produced.
///
/// That said, there are use cases where it is important to be able to
/// reproduce *exactly* a specific behavior. To that end, we provide a function
/// which will forcibly set the seed to a fixed value. This must be done at the
/// start of the program, before any hashes are computed. Also, it cannot be
/// undone. This makes it thread-hostile and very hard to use outside of
/// immediately on start of a simple program designed for reproducible
/// behavior.
void set_fixed_execution_hash_seed(size_t fixed_value);
// All of the implementation details of actually computing the various hash
// code values are held within this namespace. These routines are included in
// the header file mainly to allow inlining and constant propagation.
namespace hashing {
namespace detail {
inline uint64_t fetch64(const char *p) {
uint64_t result;
memcpy(&result, p, sizeof(result));
if (sys::isBigEndianHost())
return sys::SwapByteOrder(result);
return result;
}
inline uint32_t fetch32(const char *p) {
uint32_t result;
memcpy(&result, p, sizeof(result));
if (sys::isBigEndianHost())
return sys::SwapByteOrder(result);
return result;
}
/// Some primes between 2^63 and 2^64 for various uses.
static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
static const uint64_t k1 = 0xb492b66fbe98f273ULL;
static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
static const uint64_t k3 = 0xc949d7c7509e6557ULL;
/// \brief Bitwise right rotate.
/// Normally this will compile to a single instruction, especially if the
/// shift is a manifest constant.
inline uint64_t rotate(uint64_t val, size_t shift) {
// Avoid shifting by 64: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
}
inline uint64_t shift_mix(uint64_t val) {
return val ^ (val >> 47);
}
inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (low ^ high) * kMul;
a ^= (a >> 47);
uint64_t b = (high ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
uint8_t a = s[0];
uint8_t b = s[len >> 1];
uint8_t c = s[len - 1];
uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
uint32_t z = len + (static_cast<uint32_t>(c) << 2);
return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
}
inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch32(s);
return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
}
inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch64(s);
uint64_t b = fetch64(s + len - 8);
return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
}
inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t a = fetch64(s) * k1;
uint64_t b = fetch64(s + 8);
uint64_t c = fetch64(s + len - 8) * k2;
uint64_t d = fetch64(s + len - 16) * k0;
return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d,
a + rotate(b ^ k3, 20) - c + len + seed);
}
inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
uint64_t z = fetch64(s + 24);
uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
uint64_t b = rotate(a + z, 52);
uint64_t c = rotate(a, 37);
a += fetch64(s + 8);
c += rotate(a, 7);
a += fetch64(s + 16);
uint64_t vf = a + z;
uint64_t vs = b + rotate(a, 31) + c;
a = fetch64(s + 16) + fetch64(s + len - 32);
z = fetch64(s + len - 8);
b = rotate(a + z, 52);
c = rotate(a, 37);
a += fetch64(s + len - 24);
c += rotate(a, 7);
a += fetch64(s + len - 16);
uint64_t wf = a + z;
uint64_t ws = b + rotate(a, 31) + c;
uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
return shift_mix((seed ^ (r * k0)) + vs) * k2;
}
inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
if (length >= 4 && length <= 8)
return hash_4to8_bytes(s, length, seed);
if (length > 8 && length <= 16)
return hash_9to16_bytes(s, length, seed);
if (length > 16 && length <= 32)
return hash_17to32_bytes(s, length, seed);
if (length > 32)
return hash_33to64_bytes(s, length, seed);
if (length != 0)
return hash_1to3_bytes(s, length, seed);
return k2 ^ seed;
}
/// \brief The intermediate state used during hashing.
/// Currently, the algorithm for computing hash codes is based on CityHash and
/// keeps 56 bytes of arbitrary state.
struct hash_state {
uint64_t h0, h1, h2, h3, h4, h5, h6;
uint64_t seed;
/// \brief Create a new hash_state structure and initialize it based on the
/// seed and the first 64-byte chunk.
/// This effectively performs the initial mix.
static hash_state create(const char *s, uint64_t seed) {
hash_state state = {
0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49),
seed * k1, shift_mix(seed), 0, seed };
state.h6 = hash_16_bytes(state.h4, state.h5);
state.mix(s);
return state;
}
/// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a'
/// and 'b', including whatever is already in 'a' and 'b'.
static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
a += fetch64(s);
uint64_t c = fetch64(s + 24);
b = rotate(b + a + c, 21);
uint64_t d = a;
a += fetch64(s + 8) + fetch64(s + 16);
b += rotate(a, 44) + d;
a += c;
}
/// \brief Mix in a 64-byte buffer of data.
/// We mix all 64 bytes even when the chunk length is smaller, but we
/// record the actual length.
void mix(const char *s) {
h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1;
h0 ^= h6;
h1 += h3 + fetch64(s + 40);
h2 = rotate(h2 + h5, 33) * k1;
h3 = h4 * k1;
h4 = h0 + h5;
mix_32_bytes(s, h3, h4);
h5 = h2 + h6;
h6 = h1 + fetch64(s + 16);
mix_32_bytes(s + 32, h5, h6);
std::swap(h2, h0);
}
/// \brief Compute the final 64-bit hash code value based on the current
/// state and the length of bytes hashed.
uint64_t finalize(size_t length) {
return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
}
};
/// \brief A global, fixed seed-override variable.
///
/// This variable can be set using the \see llvm::set_fixed_execution_seed
/// function. See that function for details. Do not, under any circumstances,
/// set or read this variable.
extern size_t fixed_seed_override;
inline size_t get_execution_seed() {
// FIXME: This needs to be a per-execution seed. This is just a placeholder
// implementation. Switching to a per-execution seed is likely to flush out
// instability bugs and so will happen as its own commit.
//
// However, if there is a fixed seed override set the first time this is
// called, return that instead of the per-execution seed.
const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
static size_t seed = fixed_seed_override ? fixed_seed_override
: (size_t)seed_prime;
return seed;
}
/// \brief Trait to indicate whether a type's bits can be hashed directly.
///
/// A type trait which is true if we want to combine values for hashing by
/// reading the underlying data. It is false if values of this type must
/// first be passed to hash_value, and the resulting hash_codes combined.
//
// FIXME: We want to replace is_integral_or_enum and is_pointer here with
// a predicate which asserts that comparing the underlying storage of two
// values of the type for equality is equivalent to comparing the two values
// for equality. For all the platforms we care about, this holds for integers
// and pointers, but there are platforms where it doesn't and we would like to
// support user-defined types which happen to satisfy this property.
template <typename T> struct is_hashable_data
: integral_constant<bool, ((is_integral_or_enum<T>::value ||
is_pointer<T>::value) &&
64 % sizeof(T) == 0)> {};
// Special case std::pair to detect when both types are viable and when there
// is no alignment-derived padding in the pair. This is a bit of a lie because
// std::pair isn't truly POD, but it's close enough in all reasonable
// implementations for our use case of hashing the underlying data.
template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
: integral_constant<bool, (is_hashable_data<T>::value &&
is_hashable_data<U>::value &&
(sizeof(T) + sizeof(U)) ==
sizeof(std::pair<T, U>))> {};
/// \brief Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
template <typename T>
typename enable_if<is_hashable_data<T>, T>::type
get_hashable_data(const T &value) {
return value;
}
/// \brief Helper to get the hashable data representation for a type.
/// This variant is enabled when we must first call hash_value and use the
/// result as our data.
template <typename T>
typename enable_if_c<!is_hashable_data<T>::value, size_t>::type
get_hashable_data(const T &value) {
using ::llvm::hash_value;
return hash_value(value);
}
/// \brief Helper to store data from a value into a buffer and advance the
/// pointer into that buffer.
///
/// This routine first checks whether there is enough space in the provided
/// buffer, and if not immediately returns false. If there is space, it
/// copies the underlying bytes of value into the buffer, advances the
/// buffer_ptr past the copied bytes, and returns true.
template <typename T>
bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
size_t offset = 0) {
size_t store_size = sizeof(value) - offset;
if (buffer_ptr + store_size > buffer_end)
return false;
const char *value_data = reinterpret_cast<const char *>(&value);
memcpy(buffer_ptr, value_data + offset, store_size);
buffer_ptr += store_size;
return true;
}
/// \brief Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is
/// integral. Rather than computing a hash_code for each object and then
/// combining them, this (as an optimization) directly combines the integers.
template <typename InputIteratorT>
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
typedef typename std::iterator_traits<InputIteratorT>::value_type ValueT;
const size_t seed = get_execution_seed();
char buffer[64], *buffer_ptr = buffer;
char *const buffer_end = buffer_ptr + array_lengthof(buffer);
while (first != last && store_and_advance(buffer_ptr, buffer_end,
get_hashable_data(*first)))
++first;
if (first == last)
return hash_short(buffer, buffer_ptr - buffer, seed);
assert(buffer_ptr == buffer_end);
hash_state state = state.create(buffer, seed);
size_t length = 64;
while (first != last) {
// Fill up the buffer. We don't clear it, which re-mixes the last round
// when only a partial 64-byte chunk is left.
buffer_ptr = buffer;
while (first != last && store_and_advance(buffer_ptr, buffer_end,
get_hashable_data(*first)))
++first;
// Rotate the buffer if we did a partial fill in order to simulate doing
// a mix of the last 64-bytes. That is how the algorithm works when we
// have a contiguous byte sequence, and we want to emulate that here.
std::rotate(buffer, buffer_ptr, buffer_end);
// Mix this chunk into the current state.
state.mix(buffer);
length += buffer_ptr - buffer;
};
return state.finalize(length);
}
/// \brief Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is integral
/// and when the input iterator is actually a pointer. Rather than computing
/// a hash_code for each object and then combining them, this (as an
/// optimization) directly combines the integers. Also, because the integers
/// are stored in contiguous memory, this routine avoids copying each value
/// and directly reads from the underlying memory.
template <typename ValueT>
typename enable_if<is_hashable_data<ValueT>, hash_code>::type
hash_combine_range_impl(ValueT *first, ValueT *last) {
const size_t seed = get_execution_seed();
const char *s_begin = reinterpret_cast<const char *>(first);
const char *s_end = reinterpret_cast<const char *>(last);
const size_t length = std::distance(s_begin, s_end);
if (length <= 64)
return hash_short(s_begin, length, seed);
const char *s_aligned_end = s_begin + (length & ~63);
hash_state state = state.create(s_begin, seed);
s_begin += 64;
while (s_begin != s_aligned_end) {
state.mix(s_begin);
s_begin += 64;
}
if (length & 63)
state.mix(s_end - 64);
return state.finalize(length);
}
} // namespace detail
} // namespace hashing
/// \brief Compute a hash_code for a sequence of values.
///
/// This hashes a sequence of values. It produces the same hash_code as
/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
/// and is significantly faster given pointers and types which can be hashed as
/// a sequence of bytes.
template <typename InputIteratorT>
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
return ::llvm::hashing::detail::hash_combine_range_impl(first, last);
}
// Implementation details for hash_combine.
namespace hashing {
namespace detail {
/// \brief Helper class to manage the recursive combining of hash_combine
/// arguments.
///
/// This class exists to manage the state and various calls involved in the
/// recursive combining of arguments used in hash_combine. It is particularly
/// useful at minimizing the code in the recursive calls to ease the pain
/// caused by a lack of variadic functions.
struct hash_combine_recursive_helper {
char buffer[64];
hash_state state;
const size_t seed;
public:
/// \brief Construct a recursive hash combining helper.
///
/// This sets up the state for a recursive hash combine, including getting
/// the seed and buffer setup.
hash_combine_recursive_helper()
: seed(get_execution_seed()) {}
/// \brief Combine one chunk of data into the current in-flight hash.
///
/// This merges one chunk of data into the hash. First it tries to buffer
/// the data. If the buffer is full, it hashes the buffer into its
/// hash_state, empties it, and then merges the new chunk in. This also
/// handles cases where the data straddles the end of the buffer.
template <typename T>
char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
if (!store_and_advance(buffer_ptr, buffer_end, data)) {
// Check for skew which prevents the buffer from being packed, and do
// a partial store into the buffer to fill it. This is only a concern
// with the variadic combine because that formation can have varying
// argument types.
size_t partial_store_size = buffer_end - buffer_ptr;
memcpy(buffer_ptr, &data, partial_store_size);
// If the store fails, our buffer is full and ready to hash. We have to
// either initialize the hash state (on the first full buffer) or mix
// this buffer into the existing hash state. Length tracks the *hashed*
// length, not the buffered length.
if (length == 0) {
state = state.create(buffer, seed);
length = 64;
} else {
// Mix this chunk into the current state and bump length up by 64.
state.mix(buffer);
length += 64;
}
// Reset the buffer_ptr to the head of the buffer for the next chunk of
// data.
buffer_ptr = buffer;
// Try again to store into the buffer -- this cannot fail as we only
// store types smaller than the buffer.
if (!store_and_advance(buffer_ptr, buffer_end, data,
partial_store_size))
abort();
}
return buffer_ptr;
}
#if defined(__has_feature) && __has_feature(__cxx_variadic_templates__)
/// \brief Recursive, variadic combining method.
///
/// This function recurses through each argument, combining that argument
/// into a single hash.
template <typename T, typename ...Ts>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T &arg, const Ts &...args) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
// Recurse to the next argument.
return combine(length, buffer_ptr, buffer_end, args...);
}
#else
// Manually expanded recursive combining methods. See variadic above for
// documentation.
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4, const T5 &arg5, const T6 &arg6) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4, const T5 &arg5) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5);
}
template <typename T1, typename T2, typename T3, typename T4>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4);
}
template <typename T1, typename T2, typename T3>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1, const T2 &arg2, const T3 &arg3) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end, arg2, arg3);
}
template <typename T1, typename T2>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1, const T2 &arg2) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end, arg2);
}
template <typename T1>
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
const T1 &arg1) {
buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
return combine(length, buffer_ptr, buffer_end);
}
#endif
/// \brief Base case for recursive, variadic combining.
///
/// The base case when combining arguments recursively is reached when all
/// arguments have been handled. It flushes the remaining buffer and
/// constructs a hash_code.
hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
// Check whether the entire set of values fit in the buffer. If so, we'll
// use the optimized short hashing routine and skip state entirely.
if (length == 0)
return hash_short(buffer, buffer_ptr - buffer, seed);
// Mix the final buffer, rotating it if we did a partial fill in order to
// simulate doing a mix of the last 64-bytes. That is how the algorithm
// works when we have a contiguous byte sequence, and we want to emulate
// that here.
std::rotate(buffer, buffer_ptr, buffer_end);
// Mix this chunk into the current state.
state.mix(buffer);
length += buffer_ptr - buffer;
return state.finalize(length);
}
};
} // namespace detail
} // namespace hashing
#if __has_feature(__cxx_variadic_templates__)
/// \brief Combine values into a single hash_code.
///
/// This routine accepts a varying number of arguments of any type. It will
/// attempt to combine them into a single hash_code. For user-defined types it
/// attempts to call a \see hash_value overload (via ADL) for the type. For
/// integer and pointer types it directly combines their data into the
/// resulting hash_code.
///
/// The result is suitable for returning from a user's hash_value
/// *implementation* for their user-defined type. Consumers of a type should
/// *not* call this routine, they should instead call 'hash_value'.
template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
// Recursively hash each argument using a helper class.
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
}
#else
// What follows are manually exploded overloads for each argument width. See
// the above variadic definition for documentation and specification.
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4, const T5 &arg5, const T6 &arg6) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64,
arg1, arg2, arg3, arg4, arg5, arg6);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4, const T5 &arg5) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64,
arg1, arg2, arg3, arg4, arg5);
}
template <typename T1, typename T2, typename T3, typename T4>
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
const T4 &arg4) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64,
arg1, arg2, arg3, arg4);
}
template <typename T1, typename T2, typename T3>
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3);
}
template <typename T1, typename T2>
hash_code hash_combine(const T1 &arg1, const T2 &arg2) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2);
}
template <typename T1>
hash_code hash_combine(const T1 &arg1) {
::llvm::hashing::detail::hash_combine_recursive_helper helper;
return helper.combine(0, helper.buffer, helper.buffer + 64, arg1);
}
#endif
// Implementation details for implementatinos of hash_value overloads provided
// here.
namespace hashing {
namespace detail {
/// \brief Helper to hash the value of a single integer.
///
/// Overloads for smaller integer types are not provided to ensure consistent
/// behavior in the presence of integral promotions. Essentially,
/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
inline hash_code hash_integer_value(uint64_t value) {
// Similar to hash_4to8_bytes but using a seed instead of length.
const uint64_t seed = get_execution_seed();
const char *s = reinterpret_cast<const char *>(&value);
const uint64_t a = fetch32(s);
return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
}
} // namespace detail
} // namespace hashing
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
typename enable_if<is_integral_or_enum<T>, hash_code>::type
hash_value(T value) {
return ::llvm::hashing::detail::hash_integer_value(value);
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T> hash_code hash_value(const T *ptr) {
return ::llvm::hashing::detail::hash_integer_value(
reinterpret_cast<uintptr_t>(ptr));
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg) {
return hash_combine(arg.first, arg.second);
}
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg) {
return hash_combine_range(arg.begin(), arg.end());
}
} // namespace llvm
#endif

View file

@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <functional>
#include <vector>
@ -346,7 +347,7 @@ public:
if (prev)
prev->next = next;
else
factory->Cache[computeDigest()] = next;
factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
}
// We need to clear the mutability bit in case we are
@ -428,6 +429,11 @@ protected:
TreeTy* getRight(TreeTy* T) const { return T->getRight(); }
value_type_ref getValue(TreeTy* T) const { return T->value; }
// Make sure the index is not the Tombstone or Entry key of the DenseMap.
static inline unsigned maskCacheIndex(unsigned I) {
return (I & ~0x02);
}
unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
unsigned hl = getHeight(L);
unsigned hr = getHeight(R);
@ -610,7 +616,7 @@ public:
// Search the hashtable for another tree with the same digest, and
// if find a collision compare those trees by their contents.
unsigned digest = TNew->computeDigest();
TreeTy *&entry = Cache[digest];
TreeTy *&entry = Cache[maskCacheIndex(digest)];
do {
if (!entry)
break;
@ -686,7 +692,7 @@ public:
stack.back() |= VisitedRight;
break;
default:
assert(false && "Unreachable.");
llvm_unreachable("Unreachable.");
}
}
@ -722,7 +728,7 @@ public:
skipToParent();
break;
default:
assert(false && "Unreachable.");
llvm_unreachable("Unreachable.");
}
return *this;
}
@ -747,7 +753,7 @@ public:
stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
break;
default:
assert(false && "Unreachable.");
llvm_unreachable("Unreachable.");
}
return *this;
}

View file

@ -739,7 +739,7 @@ public:
// A Path is used by iterators to represent a position in a B+-tree, and the
// path to get there from the root.
//
// The Path class also constains the tree navigation code that doesn't have to
// The Path class also contains the tree navigation code that doesn't have to
// be templatized.
//
//===----------------------------------------------------------------------===//
@ -1977,7 +1977,7 @@ iterator::overflow(unsigned Level) {
CurSize[Nodes] = CurSize[NewNode];
Node[Nodes] = Node[NewNode];
CurSize[NewNode] = 0;
Node[NewNode] = this->map->newNode<NodeT>();
Node[NewNode] = this->map->template newNode<NodeT>();
++Nodes;
}

View file

@ -46,6 +46,7 @@ namespace llvm {
public:
RefCountedBase() : ref_cnt(0) {}
RefCountedBase(const RefCountedBase &) : ref_cnt(0) {}
void Retain() const { ++ref_cnt; }
void Release() const {
@ -64,9 +65,12 @@ namespace llvm {
//===----------------------------------------------------------------------===//
class RefCountedBaseVPTR {
mutable unsigned ref_cnt;
virtual void anchor();
protected:
RefCountedBaseVPTR() : ref_cnt(0) {}
RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
virtual ~RefCountedBaseVPTR() {}
void Retain() const { ++ref_cnt; }
@ -76,9 +80,15 @@ namespace llvm {
}
template <typename T>
friend class IntrusiveRefCntPtr;
friend struct IntrusiveRefCntPtrInfo;
};
template <typename T> struct IntrusiveRefCntPtrInfo {
static void retain(T *obj) { obj->Retain(); }
static void release(T *obj) { obj->Release(); }
};
//===----------------------------------------------------------------------===//
/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
/// that assumes the wrapped object has a reference count associated
@ -105,7 +115,7 @@ namespace llvm {
explicit IntrusiveRefCntPtr() : Obj(0) {}
explicit IntrusiveRefCntPtr(T* obj) : Obj(obj) {
IntrusiveRefCntPtr(T* obj) : Obj(obj) {
retain();
}
@ -153,14 +163,19 @@ namespace llvm {
other.Obj = Obj;
Obj = tmp;
}
void reset() {
release();
Obj = 0;
}
void resetWithoutRelease() {
Obj = 0;
}
private:
void retain() { if (Obj) Obj->Retain(); }
void release() { if (Obj) Obj->Release(); }
void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
void replace(T* S) {
this_type(S).swap(*this);

View file

@ -92,10 +92,14 @@ public:
}
PointerTy const *getAddrOfPointer() const {
return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
}
PointerTy *getAddrOfPointer() {
assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
"Can only return the address if IntBits is cleared and "
"PtrTraits doesn't change the pointer");
return reinterpret_cast<PointerTy const *>(&Value);
return reinterpret_cast<PointerTy *>(&Value);
}
void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }

View file

@ -142,16 +142,19 @@ namespace llvm {
return T();
}
/// \brief If the union is set to the first pointer type we can get an
/// address pointing to it.
template <typename T>
PT1 const *getAddrOf() const {
/// \brief If the union is set to the first pointer type get an address
/// pointing to it.
PT1 const *getAddrOfPtr1() const {
return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
}
/// \brief If the union is set to the first pointer type get an address
/// pointing to it.
PT1 *getAddrOfPtr1() {
assert(is<PT1>() && "Val is not the first pointer");
assert(get<PT1>() == Val.getPointer() &&
"Can't get the address because PointerLikeTypeTraits changes the ptr");
T const *can_only_get_address_of_first_pointer_type
= reinterpret_cast<PT1 const *>(Val.getAddrOfPointer());
return can_only_get_address_of_first_pointer_type;
return (PT1 *)Val.getAddrOfPointer();
}
/// Assignment operators - Allow assigning into this union from either
@ -263,7 +266,7 @@ namespace llvm {
::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
>::Return Ty;
return Ty(Val).is<T>();
return Ty(Val).template is<T>();
}
/// get<T>() - Return the value of the specified pointer type. If the
@ -276,7 +279,7 @@ namespace llvm {
::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
>::Return Ty;
return Ty(Val).get<T>();
return Ty(Val).template get<T>();
}
/// dyn_cast<T>() - If the current value is of the specified pointer type,

View file

@ -144,6 +144,12 @@ public:
set_.erase(back());
vector_.pop_back();
}
T pop_back_val() {
T Ret = back();
pop_back();
return Ret;
}
bool operator==(const SetVector &that) const {
return vector_ == that.vector_;

View file

@ -175,7 +175,7 @@ public:
return CountPopulation_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
return CountPopulation_64(Bits);
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return getPointer()->count();
}
@ -212,7 +212,7 @@ public:
return CountTrailingZeros_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
return CountTrailingZeros_64(Bits);
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return getPointer()->find_first();
}
@ -230,7 +230,7 @@ public:
return CountTrailingZeros_32(Bits);
if (sizeof(uintptr_t) * CHAR_BIT == 64)
return CountTrailingZeros_64(Bits);
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return getPointer()->find_next(Prev);
}

View file

@ -137,6 +137,10 @@ private:
void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.
void swap(SmallPtrSetImpl &RHS);
void CopyFrom(const SmallPtrSetImpl &RHS);
};
@ -287,8 +291,20 @@ public:
return *this;
}
/// swap - Swaps the elements of two sets.
void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
SmallPtrSetImpl::swap(RHS);
}
};
}
namespace std {
/// Implement std::swap in terms of SmallPtrSet swap.
template<class T, unsigned N>
inline void swap(llvm::SmallPtrSet<T, N> &LHS, llvm::SmallPtrSet<T, N> &RHS) {
LHS.swap(RHS);
}
}
#endif

View file

@ -27,13 +27,13 @@ namespace llvm {
///
/// Note that this set does not provide a way to iterate over members in the
/// set.
template <typename T, unsigned N>
template <typename T, unsigned N, typename C = std::less<T> >
class SmallSet {
/// Use a SmallVector to hold the elements here (even though it will never
/// reach its 'large' stage) to avoid calling the default ctors of elements
/// we will never use.
SmallVector<T, N> Vector;
std::set<T> Set;
std::set<T, C> Set;
typedef typename SmallVector<T, N>::const_iterator VIterator;
typedef typename SmallVector<T, N>::iterator mutable_iterator;
public:

View file

@ -24,21 +24,244 @@ namespace llvm {
template<unsigned InternalLen>
class SmallString : public SmallVector<char, InternalLen> {
public:
// Default ctor - Initialize to empty.
/// Default ctor - Initialize to empty.
SmallString() {}
// Initialize from a StringRef.
/// Initialize from a StringRef.
SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
// Initialize with a range.
/// Initialize with a range.
template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
// Copy ctor.
/// Copy ctor.
SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
// Note that in order to add new overloads for append & assign, we have to
// duplicate the inherited versions so as not to inadvertently hide them.
/// @}
/// @name String Assignment
/// @{
/// Assign from a repeated element
void assign(unsigned NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
/// Assign from an iterator pair
template<typename in_iter>
void assign(in_iter S, in_iter E) {
this->clear();
SmallVectorImpl<char>::append(S, E);
}
/// Assign from a StringRef
void assign(StringRef RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Assign from a SmallVector
void assign(const SmallVectorImpl<char> &RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// @}
/// @name String Concatenation
/// @{
/// Append from an iterator pair
template<typename in_iter>
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
}
/// Append from a StringRef
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Append from a SmallVector
void append(const SmallVectorImpl<char> &RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// @}
/// @name String Comparison
/// @{
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
/// equals_lower - Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \arg RHS.
int compare(StringRef RHS) const {
return str().compare(RHS);
}
/// compare_lower - Compare two strings, ignoring case.
int compare_lower(StringRef RHS) const {
return str().compare_lower(RHS);
}
/// compare_numeric - Compare two strings, treating sequences of digits as
/// numbers.
int compare_numeric(StringRef RHS) const {
return str().compare_numeric(RHS);
}
/// @}
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \arg Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
/// endswith - Check if this string ends with the given \arg Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
/// @}
/// @name String Searching
/// @{
/// find - Search for the first character \arg C in the string.
///
/// \return - The index of the first occurrence of \arg C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
return str().find(C, From);
}
/// find - Search for the first string \arg Str in the string.
///
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
return str().find(Str, From);
}
/// rfind - Search for the last character \arg C in the string.
///
/// \return - The index of the last occurrence of \arg C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
return str().rfind(C, From);
}
/// rfind - Search for the last string \arg Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
return str().rfind(Str);
}
/// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find.
size_t find_first_of(char C, size_t From = 0) const {
return str().find_first_of(C, From);
}
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// \arg C or npos if not found.
size_t find_first_not_of(char C, size_t From = 0) const {
return str().find_first_not_of(C, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
/// find_last_of - Find the last character in the string that is \arg C, or
/// npos if not found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
return str().find_last_of(C, From);
}
/// find_last_of - Find the last character in the string that is in \arg C,
/// or npos if not found.
///
/// Note: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
return str().find_last_of(Chars, From);
}
/// @}
/// @name Helpful Algorithms
/// @{
/// count - Return the number of occurrences of \arg C in the string.
size_t count(char C) const {
return str().count(C);
}
/// count - Return the number of non-overlapped occurrences of \arg Str in
/// the string.
size_t count(StringRef Str) const {
return str().count(Str);
}
/// @}
/// @name Substring Operations
/// @{
/// substr - Return a reference to the substring from [Start, Start + N).
///
/// \param Start - The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N - The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \arg Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
return str().substr(Start, N);
}
/// slice - Return a reference to the substring from [Start, End).
///
/// \param Start - The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End - The index following the last character to include in the
/// substring. If this is npos, or less than \arg Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \arg Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
/// Explicit conversion to StringRef
StringRef str() const { return StringRef(this->begin(), this->size()); }
// TODO: Make this const, if it's safe...
@ -48,7 +271,7 @@ public:
return this->data();
}
// Implicit conversion to StringRef.
/// Implicit conversion to StringRef.
operator StringRef() const { return str(); }
// Extra operators.

View file

@ -23,30 +23,6 @@
#include <iterator>
#include <memory>
#ifdef _MSC_VER
namespace std {
#if _MSC_VER <= 1310
// Work around flawed VC++ implementation of std::uninitialized_copy. Define
// additional overloads so that elements with pointer types are recognized as
// scalars and not objects, causing bizarre type conversion errors.
template<class T1, class T2>
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
_Scalar_ptr_iterator_tag _Cat;
return _Cat;
}
template<class T1, class T2>
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
_Scalar_ptr_iterator_tag _Cat;
return _Cat;
}
#else
// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
// is that the above hack won't work if it wasn't fixed.
#endif
}
#endif
namespace llvm {
/// SmallVectorBase - This is all the non-templated stuff common to all
@ -100,10 +76,10 @@ public:
template <typename T>
class SmallVectorTemplateCommon : public SmallVectorBase {
protected:
void setEnd(T *P) { this->EndX = P; }
public:
SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
void setEnd(T *P) { this->EndX = P; }
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
@ -174,7 +150,7 @@ public:
/// implementations that are designed to work with non-POD-like T's.
template <typename T, bool isPodLike>
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
public:
protected:
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
static void destroy_range(T *S, T *E) {
@ -194,6 +170,23 @@ public:
/// grow - double the size of the allocated memory, guaranteeing space for at
/// least one more element or MinSize if specified.
void grow(size_t MinSize = 0);
public:
void push_back(const T &Elt) {
if (this->EndX < this->CapacityX) {
Retry:
new (this->end()) T(Elt);
this->setEnd(this->end()+1);
return;
}
this->grow();
goto Retry;
}
void pop_back() {
this->setEnd(this->end()-1);
this->end()->~T();
}
};
// Define this out-of-line to dissuade the C++ compiler from inlining it.
@ -226,7 +219,7 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
/// implementations that are designed to work with POD-like T's.
template <typename T>
class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
public:
protected:
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
// No need to do a destroy loop for POD's.
@ -255,6 +248,21 @@ public:
void grow(size_t MinSize = 0) {
this->grow_pod(MinSize*sizeof(T), sizeof(T));
}
public:
void push_back(const T &Elt) {
if (this->EndX < this->CapacityX) {
Retry:
*this->end() = Elt;
this->setEnd(this->end()+1);
return;
}
this->grow();
goto Retry;
}
void pop_back() {
this->setEnd(this->end()-1);
}
};
@ -270,11 +278,13 @@ public:
typedef typename SuperClass::iterator iterator;
typedef typename SuperClass::size_type size_type;
protected:
// Default ctor - Initialize to empty.
explicit SmallVectorImpl(unsigned N)
: SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
}
public:
~SmallVectorImpl() {
// Destroy the constructed elements in the vector.
this->destroy_range(this->begin(), this->end());
@ -297,7 +307,7 @@ public:
} else if (N > this->size()) {
if (this->capacity() < N)
this->grow(N);
this->construct_range(this->end(), this->begin()+N, T());
std::uninitialized_fill(this->end(), this->begin()+N, T());
this->setEnd(this->begin()+N);
}
}
@ -309,7 +319,7 @@ public:
} else if (N > this->size()) {
if (this->capacity() < N)
this->grow(N);
construct_range(this->end(), this->begin()+N, NV);
std::uninitialized_fill(this->end(), this->begin()+N, NV);
this->setEnd(this->begin()+N);
}
}
@ -319,25 +329,9 @@ public:
this->grow(N);
}
void push_back(const T &Elt) {
if (this->EndX < this->CapacityX) {
Retry:
new (this->end()) T(Elt);
this->setEnd(this->end()+1);
return;
}
this->grow();
goto Retry;
}
void pop_back() {
this->setEnd(this->end()-1);
this->end()->~T();
}
T pop_back_val() {
T Result = this->back();
pop_back();
this->pop_back();
return Result;
}
@ -376,7 +370,7 @@ public:
if (this->capacity() < NumElts)
this->grow(NumElts);
this->setEnd(this->begin()+NumElts);
construct_range(this->begin(), this->end(), Elt);
std::uninitialized_fill(this->begin(), this->end(), Elt);
}
iterator erase(iterator I) {
@ -384,7 +378,7 @@ public:
// Shift all elts down one.
std::copy(I+1, this->end(), I);
// Drop the last elt.
pop_back();
this->pop_back();
return(N);
}
@ -400,7 +394,7 @@ public:
iterator insert(iterator I, const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
push_back(Elt);
this->push_back(Elt);
return this->end()-1;
}
@ -554,12 +548,6 @@ public:
assert(N <= this->capacity());
this->setEnd(this->begin() + N);
}
private:
static void construct_range(T *S, T *E, const T &Elt) {
for (; S != E; ++S)
new (S) T(Elt);
}
};
@ -686,9 +674,7 @@ public:
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(NumTsAvailable) {
this->reserve(Size);
while (Size--)
this->push_back(Value);
this->assign(Size, Value);
}
template<typename ItTy>
@ -718,9 +704,7 @@ public:
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(0) {
this->reserve(Size);
while (Size--)
this->push_back(Value);
this->assign(Size, Value);
}
template<typename ItTy>

View file

@ -18,11 +18,11 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <climits>
#include <cstring>
namespace llvm {
@ -128,7 +128,7 @@ public:
else if (sizeof(BitWord) == 8)
NumBits += CountPopulation_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
return NumBits;
}
@ -138,13 +138,11 @@ public:
if (Bits[i] != 0) {
if (sizeof(BitWord) == 4)
return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
assert(0 && "Illegal empty element");
return 0; // Not reached
llvm_unreachable("Illegal empty element");
}
/// find_next - Returns the index of the next set bit starting from the
@ -165,10 +163,9 @@ public:
if (Copy != 0) {
if (sizeof(BitWord) == 4)
return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
// Check subsequent words.
@ -176,10 +173,9 @@ public:
if (Bits[i] != 0) {
if (sizeof(BitWord) == 4)
return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
else if (sizeof(BitWord) == 8)
if (sizeof(BitWord) == 8)
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
else
assert(0 && "Unsupported!");
llvm_unreachable("Unsupported!");
}
return -1;
}
@ -264,15 +260,6 @@ public:
}
BecameZero = allzero;
}
// Get a hash value for this element;
uint64_t getHashValue() const {
uint64_t HashVal = 0;
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
HashVal ^= Bits[i];
}
return HashVal;
}
};
template <unsigned ElementSize = 128>
@ -813,18 +800,6 @@ public:
iterator end() const {
return iterator(this, true);
}
// Get a hash value for this bitmap.
uint64_t getHashValue() const {
uint64_t HashVal = 0;
for (ElementListConstIter Iter = Elements.begin();
Iter != Elements.end();
++Iter) {
HashVal ^= Iter->index();
HashVal ^= Iter->getHashValue();
}
return HashVal;
}
};
// Convenience functions to allow Or and And without dereferencing in the user

View file

@ -0,0 +1,268 @@
//===--- llvm/ADT/SparseSet.h - Sparse set ----------------------*- 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 SparseSet class derived from the version described in
// Briggs, Torczon, "An efficient representation for sparse sets", ACM Letters
// on Programming Languages and Systems, Volume 2 Issue 1-4, March-Dec. 1993.
//
// A sparse set holds a small number of objects identified by integer keys from
// a moderately sized universe. The sparse set uses more memory than other
// containers in order to provide faster operations.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_SPARSESET_H
#define LLVM_ADT_SPARSESET_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include <limits>
namespace llvm {
/// SparseSetFunctor - Objects in a SparseSet are identified by small integer
/// keys. A functor object is used to compute the key of an object. The
/// functor's operator() must return an unsigned smaller than the universe.
///
/// The default functor implementation forwards to a getSparseSetKey() method
/// on the object. It is intended for sparse sets holding ad-hoc structs.
///
template<typename ValueT>
struct SparseSetFunctor {
unsigned operator()(const ValueT &Val) {
return Val.getSparseSetKey();
}
};
/// SparseSetFunctor<unsigned> - Provide a trivial identity functor for
/// SparseSet<unsigned>.
///
template<> struct SparseSetFunctor<unsigned> {
unsigned operator()(unsigned Val) { return Val; }
};
/// SparseSet - Fast set implementation for objects that can be identified by
/// small unsigned keys.
///
/// SparseSet 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, SparseSet provides constant-time fast
/// clear() and iteration 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. When no elements
/// have been erased, the iteration order is the insertion order.
///
/// Compared to BitVector, SparseSet<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.
///
/// SparseSet 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 2 cache lines, but the sparse
/// array uses 4 x Universe bytes.
///
/// When SparseT is uint8_t (the default), find() touches up to 2+[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.
///
/// @param ValueT The type of objects in the set.
/// @param SparseT An unsigned integer type. See above.
/// @param KeyFunctorT A functor that computes the unsigned key of a ValueT.
///
template<typename ValueT,
typename SparseT = uint8_t,
typename KeyFunctorT = SparseSetFunctor<ValueT> >
class SparseSet {
typedef SmallVector<ValueT, 8> DenseT;
DenseT Dense;
SparseT *Sparse;
unsigned Universe;
KeyFunctorT KeyOf;
// Disable copy construction and assignment.
// This data structure is not meant to be used that way.
SparseSet(const SparseSet&); // DO NOT IMPLEMENT.
SparseSet &operator=(const SparseSet&); // DO NOT IMPLEMENT.
public:
typedef ValueT value_type;
typedef ValueT &reference;
typedef const ValueT &const_reference;
typedef ValueT *pointer;
typedef const ValueT *const_pointer;
SparseSet() : Sparse(0), Universe(0) {}
~SparseSet() { free(Sparse); }
/// setUniverse - 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;
}
// Import trivial vector stuff from DenseT.
typedef typename DenseT::iterator iterator;
typedef typename DenseT::const_iterator const_iterator;
const_iterator begin() const { return Dense.begin(); }
const_iterator end() const { return Dense.end(); }
iterator begin() { return Dense.begin(); }
iterator end() { return Dense.end(); }
/// empty - Returns true if the set is empty.
///
/// This is not the same as BitVector::empty().
///
bool empty() const { return Dense.empty(); }
/// size - 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 { return Dense.size(); }
/// clear - Clears the set. This is a very fast constant time operation.
///
void clear() {
// Sparse does not need to be cleared, see find().
Dense.clear();
}
/// find - 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(unsigned Key) {
assert(Key < 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[Key], e = size(); i < e; i += Stride) {
const unsigned FoundKey = KeyOf(Dense[i]);
assert(FoundKey < Universe && "Invalid key in set. Did object mutate?");
if (Key == FoundKey)
return begin() + i;
// Stride is 0 when SparseT >= unsigned. We don't need to loop.
if (!Stride)
break;
}
return end();
}
const_iterator find(unsigned Key) const {
return const_cast<SparseSet*>(this)->find(Key);
}
/// count - Returns true if this set contains an element identified by Key.
///
bool count(unsigned Key) const {
return find(Key) != end();
}
/// insert - Attempts to insert a new element.
///
/// If Val is successfully inserted, return (I, true), where I is an iterator
/// pointing to the newly inserted element.
///
/// If the set already contains an element with the same key as Val, return
/// (I, false), where I is an iterator pointing to the existing element.
///
/// Insertion invalidates all iterators.
///
std::pair<iterator, bool> insert(const ValueT &Val) {
unsigned Key = KeyOf(Val);
iterator I = find(Key);
if (I != end())
return std::make_pair(I, false);
Sparse[Key] = size();
Dense.push_back(Val);
return std::make_pair(end() - 1, true);
}
/// array subscript - If an element already exists with this key, return it.
/// Otherwise, automatically construct a new value from Key, insert it,
/// and return the newly inserted element.
ValueT &operator[](unsigned Key) {
return *insert(ValueT(Key)).first;
}
/// erase - Erases an existing element identified by a valid iterator.
///
/// This invalidates all iterators, but erase() returns an iterator pointing
/// to the next element. This makes it possible to erase selected elements
/// while iterating over the set:
///
/// for (SparseSet::iterator I = Set.begin(); I != Set.end();)
/// if (test(*I))
/// I = Set.erase(I);
/// else
/// ++I;
///
/// Note that end() changes when elements are erased, unlike std::list.
///
iterator erase(iterator I) {
assert(unsigned(I - begin()) < size() && "Invalid iterator");
if (I != end() - 1) {
*I = Dense.back();
unsigned BackKey = KeyOf(Dense.back());
assert(BackKey < Universe && "Invalid key in set. Did object mutate?");
Sparse[BackKey] = I - begin();
}
// This depends on SmallVector::pop_back() not invalidating iterators.
// std::vector::pop_back() doesn't give that guarantee.
Dense.pop_back();
return I;
}
/// erase - Erases an element identified by Key, if it exists.
///
/// @param Key The key identifying the element to erase.
/// @returns True when an element was erased, false if no element was found.
///
bool erase(unsigned Key) {
iterator I = find(Key);
if (I == end())
return false;
erase(I);
return true;
}
};
} // end namespace llvm
#endif

View file

@ -27,6 +27,7 @@
#define LLVM_ADT_STATISTIC_H
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Valgrind.h"
namespace llvm {
class raw_ostream;
@ -110,6 +111,7 @@ protected:
bool tmp = Initialized;
sys::MemoryFence();
if (!tmp) RegisterStatistic();
TsanHappensAfter(this);
return *this;
}
void RegisterStatistic();

View file

@ -15,12 +15,7 @@
#define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
#include <cstdio>
#include <string>
namespace llvm {
template<typename T> class SmallVectorImpl;
@ -101,38 +96,6 @@ static inline std::string itostr(int64_t X) {
return utostr(static_cast<uint64_t>(X));
}
static inline std::string ftostr(double V) {
char Buffer[200];
sprintf(Buffer, "%20.6e", V);
char *B = Buffer;
while (*B == ' ') ++B;
return B;
}
static inline std::string ftostr(const APFloat& V) {
if (&V.getSemantics() == &APFloat::IEEEdouble)
return ftostr(V.convertToDouble());
else if (&V.getSemantics() == &APFloat::IEEEsingle)
return ftostr((double)V.convertToFloat());
return "<unknown format in ftostr>"; // error
}
static inline std::string LowercaseString(const std::string &S) {
std::string result(S);
for (unsigned i = 0; i < S.length(); ++i)
if (isupper(result[i]))
result[i] = char(tolower(result[i]));
return result;
}
static inline std::string UppercaseString(const std::string &S) {
std::string result(S);
for (unsigned i = 0; i < S.length(); ++i)
if (islower(result[i]))
result[i] = char(toupper(result[i]));
return result;
}
/// StrInStrNoCase - Portable version of strcasestr. Locates the first
/// occurrence of string 's1' in string 's2', ignoring case. Returns
/// the offset of s2 in s1 or npos if s2 cannot be found.

View file

@ -51,20 +51,11 @@ public:
/// StringMapImpl - This is the base class of StringMap that is shared among
/// all of its instantiations.
class StringMapImpl {
public:
/// ItemBucket - The hash table consists of an array of these. If Item is
/// non-null, this is an extant entry, otherwise, it is a hole.
struct ItemBucket {
/// FullHashValue - This remembers the full hash value of the key for
/// easy scanning.
unsigned FullHashValue;
/// Item - This is a pointer to the actual item object.
StringMapEntryBase *Item;
};
protected:
ItemBucket *TheTable;
// Array of NumBuckets pointers to entries, null pointers are holes.
// TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed
// by an array of the actual hash values as unsigned integers.
StringMapEntryBase **TheTable;
unsigned NumBuckets;
unsigned NumItems;
unsigned NumTombstones;
@ -238,8 +229,9 @@ public:
template<typename ValueTy, typename AllocatorTy = MallocAllocator>
class StringMap : public StringMapImpl {
AllocatorTy Allocator;
typedef StringMapEntry<ValueTy> MapEntryTy;
public:
typedef StringMapEntry<ValueTy> MapEntryTy;
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
@ -289,13 +281,13 @@ public:
iterator find(StringRef Key) {
int Bucket = FindKey(Key);
if (Bucket == -1) return end();
return iterator(TheTable+Bucket);
return iterator(TheTable+Bucket, true);
}
const_iterator find(StringRef Key) const {
int Bucket = FindKey(Key);
if (Bucket == -1) return end();
return const_iterator(TheTable+Bucket);
return const_iterator(TheTable+Bucket, true);
}
/// lookup - Return the entry for the specified key, or a default
@ -320,13 +312,13 @@ public:
/// insert it and return true.
bool insert(MapEntryTy *KeyValue) {
unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
ItemBucket &Bucket = TheTable[BucketNo];
if (Bucket.Item && Bucket.Item != getTombstoneVal())
StringMapEntryBase *&Bucket = TheTable[BucketNo];
if (Bucket && Bucket != getTombstoneVal())
return false; // Already exists in map.
if (Bucket.Item == getTombstoneVal())
if (Bucket == getTombstoneVal())
--NumTombstones;
Bucket.Item = KeyValue;
Bucket = KeyValue;
++NumItems;
assert(NumItems + NumTombstones <= NumBuckets);
@ -340,10 +332,11 @@ public:
// Zap all values, resetting the keys back to non-present (not tombstone),
// which is safe because we're removing all elements.
for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) {
if (I->Item && I->Item != getTombstoneVal()) {
static_cast<MapEntryTy*>(I->Item)->Destroy(Allocator);
I->Item = 0;
for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
StringMapEntryBase *&Bucket = TheTable[I];
if (Bucket && Bucket != getTombstoneVal()) {
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
Bucket = 0;
}
}
@ -357,21 +350,21 @@ public:
template <typename InitTy>
MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
unsigned BucketNo = LookupBucketFor(Key);
ItemBucket &Bucket = TheTable[BucketNo];
if (Bucket.Item && Bucket.Item != getTombstoneVal())
return *static_cast<MapEntryTy*>(Bucket.Item);
StringMapEntryBase *&Bucket = TheTable[BucketNo];
if (Bucket && Bucket != getTombstoneVal())
return *static_cast<MapEntryTy*>(Bucket);
MapEntryTy *NewItem =
MapEntryTy::Create(Key.begin(), Key.end(), Allocator, Val);
if (Bucket.Item == getTombstoneVal())
if (Bucket == getTombstoneVal())
--NumTombstones;
++NumItems;
assert(NumItems + NumTombstones <= NumBuckets);
// Fill in the bucket for the hash table. The FullHashValue was already
// filled in by LookupBucketFor.
Bucket.Item = NewItem;
Bucket = NewItem;
RehashTable();
return *NewItem;
@ -410,21 +403,21 @@ public:
template<typename ValueTy>
class StringMapConstIterator {
protected:
StringMapImpl::ItemBucket *Ptr;
StringMapEntryBase **Ptr;
public:
typedef StringMapEntry<ValueTy> value_type;
explicit StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
explicit StringMapConstIterator(StringMapEntryBase **Bucket,
bool NoAdvance = false)
: Ptr(Bucket) {
if (!NoAdvance) AdvancePastEmptyBuckets();
}
const value_type &operator*() const {
return *static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
return *static_cast<StringMapEntry<ValueTy>*>(*Ptr);
}
const value_type *operator->() const {
return static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
return static_cast<StringMapEntry<ValueTy>*>(*Ptr);
}
bool operator==(const StringMapConstIterator &RHS) const {
@ -445,7 +438,7 @@ public:
private:
void AdvancePastEmptyBuckets() {
while (Ptr->Item == 0 || Ptr->Item == StringMapImpl::getTombstoneVal())
while (*Ptr == 0 || *Ptr == StringMapImpl::getTombstoneVal())
++Ptr;
}
};
@ -453,15 +446,15 @@ private:
template<typename ValueTy>
class StringMapIterator : public StringMapConstIterator<ValueTy> {
public:
explicit StringMapIterator(StringMapImpl::ItemBucket *Bucket,
explicit StringMapIterator(StringMapEntryBase **Bucket,
bool NoAdvance = false)
: StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
}
StringMapEntry<ValueTy> &operator*() const {
return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
}
StringMapEntry<ValueTy> *operator->() const {
return static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
}
};

View file

@ -10,15 +10,26 @@
#ifndef LLVM_ADT_STRINGREF_H
#define LLVM_ADT_STRINGREF_H
#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstring>
#include <utility>
#include <limits>
#include <string>
#include <utility>
namespace llvm {
template<typename T>
class SmallVectorImpl;
class APInt;
class hash_code;
class StringRef;
/// Helper functions for StringRef::getAsInteger.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
unsigned long long &Result);
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
/// StringRef - Represent a constant reference to a string, i.e. a character
/// array and a length, which need not be null terminated.
@ -304,14 +315,29 @@ namespace llvm {
///
/// If the string is invalid or if only a subset of the string is valid,
/// this returns true to signify the error. The string is considered
/// erroneous if empty.
/// erroneous if empty or if it overflows T.
///
bool getAsInteger(unsigned Radix, long long &Result) const;
bool getAsInteger(unsigned Radix, unsigned long long &Result) const;
bool getAsInteger(unsigned Radix, int &Result) const;
bool getAsInteger(unsigned Radix, unsigned &Result) const;
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
long long LLVal;
if (getAsSignedInteger(*this, Radix, LLVal) ||
static_cast<T>(LLVal) != LLVal)
return true;
Result = LLVal;
return false;
}
// TODO: Provide overloads for int/unsigned that check for overflow.
template <typename T>
typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
unsigned long long ULLVal;
if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
static_cast<T>(ULLVal) != ULLVal)
return true;
Result = ULLVal;
return false;
}
/// getAsInteger - Parse the current string as an integer of the
/// specified radix, or of an autosensed radix if the radix given
@ -326,6 +352,16 @@ namespace llvm {
/// string is well-formed in the given radix.
bool getAsInteger(unsigned Radix, APInt &Result) const;
/// @}
/// @name String Operations
/// @{
// lower - Convert the given ASCII string to lowercase.
std::string lower() const;
/// upper - Convert the given ASCII string to uppercase.
std::string upper() const;
/// @}
/// @name Substring Operations
/// @{
@ -343,6 +379,20 @@ namespace llvm {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
/// drop_front - Return a StringRef equal to 'this' but with the first
/// elements dropped.
StringRef drop_front(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
}
/// drop_back - Return a StringRef equal to 'this' but with the last
/// elements dropped.
StringRef drop_back(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
}
/// slice - Return a reference to the substring from [Start, End).
///
@ -466,6 +516,9 @@ namespace llvm {
/// @}
/// \brief Compute a hash_code for a StringRef.
hash_code hash_value(StringRef S);
// StringRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };

View file

@ -37,6 +37,15 @@ public:
delete V;
}
// implicit conversion operator to ArrayRef.
operator ArrayRef<EltTy>() const {
if (Val.isNull())
return ArrayRef<EltTy>();
if (Val.template is<EltTy>())
return *Val.getAddrOfPtr1();
return *Val.template get<VecTy*>();
}
bool empty() const {
// This vector can be empty if it contains no element, or if it
// contains a pointer to an empty vector.
@ -54,18 +63,20 @@ public:
return Val.template get<VecTy*>()->size();
}
typedef const EltTy *iterator;
iterator begin() const {
typedef const EltTy *const_iterator;
typedef EltTy *iterator;
iterator begin() {
if (empty())
return 0;
if (Val.template is<EltTy>())
return Val.template getAddrOf<EltTy>();
return Val.getAddrOfPtr1();
return Val.template get<VecTy *>()->begin();
}
iterator end() const {
iterator end() {
if (empty())
return 0;
@ -75,7 +86,14 @@ public:
return Val.template get<VecTy *>()->end();
}
const_iterator begin() const {
return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
}
const_iterator end() const {
return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
}
EltTy operator[](unsigned i) const {
assert(!Val.isNull() && "can't index into an empty vector");
if (EltTy V = Val.template dyn_cast<EltTy>()) {
@ -124,6 +142,20 @@ public:
}
// Otherwise, we're already empty.
}
iterator erase(iterator I) {
// If we have a single value, convert to empty.
if (Val.template is<EltTy>()) {
if (I == begin())
Val = (EltTy)0;
} else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
// multiple items in a vector; just do the erase, there is no
// benefit to collapsing back to a pointer
return Vec->erase(I);
}
return 0;
}
private:
void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.

View file

@ -220,8 +220,7 @@ bool Trie<Payload>::addString(const std::string& s, const Payload& data) {
assert(0 && "FIXME!");
return false;
case Node::DontMatch:
assert(0 && "Impossible!");
return false;
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;
@ -258,8 +257,7 @@ const Payload& Trie<Payload>::lookup(const std::string& s) const {
case Node::StringIsPrefix:
return Empty;
case Node::DontMatch:
assert(0 && "Impossible!");
return Empty;
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;

View file

@ -43,20 +43,19 @@ public:
enum ArchType {
UnknownArch,
alpha, // Alpha: alpha
arm, // ARM; arm, armv.*, xscale
bfin, // Blackfin: bfin
cellspu, // CellSPU: spu, cellspu
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
mipsel, // MIPSEL: mipsel, mipsallegrexel
mips64, // MIPS64: mips64
mips64el,// MIPS64EL: mips64el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
r600, // R600: AMD GPUs HD2XXX - HD6XXX
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
systemz, // SystemZ: s390x
tce, // TCE (http://tce.cs.tut.fi/): tce
thumb, // Thumb: thumb, thumbv.*
x86, // X86: i[3-9]86
@ -66,16 +65,16 @@ public:
ptx32, // PTX: ptx (32-bit)
ptx64, // PTX: ptx (64-bit)
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: amd IL
InvalidArch
amdil // amdil: amd IL
};
enum VendorType {
UnknownVendor,
Apple,
PC,
SCEI
SCEI,
BGP,
BGQ
};
enum OSType {
UnknownOS,
@ -93,61 +92,52 @@ public:
MinGW32, // i*86-pc-mingw32, *-w64-mingw32
NetBSD,
OpenBSD,
Psp,
Solaris,
Win32,
Haiku,
Minix,
RTEMS,
NativeClient
NativeClient,
CNK // BG/P Compute-Node Kernel
};
enum EnvironmentType {
UnknownEnvironment,
GNU,
GNUEABI,
GNUEABIHF,
EABI,
MachO
MachO,
ANDROIDEABI
};
private:
std::string Data;
/// The parsed arch type (or InvalidArch if uninitialized).
mutable ArchType Arch;
/// The parsed arch type.
ArchType Arch;
/// The parsed vendor type.
mutable VendorType Vendor;
VendorType Vendor;
/// The parsed OS type.
mutable OSType OS;
OSType OS;
/// The parsed Environment type.
mutable EnvironmentType Environment;
bool isInitialized() const { return Arch != InvalidArch; }
static ArchType ParseArch(StringRef ArchName);
static VendorType ParseVendor(StringRef VendorName);
static OSType ParseOS(StringRef OSName);
static EnvironmentType ParseEnvironment(StringRef EnvironmentName);
void Parse() const;
EnvironmentType Environment;
public:
/// @name Constructors
/// @{
Triple() : Data(), Arch(InvalidArch) {}
explicit Triple(const Twine &Str) : Data(Str.str()), Arch(InvalidArch) {}
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
: Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
Arch(InvalidArch) {
}
/// \brief Default constructor is the same as an empty string and leaves all
/// triple fields unknown.
Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
const Twine &EnvironmentStr)
: Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
EnvironmentStr).str()), Arch(InvalidArch) {
}
const Twine &EnvironmentStr);
/// @}
/// @name Normalization
@ -164,22 +154,13 @@ public:
/// @{
/// getArch - Get the parsed architecture type of this triple.
ArchType getArch() const {
if (!isInitialized()) Parse();
return Arch;
}
ArchType getArch() const { return Arch; }
/// getVendor - Get the parsed vendor type of this triple.
VendorType getVendor() const {
if (!isInitialized()) Parse();
return Vendor;
}
VendorType getVendor() const { return Vendor; }
/// getOS - Get the parsed operating system type of this triple.
OSType getOS() const {
if (!isInitialized()) Parse();
return OS;
}
OSType getOS() const { return OS; }
/// hasEnvironment - Does this triple have the optional environment
/// (fourth) component?
@ -188,11 +169,31 @@ public:
}
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const {
if (!isInitialized()) Parse();
return Environment;
EnvironmentType getEnvironment() const { return Environment; }
/// getOSVersion - Parse the version number from the OS name component of the
/// triple, if present.
///
/// For example, "fooos1.2.3" would return (1, 2, 3).
///
/// If an entry is not defined, it will be returned as 0.
void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
/// getOSMajorVersion - Return just the major version number, this is
/// specialized because it is a common query.
unsigned getOSMajorVersion() const {
unsigned Maj, Min, Micro;
getOSVersion(Maj, Min, Micro);
return Maj;
}
/// getMacOSXVersion - Parse the version number as with getOSVersion and then
/// translate generic "darwin" versions to the corresponding OS X versions.
/// This may also be called with IOS triples but the OS X version number is
/// just set to a constant 10.4.0 in that case. Returns true if successful.
bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
unsigned &Micro) const;
/// @}
/// @name Direct Component Access
/// @{
@ -221,21 +222,28 @@ public:
/// if the environment component is present).
StringRef getOSAndEnvironmentName() const;
/// getOSVersion - Parse the version number from the OS name component of the
/// triple, if present.
///
/// For example, "fooos1.2.3" would return (1, 2, 3).
///
/// If an entry is not defined, it will be returned as 0.
void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
/// @}
/// @name Convenience Predicates
/// @{
/// getOSMajorVersion - Return just the major version number, this is
/// specialized because it is a common query.
unsigned getOSMajorVersion() const {
unsigned Maj, Min, Micro;
getOSVersion(Maj, Min, Micro);
return Maj;
}
/// \brief Test whether the architecture is 64-bit
///
/// Note that this tests for 64-bit pointer width, and nothing else. Note
/// that we intentionally expose only three predicates, 64-bit, 32-bit, and
/// 16-bit. The inner details of pointer width for particular architectures
/// is not summed up in the triple, and so only a coarse grained predicate
/// system is provided.
bool isArch64Bit() const;
/// \brief Test whether the architecture is 32-bit
///
/// Note that this tests for 32-bit pointer width, and nothing else.
bool isArch32Bit() const;
/// \brief Test whether the architecture is 16-bit
///
/// Note that this tests for 16-bit pointer width, and nothing else.
bool isArch16Bit() const;
/// isOSVersionLT - Helper function for doing comparisons against version
/// numbers included in the target triple.
@ -254,23 +262,6 @@ public:
return false;
}
/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
/// "darwin" and "osx" as OS X triples.
bool isMacOSX() const {
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
}
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const {
return isMacOSX() || getOS() == Triple::IOS;
}
/// isOSWindows - Is this a "Windows" OS.
bool isOSWindows() const {
return getOS() == Triple::Win32 || getOS() == Triple::Cygwin ||
getOS() == Triple::MinGW32;
}
/// isMacOSXVersionLT - Comparison function for checking OS X version
/// compatibility, which handles supporting skewed version numbering schemes
/// used by the "darwin" triples.
@ -287,6 +278,43 @@ public:
return isOSVersionLT(Minor + 4, Micro, 0);
}
/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
/// "darwin" and "osx" as OS X triples.
bool isMacOSX() const {
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
}
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const {
return isMacOSX() || getOS() == Triple::IOS;
}
/// \brief Tests for either Cygwin or MinGW OS
bool isOSCygMing() const {
return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
}
/// isOSWindows - Is this a "Windows" OS.
bool isOSWindows() const {
return getOS() == Triple::Win32 || isOSCygMing();
}
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return !isOSDarwin() && !isOSWindows();
}
/// \brief Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
return isOSWindows();
}
/// \brief Tests whether the environment is MachO.
// FIXME: Should this be an OSBinFormat predicate?
bool isEnvironmentMachO() const {
return getEnvironment() == Triple::MachO || isOSDarwin();
}
/// @}
/// @name Mutators
/// @{
@ -334,6 +362,26 @@ public:
/// the target assembler.
const char *getArchNameForAssembler();
/// @}
/// @name Helpers to build variants of a particular triple.
/// @{
/// \brief Form a triple with a 32-bit variant of the current architecture.
///
/// This can be used to move across "families" of architectures where useful.
///
/// \returns A new triple with a 32-bit architecture or an unknown
/// architecture if no such variant can be found.
llvm::Triple get32BitArchVariant() const;
/// \brief Form a triple with a 64-bit variant of the current architecture.
///
/// This can be used to move across "families" of architectures where useful.
///
/// \returns A new triple with a 64-bit architecture or an unknown
/// architecture if no such variant can be found.
llvm::Triple get64BitArchVariant() const;
/// @}
/// @name Static helpers for IDs.
/// @{

View file

@ -12,6 +12,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <string>
@ -425,7 +426,7 @@ namespace llvm {
StringRef getSingleStringRef() const {
assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
switch (getLHSKind()) {
default: assert(0 && "Out of sync with isSingleStringRef");
default: llvm_unreachable("Out of sync with isSingleStringRef");
case EmptyKind: return StringRef();
case CStringKind: return StringRef(LHS.cString);
case StdStringKind: return StringRef(*LHS.stdString);

View file

@ -35,7 +35,7 @@
namespace llvm {
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
template<typename KeyT, typename ValueT, typename Config>
class ValueMapCallbackVH;
template<typename DenseMapT, typename KeyT>
@ -72,13 +72,11 @@ struct ValueMapConfig {
};
/// See the file comment.
template<typename KeyT, typename ValueT, typename Config = ValueMapConfig<KeyT>,
typename ValueInfoT = DenseMapInfo<ValueT> >
template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> >
class ValueMap {
friend class ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT>;
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> ValueMapCVH;
typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>,
ValueInfoT> MapT;
friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT;
typedef typename Config::ExtraData ExtraData;
MapT Map;
ExtraData Data;
@ -190,11 +188,11 @@ private:
// This CallbackVH updates its ValueMap when the contained Value changes,
// according to the user's preferences expressed through the Config object.
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
template<typename KeyT, typename ValueT, typename Config>
class ValueMapCallbackVH : public CallbackVH {
friend class ValueMap<KeyT, ValueT, Config, ValueInfoT>;
friend class ValueMap<KeyT, ValueT, Config>;
friend struct DenseMapInfo<ValueMapCallbackVH>;
typedef ValueMap<KeyT, ValueT, Config, ValueInfoT> ValueMapT;
typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
ValueMapT *Map;
@ -244,9 +242,9 @@ public:
}
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;
template<typename KeyT, typename ValueT, typename Config>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > {
typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
typedef DenseMapInfo<KeyT> PointerInfo;
static inline VH getEmptyKey() {

View file

@ -0,0 +1,331 @@
//===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements compile-time type-safe variadic functions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
#define LLVM_ADT_VARIADIC_FUNCTION_H
#include "llvm/ADT/ArrayRef.h"
namespace llvm {
// Define macros to aid in expanding a comma separated series with the index of
// the series pasted onto the last token.
#define LLVM_COMMA_JOIN1(x) x ## 0
#define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
#define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
#define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
#define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
#define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
#define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
#define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
#define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
#define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
#define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
#define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
#define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
#define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
#define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
#define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
#define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
#define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
#define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
#define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
#define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
#define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
#define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
#define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
#define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
#define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
#define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
#define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
#define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
#define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
#define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
#define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
/// \brief Class which can simulate a type-safe variadic function.
///
/// The VariadicFunction class template makes it easy to define
/// type-safe variadic functions where all arguments have the same
/// type.
///
/// Suppose we need a variadic function like this:
///
/// ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
///
/// Instead of many overloads of Foo(), we only need to define a helper
/// function that takes an array of arguments:
///
/// ResultT FooImpl(ArrayRef<const ArgT *> Args) {
/// // 'Args[i]' is a pointer to the i-th argument passed to Foo().
/// ...
/// }
///
/// and then define Foo() like this:
///
/// const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
///
/// VariadicFunction takes care of defining the overloads of Foo().
///
/// Actually, Foo is a function object (i.e. functor) instead of a plain
/// function. This object is stateless and its constructor/destructor
/// does nothing, so it's safe to create global objects and call Foo(...) at
/// any time.
///
/// Sometimes we need a variadic function to have some fixed leading
/// arguments whose types may be different from that of the optional
/// arguments. For example:
///
/// bool FullMatch(const StringRef &S, const RE &Regex,
/// const ArgT &A_0, ..., const ArgT &A_N);
///
/// VariadicFunctionN is for such cases, where N is the number of fixed
/// arguments. It is like VariadicFunction, except that it takes N more
/// template arguments for the types of the fixed arguments:
///
/// bool FullMatchImpl(const StringRef &S, const RE &Regex,
/// ArrayRef<const ArgT *> Args) { ... }
/// const VariadicFunction2<bool, const StringRef&,
/// const RE&, ArgT, FullMatchImpl>
/// FullMatch;
///
/// Currently VariadicFunction and friends support up-to 3
/// fixed leading arguments and up-to 32 optional arguments.
template <typename ResultT, typename ArgT,
ResultT (*Func)(ArrayRef<const ArgT *>)>
struct VariadicFunction {
ResultT operator()() const {
return Func(ArrayRef<const ArgT *>());
}
#define LLVM_DEFINE_OVERLOAD(N) \
ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
return Func(makeArrayRef(Args)); \
}
LLVM_DEFINE_OVERLOAD(1)
LLVM_DEFINE_OVERLOAD(2)
LLVM_DEFINE_OVERLOAD(3)
LLVM_DEFINE_OVERLOAD(4)
LLVM_DEFINE_OVERLOAD(5)
LLVM_DEFINE_OVERLOAD(6)
LLVM_DEFINE_OVERLOAD(7)
LLVM_DEFINE_OVERLOAD(8)
LLVM_DEFINE_OVERLOAD(9)
LLVM_DEFINE_OVERLOAD(10)
LLVM_DEFINE_OVERLOAD(11)
LLVM_DEFINE_OVERLOAD(12)
LLVM_DEFINE_OVERLOAD(13)
LLVM_DEFINE_OVERLOAD(14)
LLVM_DEFINE_OVERLOAD(15)
LLVM_DEFINE_OVERLOAD(16)
LLVM_DEFINE_OVERLOAD(17)
LLVM_DEFINE_OVERLOAD(18)
LLVM_DEFINE_OVERLOAD(19)
LLVM_DEFINE_OVERLOAD(20)
LLVM_DEFINE_OVERLOAD(21)
LLVM_DEFINE_OVERLOAD(22)
LLVM_DEFINE_OVERLOAD(23)
LLVM_DEFINE_OVERLOAD(24)
LLVM_DEFINE_OVERLOAD(25)
LLVM_DEFINE_OVERLOAD(26)
LLVM_DEFINE_OVERLOAD(27)
LLVM_DEFINE_OVERLOAD(28)
LLVM_DEFINE_OVERLOAD(29)
LLVM_DEFINE_OVERLOAD(30)
LLVM_DEFINE_OVERLOAD(31)
LLVM_DEFINE_OVERLOAD(32)
#undef LLVM_DEFINE_OVERLOAD
};
template <typename ResultT, typename Param0T, typename ArgT,
ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
struct VariadicFunction1 {
ResultT operator()(Param0T P0) const {
return Func(P0, ArrayRef<const ArgT *>());
}
#define LLVM_DEFINE_OVERLOAD(N) \
ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
return Func(P0, makeArrayRef(Args)); \
}
LLVM_DEFINE_OVERLOAD(1)
LLVM_DEFINE_OVERLOAD(2)
LLVM_DEFINE_OVERLOAD(3)
LLVM_DEFINE_OVERLOAD(4)
LLVM_DEFINE_OVERLOAD(5)
LLVM_DEFINE_OVERLOAD(6)
LLVM_DEFINE_OVERLOAD(7)
LLVM_DEFINE_OVERLOAD(8)
LLVM_DEFINE_OVERLOAD(9)
LLVM_DEFINE_OVERLOAD(10)
LLVM_DEFINE_OVERLOAD(11)
LLVM_DEFINE_OVERLOAD(12)
LLVM_DEFINE_OVERLOAD(13)
LLVM_DEFINE_OVERLOAD(14)
LLVM_DEFINE_OVERLOAD(15)
LLVM_DEFINE_OVERLOAD(16)
LLVM_DEFINE_OVERLOAD(17)
LLVM_DEFINE_OVERLOAD(18)
LLVM_DEFINE_OVERLOAD(19)
LLVM_DEFINE_OVERLOAD(20)
LLVM_DEFINE_OVERLOAD(21)
LLVM_DEFINE_OVERLOAD(22)
LLVM_DEFINE_OVERLOAD(23)
LLVM_DEFINE_OVERLOAD(24)
LLVM_DEFINE_OVERLOAD(25)
LLVM_DEFINE_OVERLOAD(26)
LLVM_DEFINE_OVERLOAD(27)
LLVM_DEFINE_OVERLOAD(28)
LLVM_DEFINE_OVERLOAD(29)
LLVM_DEFINE_OVERLOAD(30)
LLVM_DEFINE_OVERLOAD(31)
LLVM_DEFINE_OVERLOAD(32)
#undef LLVM_DEFINE_OVERLOAD
};
template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
struct VariadicFunction2 {
ResultT operator()(Param0T P0, Param1T P1) const {
return Func(P0, P1, ArrayRef<const ArgT *>());
}
#define LLVM_DEFINE_OVERLOAD(N) \
ResultT operator()(Param0T P0, Param1T P1, \
LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
return Func(P0, P1, makeAraryRef(Args)); \
}
LLVM_DEFINE_OVERLOAD(1)
LLVM_DEFINE_OVERLOAD(2)
LLVM_DEFINE_OVERLOAD(3)
LLVM_DEFINE_OVERLOAD(4)
LLVM_DEFINE_OVERLOAD(5)
LLVM_DEFINE_OVERLOAD(6)
LLVM_DEFINE_OVERLOAD(7)
LLVM_DEFINE_OVERLOAD(8)
LLVM_DEFINE_OVERLOAD(9)
LLVM_DEFINE_OVERLOAD(10)
LLVM_DEFINE_OVERLOAD(11)
LLVM_DEFINE_OVERLOAD(12)
LLVM_DEFINE_OVERLOAD(13)
LLVM_DEFINE_OVERLOAD(14)
LLVM_DEFINE_OVERLOAD(15)
LLVM_DEFINE_OVERLOAD(16)
LLVM_DEFINE_OVERLOAD(17)
LLVM_DEFINE_OVERLOAD(18)
LLVM_DEFINE_OVERLOAD(19)
LLVM_DEFINE_OVERLOAD(20)
LLVM_DEFINE_OVERLOAD(21)
LLVM_DEFINE_OVERLOAD(22)
LLVM_DEFINE_OVERLOAD(23)
LLVM_DEFINE_OVERLOAD(24)
LLVM_DEFINE_OVERLOAD(25)
LLVM_DEFINE_OVERLOAD(26)
LLVM_DEFINE_OVERLOAD(27)
LLVM_DEFINE_OVERLOAD(28)
LLVM_DEFINE_OVERLOAD(29)
LLVM_DEFINE_OVERLOAD(30)
LLVM_DEFINE_OVERLOAD(31)
LLVM_DEFINE_OVERLOAD(32)
#undef LLVM_DEFINE_OVERLOAD
};
template <typename ResultT, typename Param0T, typename Param1T,
typename Param2T, typename ArgT,
ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
struct VariadicFunction3 {
ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
return Func(P0, P1, P2, ArrayRef<const ArgT *>());
}
#define LLVM_DEFINE_OVERLOAD(N) \
ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
return Func(P0, P1, P2, makeArrayRef(Args)); \
}
LLVM_DEFINE_OVERLOAD(1)
LLVM_DEFINE_OVERLOAD(2)
LLVM_DEFINE_OVERLOAD(3)
LLVM_DEFINE_OVERLOAD(4)
LLVM_DEFINE_OVERLOAD(5)
LLVM_DEFINE_OVERLOAD(6)
LLVM_DEFINE_OVERLOAD(7)
LLVM_DEFINE_OVERLOAD(8)
LLVM_DEFINE_OVERLOAD(9)
LLVM_DEFINE_OVERLOAD(10)
LLVM_DEFINE_OVERLOAD(11)
LLVM_DEFINE_OVERLOAD(12)
LLVM_DEFINE_OVERLOAD(13)
LLVM_DEFINE_OVERLOAD(14)
LLVM_DEFINE_OVERLOAD(15)
LLVM_DEFINE_OVERLOAD(16)
LLVM_DEFINE_OVERLOAD(17)
LLVM_DEFINE_OVERLOAD(18)
LLVM_DEFINE_OVERLOAD(19)
LLVM_DEFINE_OVERLOAD(20)
LLVM_DEFINE_OVERLOAD(21)
LLVM_DEFINE_OVERLOAD(22)
LLVM_DEFINE_OVERLOAD(23)
LLVM_DEFINE_OVERLOAD(24)
LLVM_DEFINE_OVERLOAD(25)
LLVM_DEFINE_OVERLOAD(26)
LLVM_DEFINE_OVERLOAD(27)
LLVM_DEFINE_OVERLOAD(28)
LLVM_DEFINE_OVERLOAD(29)
LLVM_DEFINE_OVERLOAD(30)
LLVM_DEFINE_OVERLOAD(31)
LLVM_DEFINE_OVERLOAD(32)
#undef LLVM_DEFINE_OVERLOAD
};
// Cleanup the macro namespace.
#undef LLVM_COMMA_JOIN1
#undef LLVM_COMMA_JOIN2
#undef LLVM_COMMA_JOIN3
#undef LLVM_COMMA_JOIN4
#undef LLVM_COMMA_JOIN5
#undef LLVM_COMMA_JOIN6
#undef LLVM_COMMA_JOIN7
#undef LLVM_COMMA_JOIN8
#undef LLVM_COMMA_JOIN9
#undef LLVM_COMMA_JOIN10
#undef LLVM_COMMA_JOIN11
#undef LLVM_COMMA_JOIN12
#undef LLVM_COMMA_JOIN13
#undef LLVM_COMMA_JOIN14
#undef LLVM_COMMA_JOIN15
#undef LLVM_COMMA_JOIN16
#undef LLVM_COMMA_JOIN17
#undef LLVM_COMMA_JOIN18
#undef LLVM_COMMA_JOIN19
#undef LLVM_COMMA_JOIN20
#undef LLVM_COMMA_JOIN21
#undef LLVM_COMMA_JOIN22
#undef LLVM_COMMA_JOIN23
#undef LLVM_COMMA_JOIN24
#undef LLVM_COMMA_JOIN25
#undef LLVM_COMMA_JOIN26
#undef LLVM_COMMA_JOIN27
#undef LLVM_COMMA_JOIN28
#undef LLVM_COMMA_JOIN29
#undef LLVM_COMMA_JOIN30
#undef LLVM_COMMA_JOIN31
#undef LLVM_COMMA_JOIN32
} // end namespace llvm
#endif // LLVM_ADT_VARIADIC_FUNCTION_H

View file

@ -1,41 +0,0 @@
//===-- llvm/ADT/VectorExtras.h - Helpers for std::vector -------*- 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 helper functions which are useful for working with the
// std::vector class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_VECTOREXTRAS_H
#define LLVM_ADT_VECTOREXTRAS_H
#include <cstdarg>
#include <vector>
namespace llvm {
/// make_vector - Helper function which is useful for building temporary vectors
/// to pass into type construction of CallInst ctors. This turns a null
/// terminated list of pointers (or other value types) into a real live vector.
///
template<typename T>
inline std::vector<T> make_vector(T A, ...) {
va_list Args;
va_start(Args, A);
std::vector<T> Result;
Result.push_back(A);
while (T Val = va_arg(Args, T))
Result.push_back(Val);
va_end(Args);
return Result;
}
} // End llvm namespace
#endif

View file

@ -0,0 +1,102 @@
//===-- llvm/ADT/edit_distance.h - Array edit distance function --- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a Levenshtein distance function that works for any two
// sequences, with each element of each sequence being analogous to a character
// in a string.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_EDIT_DISTANCE_H
#define LLVM_ADT_EDIT_DISTANCE_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
#include <algorithm>
namespace llvm {
/// \brief Determine the edit distance between two sequences.
///
/// \param FromArray the first sequence to compare.
///
/// \param ToArray the second sequence to compare.
///
/// \param AllowReplacements whether to allow element replacements (change one
/// element into another) as a single operation, rather than as two operations
/// (an insertion and a removal).
///
/// \param MaxEditDistance If non-zero, the maximum edit distance that this
/// routine is allowed to compute. If the edit distance will exceed that
/// maximum, returns \c MaxEditDistance+1.
///
/// \returns the minimum number of element insertions, removals, or (if
/// \p AllowReplacements is \c true) replacements needed to transform one of
/// the given sequences into the other. If zero, the sequences are identical.
template<typename T>
unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
bool AllowReplacements = true,
unsigned MaxEditDistance = 0) {
// The algorithm implemented below is the "classic"
// dynamic-programming algorithm for computing the Levenshtein
// distance, which is described here:
//
// http://en.wikipedia.org/wiki/Levenshtein_distance
//
// Although the algorithm is typically described using an m x n
// array, only two rows are used at a time, so this implemenation
// just keeps two separate vectors for those two rows.
typename ArrayRef<T>::size_type m = FromArray.size();
typename ArrayRef<T>::size_type n = ToArray.size();
const unsigned SmallBufferSize = 64;
unsigned SmallBuffer[SmallBufferSize];
llvm::OwningArrayPtr<unsigned> Allocated;
unsigned *Previous = SmallBuffer;
if (2*(n + 1) > SmallBufferSize) {
Previous = new unsigned [2*(n+1)];
Allocated.reset(Previous);
}
unsigned *Current = Previous + (n + 1);
for (unsigned i = 0; i <= n; ++i)
Previous[i] = i;
for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
Current[0] = y;
unsigned BestThisRow = Current[0];
for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
if (AllowReplacements) {
Current[x] = std::min(
Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
std::min(Current[x-1], Previous[x])+1);
}
else {
if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1];
else Current[x] = std::min(Current[x-1], Previous[x]) + 1;
}
BestThisRow = std::min(BestThisRow, Current[x]);
}
if (MaxEditDistance && BestThisRow > MaxEditDistance)
return MaxEditDistance + 1;
unsigned *tmp = Current;
Current = Previous;
Previous = tmp;
}
unsigned Result = Previous[n];
return Result;
}
} // End llvm namespace
#endif

View file

@ -652,10 +652,6 @@ struct ilist : public iplist<NodeTy> {
void push_front(const NodeTy &val) { insert(this->begin(), val); }
void push_back(const NodeTy &val) { insert(this->end(), val); }
// Special forms of insert...
template<class InIt> void insert(iterator where, InIt first, InIt last) {
for (; first != last; ++first) insert(where, *first);
}
void insert(iterator where, size_type count, const NodeTy &val) {
for (; count != 0; --count) insert(where, val);
}

View file

@ -327,7 +327,7 @@ public:
}
/// doesAccessArgPointees - Return true if functions with the specified
/// behavior are known to potentially read or write from objects pointed
/// behavior are known to potentially read or write from objects pointed
/// to be their pointer-typed arguments (with arbitrary offsets).
///
static bool doesAccessArgPointees(ModRefBehavior MRB) {
@ -568,6 +568,11 @@ bool isNoAliasCall(const Value *V);
///
bool isIdentifiedObject(const Value *V);
/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
/// its definition. This returns true for allocas, non-extern-weak globals and
/// byval arguments.
bool isKnownNonNull(const Value *V);
} // End llvm namespace
#endif

View file

@ -264,6 +264,7 @@ private:
}
void setVolatile() { Volatile = true; }
public:
/// aliasesPointer - Return true if the specified pointer "may" (or must)
/// alias one of the members in the set.
///

View file

@ -24,7 +24,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <vector>
#include <sstream>
#include <string>
namespace llvm {
@ -41,7 +40,7 @@ class MachineBlockFrequencyInfo;
template<class BlockT, class FunctionT, class BlockProbInfoT>
class BlockFrequencyImpl {
DenseMap<BlockT *, BlockFrequency> Freqs;
DenseMap<const BlockT *, BlockFrequency> Freqs;
BlockProbInfoT *BPI;
@ -52,15 +51,16 @@ class BlockFrequencyImpl {
const uint32_t EntryFreq;
std::string getBlockName(BasicBlock *BB) const {
return BB->getNameStr();
return BB->getName().str();
}
std::string getBlockName(MachineBasicBlock *MBB) const {
std::stringstream ss;
std::string str;
raw_string_ostream ss(str);
ss << "BB#" << MBB->getNumber();
if (const BasicBlock *BB = MBB->getBasicBlock())
ss << " derived from LLVM BB " << BB->getNameStr();
ss << " derived from LLVM BB " << BB->getName();
return ss.str();
}
@ -308,8 +308,9 @@ class BlockFrequencyImpl {
public:
/// getBlockFreq - Return block frequency. Return 0 if we don't have it.
BlockFrequency getBlockFreq(BlockT *BB) const {
typename DenseMap<BlockT *, BlockFrequency>::const_iterator I = Freqs.find(BB);
BlockFrequency getBlockFreq(const BlockT *BB) const {
typename DenseMap<const BlockT *, BlockFrequency>::const_iterator
I = Freqs.find(BB);
if (I != Freqs.end())
return I->second;
return 0;

View file

@ -47,7 +47,7 @@ public:
/// that we should not rely on the value itself, but only on the comparison to
/// the other block frequencies. We do this to avoid using of floating points.
///
BlockFrequency getBlockFreq(BasicBlock *BB) const;
BlockFrequency getBlockFreq(const BasicBlock *BB) const;
};
}

View file

@ -17,13 +17,82 @@
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/BranchProbability.h"
namespace llvm {
class LoopInfo;
class raw_ostream;
/// \brief Analysis pass providing branch probability information.
///
/// This is a function analysis pass which provides information on the relative
/// probabilities of each "edge" in the function's CFG where such an edge is
/// defined by a pair of basic blocks. The probability for a given block and
/// a successor block are always relative to the probabilities of the other
/// successor blocks. Another way of looking at it is that the probabilities
/// for a given block B and each of its successors should sum to exactly
/// one (100%).
class BranchProbabilityInfo : public FunctionPass {
public:
static char ID;
BranchProbabilityInfo() : FunctionPass(ID) {
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
void print(raw_ostream &OS, const Module *M = 0) const;
/// \brief Get an edge's probability, relative to other out-edges of the Src.
///
/// This routine provides access to the fractional probability between zero
/// (0%) and one (100%) of this edge executing, relative to other edges
/// leaving the 'Src' block. The returned probability is never zero, and can
/// only be one if the source block has only one successor.
BranchProbability getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Test if an edge is hot relative to other out-edges of the Src.
///
/// Check whether this edge out of the source block is 'hot'. We define hot
/// as having a relative probability >= 80%.
bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Retrieve the hot successor of a block if one exists.
///
/// Given a basic block, look through its successors and if one exists for
/// which \see isEdgeHot would return true, return that successor block.
BasicBlock *getHotSucc(BasicBlock *BB) const;
/// \brief Print an edge's probability.
///
/// Retrieves an edge's probability similarly to \see getEdgeProbability, but
/// then prints that probability to the provided stream. That stream is then
/// returned.
raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Get the raw edge weight calculated for the block pair.
///
/// This returns the raw edge weight. It is guaranteed to fall between 1 and
/// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
/// This interface should be very carefully, and primarily by routines that
/// are updating the analysis by later calling setEdgeWeight.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Set the raw edge weight for the block pair.
///
/// This allows a pass to explicitly set the edge weight for a block. It can
/// be used when updating the CFG to update and preserve the branch
/// probability information. Read the implementation of how these edge
/// weights are calculated carefully before using!
void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
uint32_t Weight);
private:
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
// Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
@ -33,49 +102,26 @@ class BranchProbabilityInfo : public FunctionPass {
// weight to just "inherit" the non-zero weight of an adjacent successor.
static const uint32_t DEFAULT_WEIGHT = 16;
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
DenseMap<Edge, uint32_t> Weights;
// Get sum of the block successors' weights.
/// \brief Handle to the LoopInfo analysis.
LoopInfo *LI;
/// \brief Track the last function we run over for printing.
Function *LastF;
/// \brief Track the set of blocks directly succeeded by a returning block.
SmallPtrSet<BasicBlock *, 16> PostDominatedByUnreachable;
/// \brief Get sum of the block successors' weights.
uint32_t getSumForBlock(const BasicBlock *BB) const;
public:
static char ID;
BranchProbabilityInfo() : FunctionPass(ID) {
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
// Returned value is between 1 and UINT32_MAX. Look at
// BranchProbabilityInfo.cpp for details.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
// Look at BranchProbabilityInfo.cpp for details. Use it with caution!
void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
uint32_t Weight);
// A 'Hot' edge is an edge which probability is >= 80%.
bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const;
// Return a hot successor for the block BB or null if there isn't one.
BasicBlock *getHotSucc(BasicBlock *BB) const;
// Return a probability as a fraction between 0 (0% probability) and
// 1 (100% probability), however the value is never equal to 0, and can be 1
// only iff SRC block has only one successor.
BranchProbability getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const;
// Print value between 0 (0% probability) and 1 (100% probability),
// however the value is never equal to 0, and can be 1 only iff SRC block
// has only one successor.
raw_ostream &printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
BasicBlock *Dst) const;
bool calcUnreachableHeuristics(BasicBlock *BB);
bool calcMetadataWeights(BasicBlock *BB);
bool calcPointerHeuristics(BasicBlock *BB);
bool calcLoopBranchHeuristics(BasicBlock *BB);
bool calcZeroHeuristics(BasicBlock *BB);
bool calcFloatingPointHeuristics(BasicBlock *BB);
};
}

View file

@ -29,13 +29,13 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
static std::string getGraphName(const Function *F) {
return "CFG for '" + F->getNameStr() + "' function";
return "CFG for '" + F->getName().str() + "' function";
}
static std::string getSimpleNodeLabel(const BasicBlock *Node,
const Function *Graph) {
const Function *) {
if (!Node->getName().empty())
return Node->getNameStr();
return Node->getName().str();
std::string Str;
raw_string_ostream OS(Str);
@ -45,7 +45,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
static std::string getCompleteNodeLabel(const BasicBlock *Node,
const Function *Graph) {
const Function *) {
std::string Str;
raw_string_ostream OS(Str);
@ -95,7 +95,9 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
std::string Str;
raw_string_ostream OS(Str);
OS << SI->getCaseValue(SuccNo)->getValue();
SwitchInst::ConstCaseIt Case =
SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
OS << Case.getCaseValue()->getValue();
return OS.str();
}
return "";

View file

@ -14,9 +14,12 @@
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
#define LLVM_ANALYSIS_CAPTURETRACKING_H
namespace llvm {
class Value;
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
/// 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
@ -28,6 +31,33 @@ namespace llvm {
bool ReturnCaptures,
bool StoreCaptures);
/// This callback is used in conjunction with PointerMayBeCaptured. In
/// addition to the interface here, you'll need to provide your own getters
/// to see whether anything was captured.
struct CaptureTracker {
virtual ~CaptureTracker();
/// tooManyUses - The depth of traversal has breached a limit. There may be
/// capturing instructions that will not be passed into captured().
virtual void tooManyUses() = 0;
/// shouldExplore - This is the use of a value derived from the pointer.
/// To prune the search (ie., assume that none of its users could possibly
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
virtual bool shouldExplore(Use *U) = 0;
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking
/// for more capturing instructions.
virtual bool captured(Use *U) = 0;
};
/// PointerMayBeCaptured - Visit the value and the values derived from it and
/// find values which appear to be capturing the pointer value. This feeds
/// results into and is controlled by the CaptureTracker object.
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker);
} // end namespace llvm
#endif

View file

@ -1,4 +1,4 @@
//===- CodeMetrics.h - Measures the weight of a function---------*- C++ -*-===//
//===- CodeMetrics.h - Code cost measurements -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -18,80 +18,75 @@
#include "llvm/ADT/DenseMap.h"
namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class TargetData;
class Value;
// CodeMetrics - Calculate size and a few similar metrics for a set of
// basic blocks.
/// \brief Check whether an instruction is likely to be "free" when lowered.
bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
/// \brief Check whether a call will lower to something small.
///
/// This tests checks whether calls to this function will lower to something
/// significantly cheaper than a traditional call, often a single
/// instruction.
bool callIsSmall(const Function *F);
/// \brief Utility to calculate the size and a few similar metrics for a set
/// of basic blocks.
struct CodeMetrics {
/// NeverInline - True if this callee should never be inlined into a
/// caller.
// bool NeverInline;
/// \brief True if this function contains a call to setjmp or other functions
/// with attribute "returns twice" without having the attribute itself.
bool exposesReturnsTwice;
// True if this function contains a call to setjmp or _setjmp
bool callsSetJmp;
// True if this function calls itself
/// \brief True if this function calls itself.
bool isRecursive;
// True if this function contains one or more indirect branches
/// \brief True if this function contains one or more indirect branches.
bool containsIndirectBr;
/// usesDynamicAlloca - True if this function calls alloca (in the C sense).
/// \brief True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
/// NumInsts, NumBlocks - Keep track of how large each function is, which
/// is used to estimate the code size cost of inlining it.
unsigned NumInsts, NumBlocks;
/// \brief Number of instructions in the analyzed blocks.
unsigned NumInsts;
/// NumBBInsts - Keeps track of basic block code size estimates.
/// \brief Number of analyzed blocks.
unsigned NumBlocks;
/// \brief Keeps track of basic block code size estimates.
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
/// NumCalls - Keep track of the number of calls to 'big' functions.
/// \brief Keep track of the number of calls to 'big' functions.
unsigned NumCalls;
/// NumInlineCandidates - Keep track of the number of calls to internal
/// functions with only a single caller. These are likely targets for
/// future inlining, likely exposed by interleaved devirtualization.
/// \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;
/// NumVectorInsts - Keep track of how many instructions produce vector
/// values. The inliner is being more aggressive with inlining vector
/// kernels.
/// \brief How many instructions produce vector values.
///
/// The inliner is more aggressive with inlining vector kernels.
unsigned NumVectorInsts;
/// NumRets - Keep track of how many Ret instructions the block contains.
/// \brief How many 'ret' instructions the blocks contain.
unsigned NumRets;
CodeMetrics() : callsSetJmp(false), isRecursive(false),
CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
containsIndirectBr(false), usesDynamicAlloca(false),
NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0),
NumRets(0) {}
/// analyzeBasicBlock - Add information about the specified basic block
/// to the current structure.
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
/// analyzeFunction - Add information about the specified function
/// to the current structure.
/// \brief Add information about a function to the current state.
void analyzeFunction(Function *F, const TargetData *TD = 0);
/// CountCodeReductionForConstant - Figure out an approximation for how
/// many instructions will be constant folded if the specified value is
/// constant.
unsigned CountCodeReductionForConstant(Value *V);
/// CountBonusForConstant - Figure out an approximation for how much
/// per-call performance boost we can expect if the specified value is
/// constant.
unsigned CountBonusForConstant(Value *V);
/// CountCodeReductionForAlloca - Figure out an approximation of how much
/// smaller the function will be if it is inlined into a context where an
/// argument becomes an alloca.
///
unsigned CountCodeReductionForAlloca(Value *V);
};
}

View file

@ -25,6 +25,7 @@ namespace llvm {
class ConstantExpr;
class Instruction;
class TargetData;
class TargetLibraryInfo;
class Function;
class Type;
template<typename T>
@ -35,13 +36,15 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified operands. If successful, the constant result is returned, if not,
@ -51,7 +54,8 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
const TargetData *TD = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
/// instruction (icmp/fcmp) with the specified operands. If it fails, it
@ -59,7 +63,8 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
const TargetData *TD = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is
@ -76,15 +81,22 @@ Constant *ConstantFoldLoadFromConstPtr(Constant *C, const TargetData *TD = 0);
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE);
/// ConstantFoldLoadThroughGEPIndices - Given a constant and getelementptr
/// indices (with an *implied* zero pointer index that is not in the list),
/// return the constant value being addressed by a virtual load, or null if
/// something is funny and we can't decide.
Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
ArrayRef<Constant*> Indices);
/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool canConstantFoldCallTo(const Function *F);
/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *
ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands);
Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI = 0);
}
#endif

View file

@ -42,6 +42,7 @@ namespace llvm {
class DISubprogram;
class DITemplateTypeParameter;
class DITemplateValueParameter;
class DIObjCProperty;
class DIBuilder {
private:
@ -190,6 +191,39 @@ namespace llvm {
StringRef PropertySetterName = StringRef(),
unsigned PropertyAttributes = 0);
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
/// @param Name Member name.
/// @param File File where this member is defined.
/// @param LineNo Line number.
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
/// @param Property Property associated with this ivar.
DIType createObjCIVar(StringRef Name, DIFile File,
unsigned LineNo, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty,
MDNode *PropertyNode);
/// createObjCProperty - Create debugging information entry for Objective-C
/// property.
/// @param Name Property name.
/// @param File File where this property is defined.
/// @param LineNumber Line number.
/// @param GetterName Name of the Objective C property getter selector.
/// @param SetterName Name of the Objective C property setter selector.
/// @param PropertyAttributes Objective C property attributes.
/// @param Ty Type.
DIObjCProperty createObjCProperty(StringRef Name,
DIFile File, unsigned LineNumber,
StringRef GetterName,
StringRef SetterName,
unsigned PropertyAttributes,
DIType Ty);
/// createClassType - Create debugging information entry for a class.
/// @param Scope Scope in which this class is defined.
/// @param Name class name.
@ -313,6 +347,10 @@ namespace llvm {
DIType createTemporaryType();
DIType createTemporaryType(DIFile F);
/// createForwardDecl - Create a temporary forward-declared type.
DIType createForwardDecl(unsigned Tag, StringRef Name, DIFile F,
unsigned Line, unsigned RuntimeLang = 0);
/// retainType - Retain DIType in a module even if it is not referenced
/// through debug info anchors.
void retainType(DIType T);
@ -407,6 +445,7 @@ namespace llvm {
/// @param Ty Function type.
/// @param isLocalToUnit True if this function is not externally visible..
/// @param isDefinition True if this is a function definition.
/// @param ScopeLine Set to the beginning of the scope this starts
/// @param Flags e.g. is this function prototyped or not.
/// This flags are used to emit dwarf attributes.
/// @param isOptimized True if optimization is ON.
@ -417,6 +456,7 @@ namespace llvm {
DIFile File, unsigned LineNo,
DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned ScopeLine,
unsigned Flags = 0,
bool isOptimized = false,
Function *Fn = 0,
@ -470,7 +510,7 @@ namespace llvm {
/// @param Scope Lexical block.
/// @param File Source file.
DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
DIFile File);
DIFile File);
/// createLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.

View file

@ -31,7 +31,7 @@ struct DOTGraphTraitsViewer : public FunctionPass {
std::string Title, GraphName;
Graph = &getAnalysis<Analysis>();
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
Title = GraphName + " for '" + F.getNameStr() + "' function";
Title = GraphName + " for '" + F.getName().str() + "' function";
ViewGraph(Graph, Name, Simple, Title);
return false;
@ -55,7 +55,7 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
virtual bool runOnFunction(Function &F) {
Analysis *Graph;
std::string Filename = Name + "." + F.getNameStr() + ".dot";
std::string Filename = Name + "." + F.getName().str() + ".dot";
errs() << "Writing '" << Filename << "'...";
std::string ErrorInfo;
@ -64,7 +64,7 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
std::string Title, GraphName;
GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
Title = GraphName + " for '" + F.getNameStr() + "' function";
Title = GraphName + " for '" + F.getName().str() + "' function";
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);

View file

@ -43,6 +43,7 @@ namespace llvm {
class DILexicalBlockFile;
class DIVariable;
class DIType;
class DIObjCProperty;
/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
/// This should not be stored in a container, because underly MDNode may
@ -128,6 +129,7 @@ namespace llvm {
bool isUnspecifiedParameter() const;
bool isTemplateTypeParameter() const;
bool isTemplateValueParameter() const;
bool isObjCProperty() const;
};
/// DISubrange - This is used to represent ranges, for array bounds.
@ -135,8 +137,8 @@ namespace llvm {
public:
explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
int64_t getLo() const { return (int64_t)getUInt64Field(1); }
int64_t getHi() const { return (int64_t)getUInt64Field(2); }
uint64_t getLo() const { return getUInt64Field(1); }
uint64_t getHi() const { return getUInt64Field(2); }
};
/// DIArray - This descriptor holds an array of descriptors.
@ -153,6 +155,7 @@ namespace llvm {
/// DIScope - A base class for various scopes.
class DIScope : public DIDescriptor {
virtual void anchor();
public:
explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
virtual ~DIScope() {}
@ -163,6 +166,7 @@ namespace llvm {
/// DICompileUnit - A wrapper for a compile unit.
class DICompileUnit : public DIScope {
virtual void anchor();
public:
explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
@ -202,6 +206,7 @@ namespace llvm {
/// DIFile - This is a wrapper for a file.
class DIFile : public DIScope {
virtual void anchor();
public:
explicit DIFile(const MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isFile())
@ -230,7 +235,7 @@ namespace llvm {
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
class DIType : public DIScope {
public:
virtual void anchor();
protected:
// This ctor is used when the Tag has already been validated by a derived
// ctor.
@ -240,7 +245,6 @@ namespace llvm {
/// Verify - Verify that a type descriptor is well formed.
bool Verify() const;
public:
explicit DIType(const MDNode *N);
explicit DIType() {}
virtual ~DIType() {}
@ -320,6 +324,7 @@ namespace llvm {
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
virtual void anchor();
public:
explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
@ -338,6 +343,7 @@ namespace llvm {
/// DIDerivedType - A simple derived type, like a const qualified type,
/// a typedef, a pointer or reference, etc.
class DIDerivedType : public DIType {
virtual void anchor();
protected:
explicit DIDerivedType(const MDNode *N, bool, bool)
: DIType(N, true, true) {}
@ -351,29 +357,45 @@ namespace llvm {
/// return base type size.
uint64_t getOriginalTypeSize() const;
StringRef getObjCPropertyName() const { return getStringField(10); }
/// getObjCProperty - Return property node, if this ivar is
/// associated with one.
MDNode *getObjCProperty() const;
StringRef getObjCPropertyName() const {
if (getVersion() > LLVMDebugVersion11)
return StringRef();
return getStringField(10);
}
StringRef getObjCPropertyGetterName() const {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return getStringField(11);
}
StringRef getObjCPropertySetterName() const {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return getStringField(12);
}
bool isReadOnlyObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
}
bool isReadWriteObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
}
bool isAssignObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
}
bool isRetainObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
}
bool isCopyObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
}
bool isNonAtomicObjCProperty() {
assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
}
@ -391,6 +413,7 @@ namespace llvm {
/// other types, like a function or struct.
/// FIXME: Why is this a DIDerivedType??
class DICompositeType : public DIDerivedType {
virtual void anchor();
public:
explicit DICompositeType(const MDNode *N = 0)
: DIDerivedType(N, true, true) {
@ -454,6 +477,7 @@ namespace llvm {
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
virtual void anchor();
public:
explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
@ -495,6 +519,7 @@ namespace llvm {
DICompositeType getContainingType() const {
return getFieldAs<DICompositeType>(13);
}
unsigned isArtificial() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return getUnsignedField(14);
@ -543,6 +568,11 @@ namespace llvm {
return getFieldAs<DIFile>(6).getDirectory();
}
/// getScopeLineNumber - Get the beginning of the scope of the
/// function, not necessarily where the name of the program
/// starts.
unsigned getScopeLineNumber() const { return getUnsignedField(20); }
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
@ -621,7 +651,7 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
DICompileUnit getCompileUnit() const {
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -687,6 +717,7 @@ namespace llvm {
/// DILexicalBlock - This is a wrapper for a lexical block.
class DILexicalBlock : public DIScope {
virtual void anchor();
public:
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
@ -705,6 +736,7 @@ namespace llvm {
/// DILexicalBlockFile - This is a wrapper for a lexical block with
/// a filename change.
class DILexicalBlockFile : public DIScope {
virtual void anchor();
public:
explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getScope().getContext(); }
@ -724,6 +756,7 @@ namespace llvm {
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
virtual void anchor();
public:
explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
@ -760,6 +793,51 @@ namespace llvm {
bool Verify() const;
};
class DIObjCProperty : public DIDescriptor {
public:
explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
StringRef getObjCPropertyName() const { return getStringField(1); }
DIFile getFile() const { return getFieldAs<DIFile>(2); }
unsigned getLineNumber() const { return getUnsignedField(3); }
StringRef getObjCPropertyGetterName() const {
return getStringField(4);
}
StringRef getObjCPropertySetterName() const {
return getStringField(5);
}
bool isReadOnlyObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
}
bool isReadWriteObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
}
bool isAssignObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
}
bool isRetainObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
}
bool isCopyObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
}
bool isNonAtomicObjCProperty() {
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
}
DIType getType() const { return getFieldAs<DIType>(7); }
/// Verify - Verify that a derived type descriptor is well formed.
bool Verify() const;
/// print - print derived type.
void print(raw_ostream &OS) const;
/// dump - print derived type to dbgs() with a newline.
void dump() const;
};
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope);
@ -816,7 +894,7 @@ namespace llvm {
/// addGlobalVariable - Add global variable into GVs.
bool addGlobalVariable(DIGlobalVariable DIG);
// addSubprogram - Add subprgoram into SPs.
// addSubprogram - Add subprogram into SPs.
bool addSubprogram(DISubprogram SP);
/// addType - Add type into Tys.

View file

@ -154,6 +154,7 @@ public:
/// used to compute a forward dominator frontiers.
///
class DominanceFrontier : public DominanceFrontierBase {
virtual void anchor();
public:
static char ID; // Pass ID, replacement for typeid
DominanceFrontier() :

View file

@ -171,7 +171,7 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
// it might be that some blocks did not get a DFS number (e.g., blocks of
// infinite loops). In these cases an artificial exit node is required.
MultipleRoots |= (DT.isPostDominator() && N != F.size());
MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
// When naively implemented, the Lengauer-Tarjan algorithm requires a separate
// bucket for each vertex. However, this is unnecessary, because each vertex

View file

@ -185,6 +185,18 @@ void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
template<class NodeT>
class DominatorTreeBase : public DominatorBase<NodeT> {
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
assert(A != B);
assert(isReachableFromEntry(B));
assert(isReachableFromEntry(A));
const DomTreeNodeBase<NodeT> *IDom;
while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
B = IDom; // Walk up the tree
return IDom != 0;
}
protected:
typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
DomTreeNodeMapType DomTreeNodes;
@ -321,8 +333,7 @@ public:
/// block. This is the same as using operator[] on this class.
///
inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
typename DomTreeNodeMapType::const_iterator I = DomTreeNodes.find(BB);
return I != DomTreeNodes.end() ? I->second : 0;
return DomTreeNodes.lookup(BB);
}
/// getRootNode - This returns the entry node for the CFG of the function. If
@ -339,38 +350,26 @@ public:
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
if (A == 0 || B == 0) return false;
return dominatedBySlowTreeWalk(A, B);
}
inline bool properlyDominates(const NodeT *A, const NodeT *B) {
const DomTreeNodeBase<NodeT> *B) {
if (A == 0 || B == 0)
return false;
if (A == B)
return false;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return properlyDominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
const DomTreeNodeBase<NodeT> *IDom;
if (A == 0 || B == 0) return false;
while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
B = IDom; // Walk up the tree
return IDom != 0;
return dominates(A, B);
}
bool properlyDominates(const NodeT *A, const NodeT *B);
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
bool isReachableFromEntry(const NodeT* A) {
bool isReachableFromEntry(const NodeT* A) const {
assert(!this->isPostDominator() &&
"This is not implemented for post dominators");
return dominates(&A->getParent()->front(), A);
return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
}
inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const {
return A;
}
/// dominates - Returns true iff A dominates B. Note that this is not a
@ -378,10 +377,16 @@ public:
///
inline bool dominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) {
// A node trivially dominates itself.
if (B == A)
return true; // A node trivially dominates itself.
return true;
if (A == 0 || B == 0)
// An unreachable node is dominated by anything.
if (!isReachableFromEntry(B))
return true;
// And dominates nothing.
if (!isReachableFromEntry(A))
return false;
// Compare the result of the tree walk and the dfs numbers, if expensive
@ -406,16 +411,7 @@ public:
return dominatedBySlowTreeWalk(A, B);
}
inline bool dominates(const NodeT *A, const NodeT *B) {
if (A == B)
return true;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
bool dominates(const NodeT *A, const NodeT *B);
NodeT *getRoot() const {
assert(this->Roots.size() == 1 && "Should always have entry node!");
@ -623,9 +619,8 @@ protected:
}
DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.find(BB);
if (I != this->DomTreeNodes.end() && I->second)
return I->second;
if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
return Node;
// Haven't calculated this node yet? Get or calculate the node for the
// immediate dominator.
@ -641,8 +636,7 @@ protected:
}
inline NodeT *getIDom(NodeT *BB) const {
typename DenseMap<NodeT*, NodeT*>::const_iterator I = IDoms.find(BB);
return I != IDoms.end() ? I->second : 0;
return IDoms.lookup(BB);
}
inline void addRoot(NodeT* BB) {
@ -653,21 +647,24 @@ public:
/// recalculate - compute a dominator tree for the given function
template<class FT>
void recalculate(FT& F) {
typedef GraphTraits<FT*> TraitsTy;
reset();
this->Vertex.push_back(0);
if (!this->IsPostDominators) {
// Initialize root
this->Roots.push_back(&F.front());
this->IDoms[&F.front()] = 0;
this->DomTreeNodes[&F.front()] = 0;
NodeT *entry = TraitsTy::getEntryNode(&F);
this->Roots.push_back(entry);
this->IDoms[entry] = 0;
this->DomTreeNodes[entry] = 0;
Calculate<FT, NodeT*>(*this, F);
} else {
// Initialize the roots list
for (typename FT::iterator I = F.begin(), E = F.end(); I != E; ++I) {
if (std::distance(GraphTraits<FT*>::child_begin(I),
GraphTraits<FT*>::child_end(I)) == 0)
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)
addRoot(I);
// Prepopulate maps so that we don't get iterator invalidation issues later.
@ -680,6 +677,32 @@ public:
}
};
// These two functions are declared out of line as a workaround for building
// with old (< r147295) versions of clang because of pr11642.
template<class NodeT>
bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
if (A == B)
return true;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
template<class NodeT>
bool
DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
if (A == B)
return false;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
//===-------------------------------------
@ -749,9 +772,12 @@ public:
return DT->dominates(A, B);
}
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
bool dominates(const Instruction *A, const Instruction *B) const;
// dominates - Return true if Def dominates a use in User. This performs
// the special checks necessary if Def and User are in the same basic block.
// Note that Def doesn't dominate a use in Def itself!
bool dominates(const Instruction *Def, const Use &U) const;
bool dominates(const Instruction *Def, const Instruction *User) const;
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const {
return DT->properlyDominates(A, B);
@ -814,10 +840,12 @@ public:
DT->splitBlock(NewBB);
}
bool isReachableFromEntry(const BasicBlock* A) {
bool isReachableFromEntry(const BasicBlock* A) const {
return DT->isReachableFromEntry(A);
}
bool isReachableFromEntry(const Use &U) const;
virtual void releaseMemory() {
DT->releaseMemory();

View file

@ -166,10 +166,16 @@ public:
const_iterator end() const { return IVUses.end(); }
bool empty() const { return IVUses.empty(); }
bool isIVUserOrOperand(Instruction *Inst) const {
return Processed.count(Inst);
}
void print(raw_ostream &OS, const Module* = 0) const;
/// dump - This method is used for debugging.
void dump() const;
protected:
bool AddUsersImpl(Instruction *I, SmallPtrSet<Loop*,16> &SimpleLoopNests);
};
Pass *createIVUsersPass();

View file

@ -14,171 +14,118 @@
#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 <cassert>
#include <climits>
#include <vector>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Analysis/CodeMetrics.h"
namespace llvm {
class Value;
class Function;
class BasicBlock;
class CallSite;
template<class PtrType, unsigned SmallSize>
class SmallPtrSet;
class TargetData;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
const int InstrCost = 5;
const int IndirectCallBonus = -100;
const int IndirectCallThreshold = 100;
const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
}
/// InlineCost - Represent 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.
/// \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 Kind {
Value,
Always,
Never
enum SentinelValues {
AlwaysInlineCost = INT_MIN,
NeverInlineCost = INT_MAX
};
// This is a do-it-yourself implementation of
// int Cost : 30;
// unsigned Type : 2;
// We used to use bitfields, but they were sometimes miscompiled (PR3822).
enum { TYPE_BITS = 2 };
enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS };
unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS;
/// \brief The estimated cost of inlining this callsite.
const int Cost;
Kind getType() const {
return Kind(TypedCost >> COST_BITS);
}
/// \brief The adjusted threshold against which this cost was computed.
const int Threshold;
int getCost() const {
// Sign-extend the bottom COST_BITS bits.
return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS;
}
// Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, int Threshold)
: Cost(Cost), Threshold(Threshold) {}
InlineCost(int C, int T) {
TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS);
assert(getCost() == C && "Cost exceeds InlineCost precision");
}
public:
static InlineCost get(int Cost) { return InlineCost(Cost, Value); }
static InlineCost getAlways() { return InlineCost(0, Always); }
static InlineCost getNever() { return InlineCost(0, Never); }
bool isVariable() const { return getType() == Value; }
bool isAlways() const { return getType() == Always; }
bool isNever() const { return getType() == Never; }
/// getValue() - Return a "variable" inline cost's amount. It is
/// an error to call this on an "always" or "never" InlineCost.
int getValue() const {
assert(getType() == Value && "Invalid access of InlineCost");
return getCost();
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 {
struct ArgInfo {
public:
unsigned ConstantWeight;
unsigned AllocaWeight;
ArgInfo(unsigned CWeight, unsigned AWeight)
: ConstantWeight(CWeight), AllocaWeight(AWeight)
{}
};
struct FunctionInfo {
CodeMetrics Metrics;
/// ArgumentWeights - Each formal argument of the function is inspected to
/// see if it is used in any contexts where making it a constant or alloca
/// would reduce the code size. If so, we add some value to the argument
/// entry here.
std::vector<ArgInfo> ArgumentWeights;
/// analyzeFunction - Add information about the specified function
/// to the current structure.
void analyzeFunction(Function *F, const TargetData *TD);
/// NeverInline - Returns true if the function should never be
/// inlined into any caller.
bool NeverInline();
};
// The Function* for a function can be changed (by ArgumentPromotion);
// the ValueMap will update itself when this happens.
ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
// TargetData if available, or null.
const TargetData *TD;
int CountBonusForConstant(Value *V, Constant *C = NULL);
int ConstantFunctionBonus(CallSite CS, Constant *C);
int getInlineSize(CallSite CS, Function *Callee);
int getInlineBonuses(CallSite CS, Function *Callee);
public:
InlineCostAnalyzer(): TD(0) {}
void setTargetData(const TargetData *TData) { TD = TData; }
/// getInlineCost - The heuristic used to determine if we should inline the
/// function call or not.
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
///
InlineCost getInlineCost(CallSite CS,
SmallPtrSet<const Function *, 16> &NeverInline);
/// 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. The
/// result assumes that the inlined version will always be used. You should
/// weight it yourself in cases where this callee will not always be called.
InlineCost getInlineCost(CallSite CS,
Function *Callee,
SmallPtrSet<const Function *, 16> &NeverInline);
/// getSpecializationBonus - The heuristic used to determine the per-call
/// performance boost for using a specialization of Callee with argument
/// SpecializedArgNos replaced by a constant.
int getSpecializationBonus(Function *Callee,
SmallVectorImpl<unsigned> &SpecializedArgNo);
/// getSpecializationCost - The heuristic used to determine the code-size
/// impact of creating a specialized version of Callee with argument
/// SpecializedArgNo replaced by a constant.
InlineCost getSpecializationCost(Function *Callee,
SmallVectorImpl<unsigned> &SpecializedArgNo);
/// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
/// higher threshold to determine if the function call should be inlined.
float getInlineFudgeFactor(CallSite CS);
/// resetCachedFunctionInfo - erase any cached cost info for this function.
void resetCachedCostInfo(Function* Caller) {
CachedFunctionInfo[Caller] = FunctionInfo();
}
/// growCachedCostInfo - update the cached cost info for Caller after Callee
/// has been inlined. If Callee is NULL it means a dead call has been
/// eliminated.
void growCachedCostInfo(Function* Caller, Function* Callee);
/// clear - empty the cache of inline costs
void clear();
/// 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);
};
/// callIsSmall - If a call is likely to lower to a single target instruction,

View file

@ -20,147 +20,198 @@
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
namespace llvm {
class DominatorTree;
class Instruction;
class Value;
class TargetData;
template<typename T>
class ArrayRef;
class DominatorTree;
class Instruction;
class TargetData;
class TargetLibraryInfo;
class Type;
class Value;
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0);
const TargetData *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 TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// 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 TargetData *TD = 0,
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// 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 TargetData *TD = 0, const DominatorTree *DT = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0, const DominatorTree *DT=0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// 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 TargetData *TD = 0,
const TargetData *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 TargetData *TD = 0,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(ArrayRef<Value *> Ops,
const TargetData *TD = 0, const DominatorTree *DT = 0);
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
//=== Helper functions for higher up the class hierarchy.
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0, const DominatorTree *DT = 0);
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// 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 TargetData *TD = 0, const DominatorTree *DT = 0);
const TargetData *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 TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then
/// delete the From instruction. In addition to a basic RAUW, this does a
/// recursive simplification of the updated instructions. This catches
/// things where one simplification exposes other opportunities. This only
/// simplifies and deletes scalar operations, it does not change the CFG.
/// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses
/// recursively.
///
void ReplaceAndSimplifyAllUses(Instruction *From, Value *To,
const TargetData *TD = 0,
const DominatorTree *DT = 0);
/// This first performs a normal RAUW of I with SimpleV. It then recursively
/// attempts to simplify those users updated by the operation. The 'I'
/// instruction must not be equal to the simplified value 'SimpleV'.
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Recursively attempt to simplify an instruction.
///
/// This routine uses SimplifyInstruction to simplify 'I', and if successful
/// replaces uses of 'I' with the simplified value. It then recurses on each
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
const TargetData *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm
#endif

View file

@ -101,14 +101,14 @@ public:
IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
OrigContainer = M;
if (!ProcessInterval(&M->front())) {
assert(0 && "ProcessInterval should never fail for first interval!");
llvm_unreachable("ProcessInterval should never fail for first interval!");
}
}
IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
OrigContainer = &IP;
if (!ProcessInterval(IP.getRootInterval())) {
assert(0 && "ProcessInterval should never fail for first interval!");
llvm_unreachable("ProcessInterval should never fail for first interval!");
}
}

View file

@ -20,12 +20,14 @@
namespace llvm {
class Constant;
class TargetData;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
class TargetData *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&); // DO NOT IMPLEMENT.
void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
@ -68,9 +70,7 @@ public:
// Implementation boilerplate.
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void releaseMemory();
virtual bool runOnFunction(Function &F);
};

View file

@ -20,6 +20,7 @@ namespace llvm {
class AliasAnalysis;
class TargetData;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
/// from this value cannot trap. If it is not obviously safe to load from the
@ -41,10 +42,15 @@ bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
/// MaxInstsToScan specifies the maximum instructions to scan in the block.
/// If it is set to 0, it will scan the whole block. You can also optionally
/// specify an alias analysis implementation, which makes this more precise.
///
/// If TBAATag is non-null and a load or store is found, the TBAA tag from the
/// load or store is recorded there. If there is no TBAA tag or if no access
/// is found, it is left unmodified.
Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan = 6,
AliasAnalysis *AA = 0);
AliasAnalysis *AA = 0,
MDNode **TBAATag = 0);
}

View file

@ -23,7 +23,6 @@
// * whether or not a particular block branches out of the loop
// * the successor blocks of the loop
// * the loop depth
// * the trip count
// * etc...
//
//===----------------------------------------------------------------------===//
@ -416,14 +415,26 @@ public:
#ifndef NDEBUG
assert(!Blocks.empty() && "Loop header is missing");
// Setup for using a depth-first iterator to visit every block in the loop.
SmallVector<BlockT*, 8> ExitBBs;
getExitBlocks(ExitBBs);
llvm::SmallPtrSet<BlockT*, 8> VisitSet;
VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
BI = df_ext_begin(getHeader(), VisitSet),
BE = df_ext_end(getHeader(), VisitSet);
// Keep track of the number of BBs visited.
unsigned NumVisited = 0;
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
std::sort(LoopBBs.begin(), LoopBBs.end());
// Check the individual blocks.
for (block_iterator I = block_begin(), E = block_end(); I != E; ++I) {
BlockT *BB = *I;
for ( ; BI != BE; ++BI) {
BlockT *BB = *BI;
bool HasInsideLoopSuccs = false;
bool HasInsideLoopPreds = false;
SmallVector<BlockT *, 2> OutsideLoopPreds;
@ -440,7 +451,7 @@ public:
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
PI != PE; ++PI) {
typename InvBlockTraits::NodeType *N = *PI;
BlockT *N = *PI;
if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N))
HasInsideLoopPreds = true;
else
@ -464,8 +475,12 @@ public:
assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
assert(BB != getHeader()->getParent()->begin() &&
"Loop contains function entry block!");
NumVisited++;
}
assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
// Check the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)
// Each block in each subloop should be contained within this loop.
@ -571,37 +586,6 @@ public:
///
PHINode *getCanonicalInductionVariable() const;
/// getTripCount - Return a loop-invariant LLVM value indicating the number of
/// times the loop will be executed. Note that this means that the backedge
/// of the loop executes N-1 times. If the trip-count cannot be determined,
/// this returns null.
///
/// The IndVarSimplify pass transforms loops to have a form that this
/// function easily understands.
///
Value *getTripCount() const;
/// getSmallConstantTripCount - Returns the trip count of this loop as a
/// normal unsigned value, if possible. Returns 0 if the trip count is unknown
/// of not constant. Will also return 0 if the trip count is very large
/// (>= 2^32)
///
/// The IndVarSimplify pass transforms loops to have a form that this
/// function easily understands.
///
unsigned getSmallConstantTripCount() const;
/// getSmallConstantTripMultiple - Returns the largest constant divisor of the
/// trip count of this loop as a normal unsigned value, if possible. This
/// means that the actual trip count is always a multiple of the returned
/// value (don't forget the trip count could very well be zero as well!).
///
/// Returns 1 if the trip count is unknown or not guaranteed to be the
/// multiple of a constant (which is also the case if the trip count is simply
/// constant, use getSmallConstantTripCount for that case), Will also return 1
/// if the trip count is very large (>= 2^32).
unsigned getSmallConstantTripMultiple() const;
/// isLCSSAForm - Return true if the Loop is in LCSSA form
bool isLCSSAForm(DominatorTree &DT) const;
@ -610,6 +594,9 @@ public:
/// normal form.
bool isLoopSimplifyForm() const;
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
bool isSafeToClone() const;
/// hasDedicatedExits - Return true if no exit block for the loop
/// has a predecessor that is outside the loop.
bool hasDedicatedExits() const;
@ -671,9 +658,7 @@ public:
/// block is in no loop (for example the entry node), null is returned.
///
LoopT *getLoopFor(const BlockT *BB) const {
typename DenseMap<BlockT *, LoopT *>::const_iterator I=
BBMap.find(const_cast<BlockT*>(BB));
return I != BBMap.end() ? I->second : 0;
return BBMap.lookup(const_cast<BlockT*>(BB));
}
/// operator[] - same as getLoopFor...
@ -712,9 +697,7 @@ public:
/// the loop hierarchy tree.
void changeLoopFor(BlockT *BB, LoopT *L) {
if (!L) {
typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
if (I != BBMap.end())
BBMap.erase(I);
BBMap.erase(BB);
return;
}
BBMap[BB] = L;
@ -771,7 +754,7 @@ public:
}
LoopT *ConsiderForLoop(BlockT *BB, DominatorTreeBase<BlockT> &DT) {
if (BBMap.find(BB) != BBMap.end()) return 0;// Haven't processed this node?
if (BBMap.count(BB)) return 0; // Haven't processed this node?
std::vector<BlockT *> TodoStack;
@ -782,7 +765,8 @@ public:
InvBlockTraits::child_begin(BB), E = InvBlockTraits::child_end(BB);
I != E; ++I) {
typename InvBlockTraits::NodeType *N = *I;
if (DT.dominates(BB, N)) // If BB dominates its predecessor...
// If BB dominates its predecessor...
if (DT.dominates(BB, N) && DT.isReachableFromEntry(N))
TodoStack.push_back(N);
}
@ -792,14 +776,12 @@ public:
LoopT *L = new LoopT(BB);
BBMap[BB] = L;
BlockT *EntryBlock = BB->getParent()->begin();
while (!TodoStack.empty()) { // Process all the nodes in the loop
BlockT *X = TodoStack.back();
TodoStack.pop_back();
if (!L->contains(X) && // As of yet unprocessed??
DT.dominates(EntryBlock, X)) { // X is reachable from entry block?
DT.isReachableFromEntry(X)) {
// Check to see if this block already belongs to a loop. If this occurs
// then we have a case where a loop that is supposed to be a child of
// the current loop was processed before the current loop. When this

View file

@ -324,6 +324,7 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
TargetData *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
MemoryDependenceAnalysis();
@ -430,6 +431,9 @@ namespace llvm {
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
AliasAnalysis::ModRefResult
getModRefInfo(const Instruction *Inst, const AliasAnalysis::Location &Loc);
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;

View file

@ -20,7 +20,8 @@
namespace llvm {
class DominatorTree;
class TargetData;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
/// As we walk "up" the CFG through predecessors, we need to ensure that the
/// address we're tracking is kept up to date. For example, if we're analyzing
@ -37,11 +38,14 @@ class PHITransAddr {
/// TD - The target data we are playing with if known, otherwise null.
const TargetData *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) {
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);

View file

@ -22,6 +22,7 @@
#define LLVM_ANALYSIS_PROFILEINFO_H
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@ -85,13 +86,11 @@ namespace llvm {
// getFunction() - Returns the Function for an Edge, checking for validity.
static const FType* getFunction(Edge e) {
if (e.first) {
if (e.first)
return e.first->getParent();
} else if (e.second) {
if (e.second)
return e.second->getParent();
}
assert(0 && "Invalid ProfileInfo::Edge");
return (const FType*)0;
llvm_unreachable("Invalid ProfileInfo::Edge");
}
// getEdge() - Creates an Edge from two BasicBlocks.

View file

@ -681,7 +681,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
if (Node.isSubRegion())
return OS << Node.getNodeAs<Region>()->getNameStr();
else
return OS << Node.getNodeAs<BasicBlock>()->getNameStr();
return OS << Node.getNodeAs<BasicBlock>()->getName();
}
} // End llvm namespace
#endif

View file

@ -41,6 +41,7 @@ namespace llvm {
class Type;
class ScalarEvolution;
class TargetData;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
class LoopInfo;
@ -118,6 +119,10 @@ namespace llvm {
///
bool isAllOnesValue() const;
/// isNonConstantNegative - Return true if the specified scev is negated,
/// but not a constant.
bool isNonConstantNegative() const;
/// print - Print out the internal representation of this scalar to the
/// specified stream. This should really only be used for debugging
/// purposes.
@ -135,7 +140,7 @@ namespace llvm {
ID = X.FastID;
}
static bool Equals(const SCEV &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) {
unsigned IDHash, FoldingSetNodeID &TempID) {
return ID == X.FastID;
}
static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
@ -224,6 +229,10 @@ namespace llvm {
///
TargetData *TD;
/// TLI - The target library information for the target we are targeting.
///
TargetLibraryInfo *TLI;
/// DT - The dominator tree.
///
DominatorTree *DT;
@ -721,16 +730,21 @@ namespace llvm {
const SCEV *LHS, const SCEV *RHS);
/// getSmallConstantTripCount - Returns the maximum trip count of this loop
/// as a normal unsigned value, if possible. Returns 0 if the trip count is
/// unknown or not constant.
unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitBlock);
/// as a normal unsigned value. Returns 0 if the trip count is unknown or
/// not constant. This "trip count" assumes that control exits via
/// ExitingBlock. More precisely, it is the number of times that control may
/// reach ExitingBlock before taking the branch. For loops with multiple
/// exits, it may not be the number times that the loop header executes if
/// the loop exits prematurely via another branch.
unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock);
/// getSmallConstantTripMultiple - Returns the largest constant divisor of
/// the trip count of this loop as a normal unsigned value, if
/// possible. This means that the actual trip count is always a multiple of
/// the returned value (don't forget the trip count could very well be zero
/// as well!).
unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitBlock);
/// as well!). As explained in the comments for getSmallConstantTripCount,
/// this assumes that control exits the loop via ExitingBlock.
unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock);
// getExitCount - Get the expression for the number of loop iterations for
// which this loop is guaranteed not to exit via ExitingBlock. Otherwise

View file

@ -22,6 +22,8 @@
#include <set>
namespace llvm {
class TargetLowering;
/// SCEVExpander - This class uses information about analyze scalars to
/// rewrite expressions in canonical form.
///
@ -58,6 +60,9 @@ namespace llvm {
/// insert the IV increment at this position.
Instruction *IVIncInsertPos;
/// Phis that complete an IV chain. Reuse
std::set<AssertingVH<PHINode> > ChainedPhis;
/// CanonicalMode - When true, expressions are expanded in "canonical"
/// form. In particular, addrecs are expanded as arithmetic based on
/// a canonical induction variable. When false, expression are expanded
@ -100,6 +105,7 @@ namespace llvm {
InsertedExpressions.clear();
InsertedValues.clear();
InsertedPostIncValues.clear();
ChainedPhis.clear();
}
/// getOrInsertCanonicalInductionVariable - This method returns the
@ -108,14 +114,18 @@ namespace llvm {
/// starts at zero and steps by one on each iteration.
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
/// hoistStep - Utility for hoisting an IV increment.
static bool hoistStep(Instruction *IncV, Instruction *InsertPos,
const DominatorTree *DT);
/// getIVIncOperand - Return the induction variable increment's IV operand.
Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
bool allowScale);
/// hoistIVInc - Utility for hoisting an IV increment.
bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
/// replaceCongruentIVs - replace congruent phis with their most canonical
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts);
SmallVectorImpl<WeakVH> &DeadInsts,
const TargetLowering *TLI = NULL);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
@ -161,6 +171,16 @@ namespace llvm {
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I) || InsertedPostIncValues.count(I);
}
void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
private:
LLVMContext &getContext() const { return SE.getContext(); }
@ -195,13 +215,6 @@ namespace llvm {
/// result will be expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV *SH, Type *Ty = 0);
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I) || InsertedPostIncValues.count(I);
}
/// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
const Loop *getRelevantLoop(const SCEV *);
@ -244,6 +257,8 @@ namespace llvm {
const Loop *L,
Type *ExpandTy,
Type *IntTy);
Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
Type *ExpandTy, Type *IntTy, bool useSubtract);
};
}

View file

@ -491,7 +491,6 @@ namespace llvm {
RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
return RetVal();
}
};
}

View file

@ -17,15 +17,15 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
template <typename T> class SmallVectorImpl;
class Value;
class Instruction;
class APInt;
class TargetData;
class StringRef;
class MDNode;
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bit sets. This code only analyzes bits in Mask, in order to short-circuit
@ -36,10 +36,10 @@ namespace llvm {
/// where V is a vector, the mask, known zero, and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, const APInt &Mask, APInt &KnownZero,
APInt &KnownOne, const TargetData *TD = 0,
unsigned Depth = 0);
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
const TargetData *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
@ -48,8 +48,10 @@ namespace llvm {
/// isPowerOfTwo - Return true if the given value is known to have exactly one
/// bit set when defined. For vectors return true if every element is known to
/// be a power of two when defined. Supports values with integer or pointer
/// type and vectors of integers.
bool isPowerOfTwo(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
/// type and vectors of integers. If 'OrZero' is set then returns true if the
/// given value is either a power of two or zero.
bool isPowerOfTwo(Value *V, const TargetData *TD = 0, bool OrZero = false,
unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
@ -123,16 +125,15 @@ namespace llvm {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
/// GetConstantStringInfo - This function computes the length of a
/// getConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V. If successful, it returns true
/// and returns the string in Str. If unsuccessful, it returns false. If
/// StopAtNul is set to true (the default), the returned string is truncated
/// by a nul character in the global. If StopAtNul is false, the nul
/// character is included in the result string.
bool GetConstantStringInfo(const Value *V, std::string &Str,
uint64_t Offset = 0,
bool StopAtNul = true);
/// and returns the string in Str. If unsuccessful, it returns false. This
/// does not include the trailing nul character by default. If TrimAtNul is
/// set to false, then this returns any trailing nul characters as well as any
/// other characters that come after it.
bool getConstantStringInfo(const Value *V, StringRef &Str,
uint64_t Offset = 0, bool TrimAtNul = true);
/// GetStringLength - If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
uint64_t GetStringLength(Value *V);
@ -154,6 +155,27 @@ namespace llvm {
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
/// isSafeToSpeculativelyExecute - Return true if the instruction does not
/// have any effects besides calculating the result and does not have
/// undefined behavior.
///
/// This method never returns true for an instruction that returns true for
/// mayHaveSideEffects; however, this method also does some other checks in
/// addition. It checks for undefined behavior, like dividing by zero or
/// loading from an invalid pointer (but not for undefined results, like a
/// shift with a shift amount larger than the width of the result). It checks
/// for malloc and alloca because speculatively executing them might cause a
/// memory leak. It also returns false for instructions related to control
/// flow, specifically terminators and PHI nodes.
///
/// This method only looks at the instruction itself and its operands, so if
/// this method returns true, it is safe to move the instruction as long as
/// the correct dominance relationships for the operands and users hold.
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
const TargetData *TD = 0);
} // end namespace llvm
#endif

View file

@ -30,6 +30,7 @@ template<typename ValueSubClass, typename ItemParentClass>
/// the function was called with.
/// @brief LLVM Argument representation
class Argument : public Value, public ilist_node<Argument> {
virtual void anchor();
Function *Parent;
friend class SymbolTableListTraits<Argument, Function>;

View file

@ -22,7 +22,7 @@ namespace llvm {
class Function;
class BasicBlock;
class Instruction;
class raw_ostream;
class Value;
class formatted_raw_ostream;
class AssemblyAnnotationWriter {
@ -32,30 +32,30 @@ public:
/// emitFunctionAnnot - This may be implemented to emit a string right before
/// the start of a function.
virtual void emitFunctionAnnot(const Function *F,
formatted_raw_ostream &OS) {}
virtual void emitFunctionAnnot(const Function *,
formatted_raw_ostream &) {}
/// emitBasicBlockStartAnnot - This may be implemented to emit a string right
/// after the basic block label, but before the first instruction in the
/// block.
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
formatted_raw_ostream &OS) {
virtual void emitBasicBlockStartAnnot(const BasicBlock *,
formatted_raw_ostream &) {
}
/// emitBasicBlockEndAnnot - This may be implemented to emit a string right
/// after the basic block.
virtual void emitBasicBlockEndAnnot(const BasicBlock *BB,
formatted_raw_ostream &OS) {
virtual void emitBasicBlockEndAnnot(const BasicBlock *,
formatted_raw_ostream &) {
}
/// emitInstructionAnnot - This may be implemented to emit a string right
/// before an instruction is emitted.
virtual void emitInstructionAnnot(const Instruction *I,
formatted_raw_ostream &OS) {}
virtual void emitInstructionAnnot(const Instruction *,
formatted_raw_ostream &) {}
/// printInfoComment - This may be implemented to emit a comment to the
/// right of an instruction or global value.
virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {}
virtual void printInfoComment(const Value &, formatted_raw_ostream &) {}
};
} // End llvm namespace

View file

@ -21,7 +21,6 @@ namespace llvm {
class Module;
class MemoryBuffer;
class SMDiagnostic;
class raw_ostream;
class LLVMContext;
/// This function is the main interface to the LLVM Assembly Parser. It parses

View file

@ -19,7 +19,6 @@
namespace llvm {
class Type;
class Module;
class Value;
class raw_ostream;

View file

@ -22,8 +22,66 @@
namespace llvm {
class Type;
namespace Attribute {
/// We use this proxy POD type to allow constructing Attributes constants
/// using initializer lists. Do not use this class directly.
struct AttrConst {
uint64_t v;
AttrConst operator | (const AttrConst Attrs) const {
AttrConst Res = {v | Attrs.v};
return Res;
}
AttrConst operator ~ () const {
AttrConst Res = {~v};
return Res;
}
};
} // namespace Attribute
/// Attributes - A bitset of attributes.
typedef unsigned Attributes;
class Attributes {
public:
Attributes() : Bits(0) { }
explicit Attributes(uint64_t Val) : Bits(Val) { }
/*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { }
// This is a "safe bool() operator".
operator const void *() const { return Bits ? this : 0; }
bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
Attributes &operator = (const Attributes &Attrs) {
Bits = Attrs.Bits;
return *this;
}
bool operator == (const Attributes &Attrs) const {
return Bits == Attrs.Bits;
}
bool operator != (const Attributes &Attrs) const {
return Bits != Attrs.Bits;
}
Attributes operator | (const Attributes &Attrs) const {
return Attributes(Bits | Attrs.Bits);
}
Attributes operator & (const Attributes &Attrs) const {
return Attributes(Bits & Attrs.Bits);
}
Attributes operator ^ (const Attributes &Attrs) const {
return Attributes(Bits ^ Attrs.Bits);
}
Attributes &operator |= (const Attributes &Attrs) {
Bits |= Attrs.Bits;
return *this;
}
Attributes &operator &= (const Attributes &Attrs) {
Bits &= Attrs.Bits;
return *this;
}
Attributes operator ~ () const { return Attributes(~Bits); }
uint64_t Raw() const { return Bits; }
private:
// Currently, we need less than 64 bits.
uint64_t Bits;
};
namespace Attribute {
@ -33,44 +91,55 @@ namespace Attribute {
/// results or the function itself.
/// @brief Function attributes.
const Attributes None = 0; ///< No attributes have been set
const Attributes ZExt = 1<<0; ///< Zero extended before/after call
const Attributes SExt = 1<<1; ///< Sign extended before/after call
const Attributes NoReturn = 1<<2; ///< Mark the function as not returning
const Attributes InReg = 1<<3; ///< Force argument to be passed in register
const Attributes StructRet = 1<<4; ///< Hidden pointer to structure to return
const Attributes NoUnwind = 1<<5; ///< Function doesn't unwind stack
const Attributes NoAlias = 1<<6; ///< Considered to not alias after call
const Attributes ByVal = 1<<7; ///< Pass structure by value
const Attributes Nest = 1<<8; ///< Nested function static chain
const Attributes ReadNone = 1<<9; ///< Function does not access memory
const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
const Attributes NoInline = 1<<11; ///< inline=never
const Attributes AlwaysInline = 1<<12; ///< inline=always
const Attributes OptimizeForSize = 1<<13; ///< opt_size
const Attributes StackProtect = 1<<14; ///< Stack protection.
const Attributes StackProtectReq = 1<<15; ///< Stack protection required.
const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits)
// We declare AttrConst objects that will be used throughout the code
// and also raw uint64_t objects with _i suffix to be used below for other
// constant declarations. This is done to avoid static CTORs and at the same
// time to keep type-safety of Attributes.
#define DECLARE_LLVM_ATTRIBUTE(name, value) \
const uint64_t name##_i = value; \
const AttrConst name = {value};
DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call
DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call
DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning
DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register
DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return
DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack
DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call
DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value
DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain
DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory
DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory
DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never
DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always
DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size
DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection.
DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required.
DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits)
// stored as log2 of alignment with +1 bias
// 0 means unaligned different from align 1
const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer
const Attributes NoRedZone = 1<<22; /// disable redzone
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
/// instructions.
const Attributes Naked = 1<<24; ///< Naked function
const Attributes InlineHint = 1<<25; ///< source said inlining was
///desirable
const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
///function (3 bits) stored as log2
///of alignment with +1 bias
///0 means unaligned (different from
///alignstack(1))
const Attributes ReturnsTwice = 1<<29; ///< Function can return twice
const Attributes UWTable = 1<<30; ///< Function must be in a unwind
///table
const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer
DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone
DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point
/// instructions.
DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function
DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was
///desirable
DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for
///function (3 bits) stored as log2
///of alignment with +1 bias
///0 means unaligned (different from
///alignstack= {1))
DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice
DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind
///table
DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on.
#undef DECLARE_LLVM_ATTRIBUTE
/// Note that uwtable is about the ABI or the user mandating an entry in the
/// unwind table. The nounwind attribute is about an exception passing by the
@ -85,24 +154,26 @@ const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or
/// uwtable + nounwind = Needs an entry because the ABI says so.
/// @brief Attributes that only apply to function parameters.
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
const AttrConst ParameterOnly = {ByVal_i | Nest_i |
StructRet_i | NoCapture_i};
/// @brief Attributes that may be applied to the function itself. These cannot
/// be used on return values or function parameters.
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
UWTable | NonLazyBind | ReturnsTwice;
const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
Naked_i | InlineHint_i | StackAlignment_i |
UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
const AttrConst VarArgsIncompatible = {StructRet_i};
/// @brief Attributes that are mutually incompatible.
const Attributes MutuallyIncompatible[4] = {
ByVal | InReg | Nest | StructRet,
ZExt | SExt,
ReadNone | ReadOnly,
NoInline | AlwaysInline
const AttrConst MutuallyIncompatible[4] = {
{ByVal_i | InReg_i | Nest_i | StructRet_i},
{ZExt_i | SExt_i},
{ReadNone_i | ReadOnly_i},
{NoInline_i | AlwaysInline_i}
};
/// @brief Which attributes cannot be applied to a type.
@ -113,20 +184,20 @@ Attributes typeIncompatible(Type *Ty);
inline Attributes constructAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return 0;
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x40000000 && "Alignment too large.");
return (Log2_32(i)+1) << 16;
return Attributes((Log2_32(i)+1) << 16);
}
/// This returns the alignment field of an attribute as a byte alignment value.
inline unsigned getAlignmentFromAttrs(Attributes A) {
Attributes Align = A & Attribute::Alignment;
if (Align == 0)
if (!Align)
return 0;
return 1U << ((Align >> 16) - 1);
return 1U << ((Align.Raw() >> 16) - 1);
}
/// This turns an int stack alignment (which must be a power of 2) into
@ -134,21 +205,21 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
inline Attributes constructStackAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return 0;
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x100 && "Alignment too large.");
return (Log2_32(i)+1) << 26;
return Attributes((Log2_32(i)+1) << 26);
}
/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
inline unsigned getStackAlignmentFromAttrs(Attributes A) {
Attributes StackAlign = A & Attribute::StackAlignment;
if (StackAlign == 0)
if (!StackAlign)
return 0;
return 1U << ((StackAlign >> 26) - 1);
return 1U << ((StackAlign.Raw() >> 26) - 1);
}
@ -242,7 +313,7 @@ public:
/// paramHasAttr - Return true if the specified parameter index has the
/// specified attribute set.
bool paramHasAttr(unsigned Idx, Attributes Attr) const {
return (getAttributes(Idx) & Attr) != 0;
return getAttributes(Idx) & Attr;
}
/// getParamAlignment - Return the alignment for the specified function

View file

@ -39,14 +39,6 @@ namespace llvm {
/// This checks for global variables which should be upgraded. It returns true
/// if it requires upgrading.
bool UpgradeGlobalVariable(GlobalVariable *GV);
/// This function checks debug info intrinsics. If an intrinsic is invalid
/// then this function simply removes the intrinsic.
void CheckDebugInfoIntrinsics(Module *M);
/// This function upgrades the old pre-3.0 exception handling system to the
/// new one. N.B. This will be removed in 3.1.
void UpgradeExceptionHandling(Module *M);
} // End llvm namespace
#endif

View file

@ -110,12 +110,6 @@ public:
const Function *getParent() const { return Parent; }
Function *getParent() { return Parent; }
/// use_back - Specialize the methods defined in Value, as we know that an
/// BasicBlock can only be used by Users (specifically terminators
/// and BlockAddress's).
User *use_back() { return cast<User>(*use_begin());}
const User *use_back() const { return cast<User>(*use_begin());}
/// getTerminator() - If this is a well formed basic block, then this returns
/// a pointer to the terminator instruction. If it is not, then you get a
/// null pointer back.
@ -274,6 +268,7 @@ public:
/// getLandingPadInst() - Return the landingpad instruction associated with
/// the landing pad.
LandingPadInst *getLandingPadInst();
const LandingPadInst *getLandingPadInst() const;
private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress

View file

@ -394,7 +394,7 @@ class Archive {
/// @brief Look up multiple symbols in the archive.
bool findModulesDefiningSymbols(
std::set<std::string>& symbols, ///< Symbols to be sought
std::set<Module*>& modules, ///< The modules matching \p symbols
SmallVectorImpl<Module*>& modules, ///< The modules matching \p symbols
std::string* ErrMessage ///< Error msg storage, if non-zero
);

View file

@ -20,6 +20,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
@ -114,7 +115,6 @@ public:
bool hasEncodingData() const { return hasEncodingData(getEncoding()); }
static bool hasEncodingData(Encoding E) {
switch (E) {
default: assert(0 && "Unknown encoding");
case Fixed:
case VBR:
return true;
@ -123,6 +123,7 @@ public:
case Blob:
return false;
}
llvm_unreachable("Invalid encoding");
}
/// isChar6 - Return true if this character is legal in the Char6 encoding.
@ -139,8 +140,7 @@ public:
if (C >= '0' && C <= '9') return C-'0'+26+26;
if (C == '.') return 62;
if (C == '_') return 63;
assert(0 && "Not a value Char6 character!");
return 0;
llvm_unreachable("Not a value Char6 character!");
}
static char DecodeChar6(unsigned V) {
@ -150,17 +150,18 @@ public:
if (V < 26+26+10) return V-26-26+'0';
if (V == 62) return '.';
if (V == 63) return '_';
assert(0 && "Not a value Char6 character!");
return ' ';
llvm_unreachable("Not a value Char6 character!");
}
};
template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=true; };
/// BitCodeAbbrev - This class represents an abbreviation record. An
/// abbreviation allows a complex record that has redundancy to be stored in a
/// specialized format instead of the fully-general, fully-vbr, format.
class BitCodeAbbrev {
SmallVector<BitCodeAbbrevOp, 8> OperandList;
SmallVector<BitCodeAbbrevOp, 32> OperandList;
unsigned char RefCount; // Number of things using this.
~BitCodeAbbrev() {}
public:

View file

@ -15,7 +15,10 @@
#ifndef BITSTREAM_READER_H
#define BITSTREAM_READER_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/StreamableMemoryObject.h"
#include <climits>
#include <string>
#include <vector>
@ -36,9 +39,7 @@ public:
std::vector<std::pair<unsigned, std::string> > RecordNames;
};
private:
/// FirstChar/LastChar - This remembers the first and last bytes of the
/// stream.
const unsigned char *FirstChar, *LastChar;
OwningPtr<StreamableMemoryObject> BitcodeBytes;
std::vector<BlockInfo> BlockInfoRecords;
@ -47,10 +48,10 @@ private:
/// uses this.
bool IgnoreBlockInfoNames;
BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED
void operator=(const BitstreamReader&); // NOT IMPLEMENTED
BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT
void operator=(const BitstreamReader&); // DO NOT IMPLEMENT
public:
BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) {
BitstreamReader() : IgnoreBlockInfoNames(true) {
}
BitstreamReader(const unsigned char *Start, const unsigned char *End) {
@ -58,12 +59,17 @@ public:
init(Start, End);
}
void init(const unsigned char *Start, const unsigned char *End) {
FirstChar = Start;
LastChar = End;
assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
BitstreamReader(StreamableMemoryObject *bytes) {
BitcodeBytes.reset(bytes);
}
void init(const unsigned char *Start, const unsigned char *End) {
assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
}
StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
~BitstreamReader() {
// Free the BlockInfoRecords.
while (!BlockInfoRecords.empty()) {
@ -75,9 +81,6 @@ public:
BlockInfoRecords.pop_back();
}
}
const unsigned char *getFirstChar() const { return FirstChar; }
const unsigned char *getLastChar() const { return LastChar; }
/// CollectBlockInfoNames - This is called by clients that want block/record
/// name information.
@ -122,7 +125,7 @@ public:
class BitstreamCursor {
friend class Deserializer;
BitstreamReader *BitStream;
const unsigned char *NextChar;
size_t NextChar;
/// CurWord - This is the current data we have pulled from the stream but have
/// not returned to the client.
@ -156,8 +159,7 @@ public:
}
explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) {
NextChar = R.getFirstChar();
assert(NextChar && "Bitstream not initialized yet");
NextChar = 0;
CurWord = 0;
BitsInCurWord = 0;
CurCodeSize = 2;
@ -167,8 +169,7 @@ public:
freeState();
BitStream = &R;
NextChar = R.getFirstChar();
assert(NextChar && "Bitstream not initialized yet");
NextChar = 0;
CurWord = 0;
BitsInCurWord = 0;
CurCodeSize = 2;
@ -225,13 +226,39 @@ public:
/// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
bool AtEndOfStream() const {
return NextChar == BitStream->getLastChar() && BitsInCurWord == 0;
bool isEndPos(size_t pos) {
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
}
bool canSkipToPos(size_t pos) const {
// pos can be skipped to if it is a valid address or one byte past the end.
return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
static_cast<uint64_t>(pos - 1));
}
unsigned char getByte(size_t pos) {
uint8_t byte = -1;
BitStream->getBitcodeBytes().readByte(pos, &byte);
return byte;
}
uint32_t getWord(size_t pos) {
uint8_t buf[sizeof(uint32_t)];
memset(buf, 0xFF, sizeof(buf));
BitStream->getBitcodeBytes().readBytes(pos,
sizeof(buf),
buf,
NULL);
return *reinterpret_cast<support::ulittle32_t *>(buf);
}
bool AtEndOfStream() {
return isEndPos(NextChar) && BitsInCurWord == 0;
}
/// GetCurrentBitNo - Return the bit # of the bit we are reading.
uint64_t GetCurrentBitNo() const {
return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord;
return NextChar*CHAR_BIT - BitsInCurWord;
}
BitstreamReader *getBitStreamReader() {
@ -246,12 +273,10 @@ public:
void JumpToBit(uint64_t BitNo) {
uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()-
BitStream->getFirstChar()) &&
"Invalid location");
assert(canSkipToPos(ByteNo) && "Invalid location");
// Move the cursor to the right word.
NextChar = BitStream->getFirstChar()+ByteNo;
NextChar = ByteNo;
BitsInCurWord = 0;
CurWord = 0;
@ -272,7 +297,7 @@ public:
}
// If we run out of data, stop at the end of the stream.
if (NextChar == BitStream->getLastChar()) {
if (isEndPos(NextChar)) {
CurWord = 0;
BitsInCurWord = 0;
return 0;
@ -281,8 +306,7 @@ public:
unsigned R = CurWord;
// Read the next word from the stream.
CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) |
(NextChar[2] << 16) | (NextChar[3] << 24);
CurWord = getWord(NextChar);
NextChar += 4;
// Extract NumBits-BitsInCurWord from what we just read.
@ -376,9 +400,8 @@ public:
// Check that the block wasn't partially defined, and that the offset isn't
// bogus.
const unsigned char *const SkipTo = NextChar + NumWords*4;
if (AtEndOfStream() || SkipTo > BitStream->getLastChar() ||
SkipTo < BitStream->getFirstChar())
size_t SkipTo = NextChar + NumWords*4;
if (AtEndOfStream() || !canSkipToPos(SkipTo))
return true;
NextChar = SkipTo;
@ -409,8 +432,7 @@ public:
if (NumWordsP) *NumWordsP = NumWords;
// Validate that this block is sane.
if (CurCodeSize == 0 || AtEndOfStream() ||
NextChar+NumWords*4 > BitStream->getLastChar())
if (CurCodeSize == 0 || AtEndOfStream())
return true;
return false;
@ -455,10 +477,10 @@ private:
void ReadAbbreviatedField(const BitCodeAbbrevOp &Op,
SmallVectorImpl<uint64_t> &Vals) {
assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");
// Decode the value as we are commanded.
switch (Op.getEncoding()) {
default: assert(0 && "Unknown encoding!");
default: llvm_unreachable("Unknown encoding!");
case BitCodeAbbrevOp::Fixed:
Vals.push_back(Read((unsigned)Op.getEncodingData()));
break;
@ -512,24 +534,25 @@ public:
SkipToWord(); // 32-bit alignment
// Figure out where the end of this blob will be including tail padding.
const unsigned char *NewEnd = NextChar+((NumElts+3)&~3);
size_t NewEnd = NextChar+((NumElts+3)&~3);
// If this would read off the end of the bitcode file, just set the
// record to empty and return.
if (NewEnd > BitStream->getLastChar()) {
if (!canSkipToPos(NewEnd)) {
Vals.append(NumElts, 0);
NextChar = BitStream->getLastChar();
NextChar = BitStream->getBitcodeBytes().getExtent();
break;
}
// Otherwise, read the number of bytes. If we can return a reference to
// the data, do so to avoid copying it.
if (BlobStart) {
*BlobStart = (const char*)NextChar;
*BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer(
NextChar, NumElts);
*BlobLen = NumElts;
} else {
for (; NumElts; ++NextChar, --NumElts)
Vals.push_back(*NextChar);
Vals.push_back(getByte(NextChar));
}
// Skip over tail padding.
NextChar = NewEnd;

View file

@ -16,13 +16,14 @@
#define BITSTREAM_WRITER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitCodes.h"
#include <vector>
namespace llvm {
class BitstreamWriter {
std::vector<unsigned char> &Out;
SmallVectorImpl<char> &Out;
/// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
unsigned CurBit;
@ -59,8 +60,40 @@ class BitstreamWriter {
};
std::vector<BlockInfo> BlockInfoRecords;
// BackpatchWord - Backpatch a 32-bit word in the output with the specified
// value.
void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
Out[ByteNo++] = (unsigned char)(NewWord >> 0);
Out[ByteNo++] = (unsigned char)(NewWord >> 8);
Out[ByteNo++] = (unsigned char)(NewWord >> 16);
Out[ByteNo ] = (unsigned char)(NewWord >> 24);
}
void WriteByte(unsigned char Value) {
Out.push_back(Value);
}
void WriteWord(unsigned Value) {
unsigned char Bytes[4] = {
(unsigned char)(Value >> 0),
(unsigned char)(Value >> 8),
(unsigned char)(Value >> 16),
(unsigned char)(Value >> 24) };
Out.append(&Bytes[0], &Bytes[4]);
}
unsigned GetBufferOffset() const {
return Out.size();
}
unsigned GetWordIndex() const {
unsigned Offset = GetBufferOffset();
assert((Offset & 3) == 0 && "Not 32-bit aligned");
return Offset / 4;
}
public:
explicit BitstreamWriter(std::vector<unsigned char> &O)
explicit BitstreamWriter(SmallVectorImpl<char> &O)
: Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
~BitstreamWriter() {
@ -78,10 +111,8 @@ public:
}
}
std::vector<unsigned char> &getBuffer() { return Out; }
/// \brief Retrieve the current position in the stream, in bits.
uint64_t GetCurrentBitNo() const { return Out.size() * 8 + CurBit; }
uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
//===--------------------------------------------------------------------===//
// Basic Primitives for emitting bits to the stream.
@ -97,11 +128,7 @@ public:
}
// Add the current word.
unsigned V = CurValue;
Out.push_back((unsigned char)(V >> 0));
Out.push_back((unsigned char)(V >> 8));
Out.push_back((unsigned char)(V >> 16));
Out.push_back((unsigned char)(V >> 24));
WriteWord(CurValue);
if (CurBit)
CurValue = Val >> (32-CurBit);
@ -121,11 +148,7 @@ public:
void FlushToWord() {
if (CurBit) {
unsigned V = CurValue;
Out.push_back((unsigned char)(V >> 0));
Out.push_back((unsigned char)(V >> 8));
Out.push_back((unsigned char)(V >> 16));
Out.push_back((unsigned char)(V >> 24));
WriteWord(CurValue);
CurBit = 0;
CurValue = 0;
}
@ -164,15 +187,6 @@ public:
Emit(Val, CurCodeSize);
}
// BackpatchWord - Backpatch a 32-bit word in the output with the specified
// value.
void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
Out[ByteNo++] = (unsigned char)(NewWord >> 0);
Out[ByteNo++] = (unsigned char)(NewWord >> 8);
Out[ByteNo++] = (unsigned char)(NewWord >> 16);
Out[ByteNo ] = (unsigned char)(NewWord >> 24);
}
//===--------------------------------------------------------------------===//
// Block Manipulation
//===--------------------------------------------------------------------===//
@ -199,7 +213,7 @@ public:
EmitVBR(CodeLen, bitc::CodeLenWidth);
FlushToWord();
unsigned BlockSizeWordLoc = static_cast<unsigned>(Out.size());
unsigned BlockSizeWordIndex = GetWordIndex();
unsigned OldCodeSize = CurCodeSize;
// Emit a placeholder, which will be replaced when the block is popped.
@ -209,7 +223,7 @@ public:
// Push the outer block's abbrev set onto the stack, start out with an
// empty abbrev set.
BlockScope.push_back(Block(OldCodeSize, BlockSizeWordLoc/4));
BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
// If there is a blockinfo for this BlockID, add all the predefined abbrevs
@ -239,7 +253,7 @@ public:
FlushToWord();
// Compute the size of the block, in words, not counting the size field.
unsigned SizeInWords= static_cast<unsigned>(Out.size())/4-B.StartSizeWord-1;
unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
unsigned ByteNo = B.StartSizeWord*4;
// Update the block size field in the header of this sub-block.
@ -275,7 +289,7 @@ private:
// Encode the value as we are commanded.
switch (Op.getEncoding()) {
default: assert(0 && "Unknown encoding!");
default: llvm_unreachable("Unknown encoding!");
case BitCodeAbbrevOp::Fixed:
if (Op.getEncodingData())
Emit((unsigned)V, (unsigned)Op.getEncodingData());
@ -355,25 +369,24 @@ private:
// Flush to a 32-bit alignment boundary.
FlushToWord();
assert((Out.size() & 3) == 0 && "Not 32-bit aligned");
// Emit each field as a literal byte.
if (BlobData) {
for (unsigned i = 0; i != BlobLen; ++i)
Out.push_back((unsigned char)BlobData[i]);
WriteByte((unsigned char)BlobData[i]);
// Know that blob data is consumed for assertion below.
BlobData = 0;
} else {
for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
assert(Vals[RecordIdx] < 256 && "Value too large to emit as blob");
Out.push_back((unsigned char)Vals[RecordIdx]);
WriteByte((unsigned char)Vals[RecordIdx]);
}
}
// Align end to 32-bits.
while (Out.size() & 3)
Out.push_back(0);
while (GetBufferOffset() & 3)
WriteByte(0);
} else { // Single scalar field.
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
EmitAbbreviatedField(Op, Vals[RecordIdx]);
@ -488,7 +501,7 @@ public:
/// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
void EnterBlockInfoBlock(unsigned CodeWidth) {
EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
BlockInfoCurBID = -1U;
BlockInfoCurBID = ~0U;
}
private:
/// SwitchToBlockID - If we aren't already talking about the specified block

View file

@ -29,23 +29,21 @@ namespace bitc {
// Module sub-block id's.
PARAMATTR_BLOCK_ID,
/// TYPE_BLOCK_ID_OLD - This is the type descriptor block in LLVM 2.9 and
/// earlier, replaced with TYPE_BLOCK_ID2. FIXME: Remove in LLVM 3.1.
TYPE_BLOCK_ID_OLD,
UNUSED_ID1,
CONSTANTS_BLOCK_ID,
FUNCTION_BLOCK_ID,
/// TYPE_SYMTAB_BLOCK_ID_OLD - This type descriptor is from LLVM 2.9 and
/// earlier bitcode files. FIXME: Remove in LLVM 3.1
TYPE_SYMTAB_BLOCK_ID_OLD,
UNUSED_ID2,
VALUE_SYMTAB_BLOCK_ID,
METADATA_BLOCK_ID,
METADATA_ATTACHMENT_ID,
TYPE_BLOCK_ID_NEW
TYPE_BLOCK_ID_NEW,
USELIST_BLOCK_ID
};
@ -63,10 +61,10 @@ namespace bitc {
MODULE_CODE_GLOBALVAR = 7,
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
// section, visibility]
// section, visibility, gc, unnamed_addr]
MODULE_CODE_FUNCTION = 8,
// ALIAS: [alias type, aliasee val#, linkage]
// ALIAS: [alias type, aliasee val#, linkage, visibility]
MODULE_CODE_ALIAS = 9,
/// MODULE_CODE_PURGEVALS: [numvals]
@ -92,11 +90,12 @@ namespace bitc {
TYPE_CODE_OPAQUE = 6, // OPAQUE
TYPE_CODE_INTEGER = 7, // INTEGER: [width]
TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N]
TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
// paramty x N]
TYPE_CODE_HALF = 10, // HALF
// FIXME: This is the encoding used for structs in LLVM 2.9 and earlier.
// REMOVE this in LLVM 3.1
TYPE_CODE_STRUCT_OLD = 10, // STRUCT: [ispacked, eltty x N]
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
@ -113,7 +112,9 @@ namespace bitc {
TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
TYPE_CODE_STRUCT_NAMED = 20 // STRUCT_NAMED: [ispacked, eltty x N]
TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
TYPE_CODE_FUNCTION = 21 // FUNCTION: [vararg, retty, paramty x N]
};
// The type symbol table only has one code (TST_ENTRY_CODE).
@ -163,7 +164,8 @@ namespace bitc {
CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr]
CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval]
CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands]
CST_CODE_BLOCKADDRESS = 21 // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
CST_CODE_BLOCKADDRESS = 21, // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
CST_CODE_DATA = 22 // DATA: [n x elements]
};
/// CastOpcodes - These are values used in the bitcode files to encode which
@ -270,7 +272,7 @@ namespace bitc {
FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#]
FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...]
FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...]
FUNC_CODE_INST_UNWIND = 14, // UNWIND
// 14 is unused.
FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
@ -314,6 +316,10 @@ namespace bitc {
FUNC_CODE_INST_STOREATOMIC = 42 // STORE: [ptrty,ptr,val, align, vol
// ordering, synchscope]
};
enum UseListCodes {
USELIST_CODE_ENTRY = 1 // USELIST_CODE_ENTRY: TBD.
};
} // End bitc namespace
} // End llvm namespace

View file

@ -17,35 +17,45 @@
#include <string>
namespace llvm {
class Module;
class MemoryBuffer;
class ModulePass;
class BitstreamWriter;
class MemoryBuffer;
class DataStreamer;
class LLVMContext;
class Module;
class ModulePass;
class raw_ostream;
/// getLazyBitcodeModule - Read the header of the specified bitcode buffer
/// and prepare for lazy deserialization of function bodies. If successful,
/// this takes ownership of 'buffer' and returns a non-null pointer. On
/// error, this returns null, *does not* take ownership of Buffer, and fills
/// in *ErrMsg with an error description if ErrMsg is non-null.
Module *getLazyBitcodeModule(MemoryBuffer *Buffer,
LLVMContext& Context,
LLVMContext &Context,
std::string *ErrMsg = 0);
/// getStreamedBitcodeModule - Read the header of the specified stream
/// and prepare for lazy deserialization and streaming of function bodies.
/// On error, this returns null, and fills in *ErrMsg with an error
/// description if ErrMsg is non-null.
Module *getStreamedBitcodeModule(const std::string &name,
DataStreamer *streamer,
LLVMContext &Context,
std::string *ErrMsg = 0);
/// getBitcodeTargetTriple - Read the header of the specified bitcode
/// buffer and extract just the triple information. If successful,
/// this returns a string and *does not* take ownership
/// of 'buffer'. On error, this returns "", and fills in *ErrMsg
/// if ErrMsg is non-null.
std::string getBitcodeTargetTriple(MemoryBuffer *Buffer,
LLVMContext& Context,
LLVMContext &Context,
std::string *ErrMsg = 0);
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, this returns null and fills in *ErrMsg if it is
/// non-null. This method *never* takes ownership of Buffer.
Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context,
std::string *ErrMsg = 0);
/// WriteBitcodeToFile - Write the specified module to the specified
@ -53,15 +63,11 @@ namespace llvm {
/// should be in "binary" mode.
void WriteBitcodeToFile(const Module *M, raw_ostream &Out);
/// WriteBitcodeToStream - Write the specified module to the specified
/// raw output stream.
void WriteBitcodeToStream(const Module *M, BitstreamWriter &Stream);
/// createBitcodeWriterPass - Create and return a pass that writes the module
/// to the specified ostream.
ModulePass *createBitcodeWriterPass(raw_ostream &Str);
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
/// for an LLVM IR bitcode wrapper.
///
@ -109,21 +115,24 @@ namespace llvm {
/// uint32_t BitcodeSize; // Size of traditional bitcode file.
/// ... potentially other gunk ...
/// };
///
///
/// This function is called when we find a file with a matching magic number.
/// In this case, skip down to the subsection of the file that is actually a
/// BC file.
static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr,
unsigned char *&BufEnd) {
/// If 'VerifyBufferSize' is true, check that the buffer is large enough to
/// contain the whole bitcode file.
static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
const unsigned char *&BufEnd,
bool VerifyBufferSize) {
enum {
KnownHeaderSize = 4*4, // Size of header we read.
OffsetField = 2*4, // Offset in bytes to Offset field.
SizeField = 3*4 // Offset in bytes to Size field.
};
// Must contain the header!
if (BufEnd-BufPtr < KnownHeaderSize) return true;
unsigned Offset = ( BufPtr[OffsetField ] |
(BufPtr[OffsetField+1] << 8) |
(BufPtr[OffsetField+2] << 16) |
@ -132,9 +141,9 @@ namespace llvm {
(BufPtr[SizeField +1] << 8) |
(BufPtr[SizeField +2] << 16) |
(BufPtr[SizeField +3] << 24));
// Verify that Offset+Size fits in the file.
if (Offset+Size > unsigned(BufEnd-BufPtr))
if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
return true;
BufPtr += Offset;
BufEnd = BufPtr+Size;

View file

@ -27,6 +27,7 @@ namespace llvm {
class GlobalVariable;
class TargetLowering;
class SDNode;
class SDValue;
class SelectionDAG;
/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
@ -70,6 +71,10 @@ bool hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos,
///
ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred);
/// getFCmpCodeWithoutNaN - Given an ISD condition code comparing floats,
/// return the equivalent code if we're allowed to assume that NaNs won't occur.
ISD::CondCode getFCmpCodeWithoutNaN(ISD::CondCode CC);
/// getICmpCondCode - Return the ISD condition code corresponding to
/// the given LLVM IR integer condition code.
///
@ -85,7 +90,7 @@ bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
const TargetLowering &TLI);
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
const TargetLowering &TLI);
SDValue &Chain, const TargetLowering &TLI);
} // End llvm namespace

View file

@ -18,16 +18,12 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class BlockAddress;
class GCStrategy;
class Constant;
class ConstantArray;
class ConstantFP;
class ConstantInt;
class ConstantStruct;
class ConstantVector;
class GCMetadataPrinter;
class GlobalValue;
class GlobalVariable;
@ -37,14 +33,11 @@ namespace llvm {
class MachineLocation;
class MachineLoopInfo;
class MachineLoop;
class MachineConstantPool;
class MachineConstantPoolEntry;
class MachineConstantPoolValue;
class MachineJumpTableInfo;
class MachineModuleInfo;
class MachineMove;
class MCAsmInfo;
class MCInst;
class MCContext;
class MCSection;
class MCStreamer;
@ -56,8 +49,6 @@ namespace llvm {
class TargetLoweringObjectFile;
class TargetData;
class TargetMachine;
class Twine;
class Type;
/// AsmPrinter - This class is intended to be used as a driving class for all
/// asm writers.
@ -97,6 +88,11 @@ namespace llvm {
///
MCSymbol *CurrentFnSym;
/// The symbol used to represent the start of the current function for the
/// purpose of calculating its size (e.g. using the .size directive). By
/// default, this is equal to CurrentFnSym.
MCSymbol *CurrentFnSymForSize;
private:
// GCMetadataPrinters - The garbage collection metadata printer table.
void *GCMetadataPrinters; // Really a DenseMap.
@ -194,6 +190,11 @@ namespace llvm {
bool needsSEHMoves();
/// needsRelocationsForDwarfStringPool - Specifies whether the object format
/// expects to use relocations to refer to debug entries. Alternatively we
/// emit section offsets in bytes from the start of the string pool.
bool needsRelocationsForDwarfStringPool() const;
/// EmitConstantPool - Print to the current output stream assembly
/// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by
@ -256,13 +257,20 @@ namespace llvm {
/// EmitInstruction - Targets should implement this to emit instructions.
virtual void EmitInstruction(const MachineInstr *) {
assert(0 && "EmitInstruction not implemented");
llvm_unreachable("EmitInstruction not implemented");
}
virtual void EmitFunctionEntryLabel();
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
/// EmitXXStructor - Targets can override this to change how global
/// constants that are part of a C++ static/global constructor list are
/// emitted.
virtual void EmitXXStructor(const Constant *CV) {
EmitGlobalConstant(CV);
}
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
@ -466,7 +474,7 @@ namespace llvm {
const MachineBasicBlock *MBB,
unsigned uid) const;
void EmitLLVMUsedList(const Constant *List);
void EmitXXStructorList(const Constant *List);
void EmitXXStructorList(const Constant *List, bool isCtor);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
};
}

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