Upgrade our copy of llvm/clang to r142614, from upstream's release_30

branch.  This brings us very close to the 3.0 release, which is expected
in a week or two.

MFC after:	1 week
This commit is contained in:
Dimitry Andric 2011-10-22 14:08:43 +00:00
commit 6122f3e60d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=226633
1744 changed files with 130675 additions and 80773 deletions

View File

@ -1030,7 +1030,9 @@ _crunchgen= usr.sbin/crunch/crunchgen
.if ${MK_CLANG} != "no"
_clang_tblgen= \
lib/clang/libllvmsupport \
usr.bin/clang/tblgen
lib/clang/libllvmtablegen \
usr.bin/clang/tblgen \
usr.bin/clang/clang-tblgen
.endif
.if ${MK_CDDL} != "no" && \

View File

@ -115,7 +115,10 @@ typedef enum {
LLVMNoImplicitFloatAttribute = 1<<23,
LLVMNakedAttribute = 1<<24,
LLVMInlineHintAttribute = 1<<25,
LLVMStackAlignment = 7<<26
LLVMStackAlignment = 7<<26,
LLVMReturnsTwice = 1 << 29,
LLVMUWTable = 1 << 30,
LLVMNonLazyBind = 1 << 31
} LLVMAttribute;
typedef enum {
@ -125,7 +128,7 @@ typedef enum {
LLVMSwitch = 3,
LLVMIndirectBr = 4,
LLVMInvoke = 5,
LLVMUnwind = 6,
/* removed 6 due to API changes */
LLVMUnreachable = 7,
/* Standard Binary Operators */
@ -176,14 +179,26 @@ typedef enum {
LLVMPHI = 44,
LLVMCall = 45,
LLVMSelect = 46,
/* UserOp1 */
/* UserOp2 */
LLVMUserOp1 = 47,
LLVMUserOp2 = 48,
LLVMVAArg = 49,
LLVMExtractElement = 50,
LLVMInsertElement = 51,
LLVMShuffleVector = 52,
LLVMExtractValue = 53,
LLVMInsertValue = 54
LLVMInsertValue = 54,
/* Atomic operators */
LLVMFence = 55,
LLVMAtomicCmpXchg = 56,
LLVMAtomicRMW = 57,
/* Exception Handling Operators */
LLVMResume = 58,
LLVMLandingPad = 59,
LLVMUnwind = 60
} LLVMOpcode;
typedef enum {
@ -274,6 +289,11 @@ typedef enum {
LLVMRealPredicateTrue /**< Always true (always folded) */
} LLVMRealPredicate;
typedef enum {
LLVMLandingPadCatch, /**< A catch clause */
LLVMLandingPadFilter /**< A filter clause */
} LLVMLandingPadClauseTy;
void LLVMInitializeCore(LLVMPassRegistryRef R);
@ -340,6 +360,7 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
/** See llvm::LLVMTypeKind::getTypeID. */
LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty);
/** See llvm::LLVMType::getContext. */
LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty);
@ -388,6 +409,7 @@ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
LLVMBool Packed);
LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
const char *LLVMGetStructName(LLVMTypeRef Ty);
void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
unsigned ElementCount, LLVMBool Packed);
@ -427,8 +449,11 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(Argument) \
macro(BasicBlock) \
macro(InlineAsm) \
macro(MDNode) \
macro(MDString) \
macro(User) \
macro(Constant) \
macro(BlockAddress) \
macro(ConstantAggregateZero) \
macro(ConstantArray) \
macro(ConstantExpr) \
@ -448,29 +473,32 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(IntrinsicInst) \
macro(DbgInfoIntrinsic) \
macro(DbgDeclareInst) \
macro(EHExceptionInst) \
macro(EHSelectorInst) \
macro(MemIntrinsic) \
macro(MemCpyInst) \
macro(MemMoveInst) \
macro(MemSetInst) \
macro(CmpInst) \
macro(FCmpInst) \
macro(ICmpInst) \
macro(FCmpInst) \
macro(ICmpInst) \
macro(ExtractElementInst) \
macro(GetElementPtrInst) \
macro(InsertElementInst) \
macro(InsertValueInst) \
macro(LandingPadInst) \
macro(PHINode) \
macro(SelectInst) \
macro(ShuffleVectorInst) \
macro(StoreInst) \
macro(TerminatorInst) \
macro(BranchInst) \
macro(IndirectBrInst) \
macro(InvokeInst) \
macro(ReturnInst) \
macro(SwitchInst) \
macro(UnreachableInst) \
macro(UnwindInst) \
macro(ResumeInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
@ -533,6 +561,11 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
unsigned Count);
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
int LLVMGetMDNodeNumOperands(LLVMValueRef V);
LLVMValueRef *LLVMGetMDNodeOperand(LLVMValueRef V, unsigned i);
unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name);
void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest);
/* Operations on scalar constants */
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
@ -728,6 +761,7 @@ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB);
LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val);
LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB);
unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn);
@ -747,16 +781,21 @@ LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name);
LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
const char *Name);
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB);
void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
/* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB);
/* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
void LLVMInstructionEraseFromParent(LLVMValueRef Inst);
LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst);
LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst);
/* Operations on call sites */
void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC);
@ -771,6 +810,9 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
/* Operations on switch instructions (only) */
LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr);
/* Operations on phi nodes */
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
LLVMBasicBlockRef *IncomingBlocks, unsigned Count);
@ -818,7 +860,10 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
const char *Name);
LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef PersFn, unsigned NumClauses,
const char *Name);
LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
/* Add a case to the switch instruction */
@ -828,6 +873,12 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
/* Add a destination to the indirectbr instruction */
void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
/* Add a catch or filter clause to the landingpad instruction */
void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal);
/* Set the 'cleanup' flag in the landingpad instruction */
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
/* Arithmetic */
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
@ -1136,7 +1187,7 @@ namespace llvm {
return reinterpret_cast<Type**>(Tys);
}
inline LLVMTypeRef *wrap(const Type **Tys) {
inline LLVMTypeRef *wrap(Type **Tys) {
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
}

View File

@ -66,7 +66,7 @@ typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC,
*/
struct LLVMOpInfoSymbol1 {
uint64_t Present; /* 1 if this symbol is present */
char *Name; /* symbol name if not NULL */
const char *Name; /* symbol name if not NULL */
uint64_t Value; /* symbol value if name is NULL */
};
@ -93,11 +93,35 @@ struct LLVMOpInfo1 {
* disassembler for things like adding a comment for a PC plus a constant
* offset load instruction to use a symbol name instead of a load address value.
* It is passed the block information is saved when the disassembler context is
* created and a value of a symbol to look up. If no symbol is found NULL is
* returned.
* created and the ReferenceValue to look up as a symbol. If no symbol is found
* for the ReferenceValue NULL is returned. The ReferenceType of the
* instruction is passed indirectly as is the PC of the instruction in
* ReferencePC. If the output reference can be determined its type is returned
* indirectly in ReferenceType along with ReferenceName if any, or that is set
* to NULL.
*/
typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
uint64_t SymbolValue);
uint64_t ReferenceValue,
uint64_t *ReferenceType,
uint64_t ReferencePC,
const char **ReferenceName);
/**
* The reference types on input and output.
*/
/* No input reference type or no output reference type. */
#define LLVMDisassembler_ReferenceType_InOut_None 0
/* The input reference is from a branch instruction. */
#define LLVMDisassembler_ReferenceType_In_Branch 1
/* The input reference is from a PC relative load instruction. */
#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2
/* The output reference is to as symbol stub. */
#define LLVMDisassembler_ReferenceType_Out_SymbolStub 1
/* The output reference is to a symbol address in a literal pool. */
#define LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr 2
/* The output reference is to a cstring address in a literal pool. */
#define LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr 3
#ifdef __cplusplus
extern "C" {

View File

@ -59,14 +59,14 @@ namespace llvm {
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
}
inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<ObjectFile::section_iterator*>(SI);
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<section_iterator*>(SI);
}
inline LLVMSectionIteratorRef
wrap(const ObjectFile::section_iterator *SI) {
wrap(const section_iterator *SI) {
return reinterpret_cast<LLVMSectionIteratorRef>
(const_cast<ObjectFile::section_iterator*>(SI));
(const_cast<section_iterator*>(SI));
}
}
}

View File

@ -29,6 +29,7 @@ extern "C" {
enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
typedef struct LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef;
typedef struct LLVMStructLayout *LLVMStructLayoutRef;
/* Declare all of the target-initialization functions that are available. */
@ -42,7 +43,7 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef;
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
#define LLVM_TARGET(TargetName) \
void LLVMInitialize##TargetName##MCAsmInfo(void);
void LLVMInitialize##TargetName##TargetMC(void);
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
@ -72,7 +73,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
#ifdef LLVM_NATIVE_TARGET
LLVM_NATIVE_TARGETINFO();
LLVM_NATIVE_TARGET();
LLVM_NATIVE_MCASMINFO();
LLVM_NATIVE_TARGETMC();
return 0;
#else
return 1;
@ -90,6 +91,11 @@ LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
See the method llvm::PassManagerBase::add. */
void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef);
/** Adds target library information to a pass manager. This does not take
ownership of the target library info.
See the method llvm::PassManagerBase::add. */
void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
See the constructor llvm::TargetData::TargetData. */
@ -157,6 +163,7 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
namespace llvm {
class TargetData;
class TargetLibraryInfo;
inline TargetData *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<TargetData*>(P);
@ -165,6 +172,15 @@ namespace llvm {
inline LLVMTargetDataRef wrap(const TargetData *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
return reinterpret_cast<TargetLibraryInfo*>(P);
}
inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
}
}
#endif /* defined(__cplusplus) */

View File

@ -36,6 +36,9 @@ void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);
/** See llvm::createFunctionInliningPass function. */
void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM);
/** See llvm::createAlwaysInlinerPass function. */
void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM);
/** See llvm::createGlobalDCEPass function. */
void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM);
@ -45,9 +48,6 @@ void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM);
/** See llvm::createIPConstantPropagationPass function. */
void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM);
/** See llvm::createLowerSetJmpPass function. */
void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM);
/** See llvm::createPruneEHPass function. */
void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
@ -57,9 +57,6 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM);
/** See llvm::createInternalizePass function. */
void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain);
// FIXME: Remove in LLVM 3.0.
void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM);
/** See llvm::createStripDeadPrototypesPass function. */
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM);

View File

@ -0,0 +1,90 @@
/*===-- llvm-c/Transform/PassManagerBuilder.h - PMB 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 PassManagerBuilder class. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_PASSMANAGERBUILDER
#define LLVM_C_PASSMANAGERBUILDER
#include "llvm-c/Core.h"
typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef;
#ifdef __cplusplus
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
extern "C" {
#endif
/** See llvm::PassManagerBuilder. */
LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void);
void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB);
/** See llvm::PassManagerBuilder::OptLevel. */
void
LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
unsigned OptLevel);
/** See llvm::PassManagerBuilder::SizeLevel. */
void
LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
unsigned SizeLevel);
/** See llvm::PassManagerBuilder::DisableUnitAtATime. */
void
LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::DisableUnrollLoops. */
void
LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::DisableSimplifyLibCalls */
void
LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::Inliner. */
void
LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
unsigned Threshold);
/** See llvm::PassManagerBuilder::populateFunctionPassManager. */
void
LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM);
/** See llvm::PassManagerBuilder::populateModulePassManager. */
void
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM);
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM,
bool Internalize,
bool RunInliner);
#ifdef __cplusplus
}
namespace llvm {
inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
return reinterpret_cast<PassManagerBuilder*>(P);
}
inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
}
}
#endif
#endif

View File

@ -107,6 +107,9 @@ void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM);
/** See llvm::createEarlyCSEPass function */
void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM);
/** See llvm::createLowerExpectIntrinsicPass function */
void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM);
/** See llvm::createTypeBasedAliasAnalysisPass function */
void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);

View File

@ -15,6 +15,7 @@
#ifndef LLVM_APINT_H
#define LLVM_APINT_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <climits>
@ -160,7 +161,7 @@ class APInt {
/// not assume that the string is well-formed and (2) grows the
/// result to hold the input.
///
/// @param radix 2, 8, 10, or 16
/// @param radix 2, 8, 10, 16, or 36
/// @brief Convert a char array into an APInt
void fromString(unsigned numBits, StringRef str, uint8_t radix);
@ -176,6 +177,9 @@ class APInt {
/// out-of-line slow case for inline constructor
void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
/// shared code between two array constructors
void initFromArray(ArrayRef<uint64_t> array);
/// out-of-line slow case for inline copy constructor
void initSlowCase(const APInt& that);
@ -230,19 +234,26 @@ class APInt {
clearUnusedBits();
}
/// Note that numWords can be smaller or larger than the corresponding bit
/// width but any extraneous bits will be dropped.
/// Note that bigVal.size() can be smaller or larger than the corresponding
/// bit width but any extraneous bits will be dropped.
/// @param numBits the bit width of the constructed APInt
/// @param numWords the number of words in bigVal
/// @param bigVal a sequence of words to form the initial value of the APInt
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
/// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
/// deprecated because this constructor is prone to ambiguity with the
/// APInt(unsigned, uint64_t, bool) constructor.
///
/// If this overload is ever deleted, care should be taken to prevent calls
/// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
/// This constructor interprets the string \arg str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
/// are 2, 8, 10 and 16. It is an error for the value implied by the string to
/// require more bits than numBits.
/// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
/// string to require more bits than numBits.
///
/// @param numBits the bit width of the constructed APInt
/// @param str the string to be interpreted
@ -342,7 +353,8 @@ class APInt {
if (isSingleWord())
return isUIntN(N, VAL);
return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this);
return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth())
== (*this);
}
/// @brief Check if this APInt has an N-bits signed integer value.
@ -1245,13 +1257,13 @@ class APInt {
bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
/// radix given. The radix can be 2, 8, 10 16, or 36.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, false, false);
}
/// Considers the APInt to be signed and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
/// radix given. The radix can be 2, 8, 10, 16, or 36.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, true, false);
}

View File

@ -147,7 +147,53 @@ namespace llvm {
/// @}
};
/// @name ArrayRef Convenience constructors
/// @{
/// Construct an ArrayRef from a single element.
template<typename T>
ArrayRef<T> makeArrayRef(const T &OneElt) {
return OneElt;
}
/// Construct an ArrayRef from a pointer and length.
template<typename T>
ArrayRef<T> makeArrayRef(const T *data, size_t length) {
return ArrayRef<T>(data, length);
}
/// Construct an ArrayRef from a range.
template<typename T>
ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
return ArrayRef<T>(begin, end);
}
/// Construct an ArrayRef from a SmallVector.
template <typename T>
ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a SmallVector.
template <typename T, unsigned N>
ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a std::vector.
template<typename T>
ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a C array.
template<typename T, size_t N>
ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
return ArrayRef<T>(Arr);
}
/// @}
/// @name ArrayRef Comparison Operators
/// @{

View File

@ -540,6 +540,12 @@ class DenseMapIterator {
++Ptr;
}
};
template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) {
return X.getMemorySize();
}
} // end namespace llvm

View File

@ -51,7 +51,7 @@ struct DenseMapInfo<T*> {
template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37; }
static unsigned getHashValue(const char& Val) { return Val * 37U; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
@ -61,7 +61,7 @@ template<> struct DenseMapInfo<char> {
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@ -96,7 +96,7 @@ template<> struct DenseMapInfo<unsigned long long> {
template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS;
}
@ -109,7 +109,7 @@ template<> struct DenseMapInfo<long> {
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {
return (unsigned)(Val * 37L);
return (unsigned)(Val * 37UL);
}
static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS;
@ -121,7 +121,7 @@ template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
static unsigned getHashValue(const long long& Val) {
return (unsigned)(Val * 37LL);
return (unsigned)(Val * 37ULL);
}
static bool isEqual(const long long& LHS,
const long long& RHS) {
@ -142,7 +142,7 @@ struct DenseMapInfo<std::pair<T, U> > {
}
static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getEmptyKey());
SecondInfo::getTombstoneKey());
}
static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
@ -158,7 +158,7 @@ struct DenseMapInfo<std::pair<T, U> > {
return (unsigned)key;
}
static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) &&
return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
}
};

View File

@ -28,7 +28,7 @@ class DenseSet {
MapTy TheMap;
public:
DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }

View File

@ -117,6 +117,10 @@ class ImmutableMap {
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
typename TreeTy::Factory *getTreeFactory() const {
return const_cast<typename TreeTy::Factory *>(&F);
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
@ -256,6 +260,159 @@ class ImmutableMap {
}
};
// NOTE: This will possibly become the new implementation of ImmutableMap some day.
template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
class ImmutableMapRef {
public:
typedef typename ValInfo::value_type value_type;
typedef typename ValInfo::value_type_ref value_type_ref;
typedef typename ValInfo::key_type key_type;
typedef typename ValInfo::key_type_ref key_type_ref;
typedef typename ValInfo::data_type data_type;
typedef typename ValInfo::data_type_ref data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
protected:
TreeTy *Root;
FactoryTy *Factory;
public:
/// Constructs a map from a pointer to a tree root. In general one
/// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F)
: Root(const_cast<TreeTy*>(R)),
Factory(F) {
if (Root) { Root->retain(); }
}
ImmutableMapRef(const ImmutableMapRef &X)
: Root(X.Root),
Factory(X.Factory) {
if (Root) { Root->retain(); }
}
ImmutableMapRef &operator=(const ImmutableMapRef &X) {
if (Root != X.Root) {
if (X.Root)
X.Root->retain();
if (Root)
Root->release();
Root = X.Root;
Factory = X.Factory;
}
return *this;
}
~ImmutableMapRef() {
if (Root)
Root->release();
}
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
return ImmutableMapRef(0, F);
}
ImmutableMapRef add(key_type_ref K, data_type_ref D) {
TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
return ImmutableMapRef(NewT, Factory);
}
ImmutableMapRef remove(key_type_ref K) {
TreeTy *NewT = Factory->remove(Root, K);
return ImmutableMapRef(NewT, Factory);
}
bool contains(key_type_ref K) const {
return Root ? Root->contains(K) : false;
}
ImmutableMap<KeyT, ValT> asImmutableMap() const {
return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
}
bool operator==(const ImmutableMapRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
bool operator!=(const ImmutableMapRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
bool isEmpty() const { return !Root; }
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
void verify() const { if (Root) Root->verify(); }
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
class iterator {
typename TreeTy::iterator itr;
iterator() {}
iterator(TreeTy* t) : itr(t) {}
friend class ImmutableMapRef;
public:
value_type_ref operator*() const { return itr->getValue(); }
value_type* operator->() const { return &itr->getValue(); }
key_type_ref getKey() const { return itr->getValue().first; }
data_type_ref getData() const { return itr->getValue().second; }
iterator& operator++() { ++itr; return *this; }
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
iterator& operator--() { --itr; return *this; }
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
};
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
data_type* lookup(key_type_ref K) const {
if (Root) {
TreeTy* T = Root->find(K);
if (T) return &T->getValue().second;
}
return 0;
}
/// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
/// which key is the highest in the ordering of keys in the map. This
/// method returns NULL if the map is empty.
value_type* getMaxElement() const {
return Root ? &(Root->getMaxElement()->getValue()) : 0;
}
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
ID.AddPointer(M.Root);
}
inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID, *this);
}
};
} // end namespace llvm
#endif

View File

@ -997,6 +997,10 @@ class ImmutableSet {
BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
typename TreeTy::Factory *getTreeFactory() const {
return const_cast<typename TreeTy::Factory *>(&F);
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
@ -1021,6 +1025,10 @@ class ImmutableSet {
if (Root) { Root->retain(); }
return Root;
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
@ -1078,6 +1086,132 @@ class ImmutableSet {
void validateTree() const { if (Root) Root->validateTree(); }
};
// NOTE: This may some day replace the current ImmutableSet.
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
class ImmutableSetRef {
public:
typedef typename ValInfo::value_type value_type;
typedef typename ValInfo::value_type_ref value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
private:
TreeTy *Root;
FactoryTy *Factory;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
: Root(R),
Factory(F) {
if (Root) { Root->retain(); }
}
ImmutableSetRef(const ImmutableSetRef &X)
: Root(X.Root),
Factory(X.Factory) {
if (Root) { Root->retain(); }
}
ImmutableSetRef &operator=(const ImmutableSetRef &X) {
if (Root != X.Root) {
if (X.Root) { X.Root->retain(); }
if (Root) { Root->release(); }
Root = X.Root;
Factory = X.Factory;
}
return *this;
}
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
ImmutableSetRef add(value_type_ref V) {
return ImmutableSetRef(Factory->add(Root, V), Factory);
}
ImmutableSetRef remove(value_type_ref V) {
return ImmutableSetRef(Factory->remove(Root, V), Factory);
}
/// Returns true if the set contains the specified value.
bool contains(value_type_ref V) const {
return Root ? Root->contains(V) : false;
}
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
return ImmutableSet<ValT>(canonicalize ?
Factory->getCanonicalTree(Root) : Root);
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
bool operator==(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
bool operator!=(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
/// isSingleton - Return true if the set contains exactly one element.
/// This method runs in constant time.
bool isSingleton() const { return getHeight() == 1; }
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
class iterator {
typename TreeTy::iterator itr;
iterator(TreeTy* t) : itr(t) {}
friend class ImmutableSetRef<ValT,ValInfo>;
public:
iterator() {}
inline value_type_ref operator*() const { return itr->getValue(); }
inline iterator& operator++() { ++itr; return *this; }
inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
inline iterator& operator--() { --itr; return *this; }
inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
inline value_type *operator->() const { return &(operator*()); }
};
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
ID.AddPointer(S.Root);
}
inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID,*this);
}
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
void validateTree() const { if (Root) Root->validateTree(); }
};
} // end namespace llvm

View File

@ -1335,6 +1335,9 @@ class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
/// valid - Return true if the current position is valid, false for end().
bool valid() const { return path.valid(); }
/// atBegin - Return true if the current position is the first map entry.
bool atBegin() const { return path.atBegin(); }
/// start - Return the beginning of the current interval.
const KeyT &start() const { return unsafeStart(); }

View File

@ -108,7 +108,11 @@ namespace llvm {
/// isNull - Return true if the pointer held in the union is null,
/// regardless of which type it is.
bool isNull() const { return Val.getPointer() == 0; }
bool isNull() const {
// Convert from the void* to one of the pointer types, to make sure that
// we recursively strip off low bits if we have a nested PointerUnion.
return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
}
operator bool() const { return !isNull(); }
/// is<T>() return true if the Union currently holds the type matching T.

View File

@ -29,6 +29,14 @@ class po_iterator_storage {
SetType Visited;
};
/// DFSetTraits - Allow the SetType used to record depth-first search results to
/// optionally record node postorder.
template<class SetType>
struct DFSetTraits {
static void finishPostorder(
typename SetType::iterator::value_type, SetType &) {}
};
template<class SetType>
class po_iterator_storage<SetType, true> {
public:
@ -109,6 +117,8 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
inline NodeType *operator->() const { return operator*(); }
inline _Self& operator++() { // Preincrement
DFSetTraits<SetType>::finishPostorder(VisitStack.back().first,
this->Visited);
VisitStack.pop_back();
if (!VisitStack.empty())
traverseChild();

View File

@ -1,4 +1,4 @@
//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===//
//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -87,7 +87,7 @@ class scc_iterator
DFSVisitOne(childN);
continue;
}
unsigned childNum = nodeVisitNumbers[childN];
if (MinVisitNumStack.back() > childNum)
MinVisitNumStack.back() = childNum;
@ -114,7 +114,7 @@ class scc_iterator
if (minVisitNum != nodeVisitNumbers[visitingN])
continue;
// A full SCC is on the SCCNodeStack! It includes all nodes below
// visitingN on the stack. Copy those nodes to CurrentSCC,
// reset their minVisit values, and return (this suspends
@ -139,7 +139,7 @@ class scc_iterator
// Provide static "constructors"...
static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
static inline _Self end (const GraphT &G) { return _Self(); }
static inline _Self end (const GraphT &) { return _Self(); }
// Direct loop termination test: I.isAtEnd() is more efficient than I == end()
inline bool isAtEnd() const {
@ -183,7 +183,7 @@ class scc_iterator
return true;
return false;
}
/// ReplaceNode - This informs the scc_iterator that the specified Old node
/// has been deleted, and New is to be used in its place.
void ReplaceNode(NodeType *Old, NodeType *New) {

View File

@ -186,25 +186,21 @@ inline ItTy prior(ItTy it)
// // do stuff
// else
// // do other stuff
template <typename T1, typename T2>
struct tier {
typedef T1 &first_type;
typedef T2 &second_type;
namespace
{
template <typename T1, typename T2>
struct tier {
typedef T1 &first_type;
typedef T2 &second_type;
first_type first;
second_type second;
first_type first;
second_type second;
tier(first_type f, second_type s) : first(f), second(s) { }
tier& operator=(const std::pair<T1, T2>& p) {
first = p.first;
second = p.second;
return *this;
}
};
}
tier(first_type f, second_type s) : first(f), second(s) { }
tier& operator=(const std::pair<T1, T2>& p) {
first = p.first;
second = p.second;
return *this;
}
};
template <typename T1, typename T2>
inline tier<T1, T2> tie(T1& f, T2& s) {

View File

@ -78,21 +78,21 @@ class SmallVectorBase {
return BeginX == static_cast<const void*>(&FirstEl);
}
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(size_t MinSizeInBytes, size_t TSize);
public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
bool empty() const { return BeginX == EndX; }
};
@ -738,6 +738,11 @@ class SmallVector<T,0> : public SmallVectorImpl<T> {
};
template<typename T, unsigned N>
static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
return X.capacity_in_bytes();
}
} // End llvm namespace
namespace std {

View File

@ -54,7 +54,7 @@ class Statistic {
Value = Val;
return init();
}
const Statistic &operator++() {
// FIXME: This function and all those that follow carefully use an
// atomic operation to update the value safely in the presence of
@ -63,41 +63,43 @@ class Statistic {
sys::AtomicIncrement(&Value);
return init();
}
unsigned operator++(int) {
init();
unsigned OldValue = Value;
sys::AtomicIncrement(&Value);
return OldValue;
}
const Statistic &operator--() {
sys::AtomicDecrement(&Value);
return init();
}
unsigned operator--(int) {
init();
unsigned OldValue = Value;
sys::AtomicDecrement(&Value);
return OldValue;
}
const Statistic &operator+=(const unsigned &V) {
if (!V) return *this;
sys::AtomicAdd(&Value, V);
return init();
}
const Statistic &operator-=(const unsigned &V) {
if (!V) return *this;
sys::AtomicAdd(&Value, -V);
return init();
}
const Statistic &operator*=(const unsigned &V) {
sys::AtomicMul(&Value, V);
return init();
}
const Statistic &operator/=(const unsigned &V) {
sys::AtomicDiv(&Value, V);
return init();

View File

@ -16,6 +16,7 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
#include <cstdio>

View File

@ -0,0 +1,133 @@
//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_TINYPTRVECTOR_H
#define LLVM_ADT_TINYPTRVECTOR_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerUnion.h"
namespace llvm {
/// TinyPtrVector - This class is specialized for cases where there are
/// normally 0 or 1 element in a vector, but is general enough to go beyond that
/// when required.
///
/// NOTE: This container doesn't allow you to store a null pointer into it.
///
template <typename EltTy>
class TinyPtrVector {
public:
typedef llvm::SmallVector<EltTy, 4> VecTy;
llvm::PointerUnion<EltTy, VecTy*> Val;
TinyPtrVector() {}
TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
if (VecTy *V = Val.template dyn_cast<VecTy*>())
Val = new VecTy(*V);
}
~TinyPtrVector() {
if (VecTy *V = Val.template dyn_cast<VecTy*>())
delete V;
}
bool empty() const {
// This vector can be empty if it contains no element, or if it
// contains a pointer to an empty vector.
if (Val.isNull()) return true;
if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
return Vec->empty();
return false;
}
unsigned size() const {
if (empty())
return 0;
if (Val.template is<EltTy>())
return 1;
return Val.template get<VecTy*>()->size();
}
typedef const EltTy *iterator;
iterator begin() const {
if (empty())
return 0;
if (Val.template is<EltTy>())
return Val.template getAddrOf<EltTy>();
return Val.template get<VecTy *>()->begin();
}
iterator end() const {
if (empty())
return 0;
if (Val.template is<EltTy>())
return begin() + 1;
return Val.template get<VecTy *>()->end();
}
EltTy operator[](unsigned i) const {
assert(!Val.isNull() && "can't index into an empty vector");
if (EltTy V = Val.template dyn_cast<EltTy>()) {
assert(i == 0 && "tinyvector index out of range");
return V;
}
assert(i < Val.template get<VecTy*>()->size() &&
"tinyvector index out of range");
return (*Val.template get<VecTy*>())[i];
}
EltTy front() const {
assert(!empty() && "vector empty");
if (EltTy V = Val.template dyn_cast<EltTy>())
return V;
return Val.template get<VecTy*>()->front();
}
void push_back(EltTy NewVal) {
assert(NewVal != 0 && "Can't add a null value");
// If we have nothing, add something.
if (Val.isNull()) {
Val = NewVal;
return;
}
// If we have a single value, convert to a vector.
if (EltTy V = Val.template dyn_cast<EltTy>()) {
Val = new VecTy();
Val.template get<VecTy*>()->push_back(V);
}
// Add the new value, we know we have a vector.
Val.template get<VecTy*>()->push_back(NewVal);
}
void clear() {
// If we have a single value, convert to empty.
if (Val.template is<EltTy>()) {
Val = (EltTy)0;
} else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
// If we have a vector form, just clear it.
Vec->clear();
}
// Otherwise, we're already empty.
}
private:
void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
};
} // end namespace llvm
#endif

View File

@ -10,8 +10,7 @@
#ifndef LLVM_ADT_TRIPLE_H
#define LLVM_ADT_TRIPLE_H
#include "llvm/ADT/StringRef.h"
#include <string>
#include "llvm/ADT/Twine.h"
// Some system headers or GCC predefined macros conflict with identifiers in
// this file. Undefine them here.
@ -19,8 +18,6 @@
#undef sparc
namespace llvm {
class StringRef;
class Twine;
/// Triple - Helper class for working with target triples.
///
@ -52,6 +49,8 @@ class Triple {
cellspu, // CellSPU: spu, cellspu
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
mips64, // MIPS64: mips64
mips64el,// MIPS64EL: mips64el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
@ -66,6 +65,8 @@ class Triple {
mblaze, // MBlaze: mblaze
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
};
@ -85,6 +86,7 @@ class Triple {
DragonFly,
FreeBSD,
IOS,
KFreeBSD,
Linux,
Lv2, // PS3
MacOSX,
@ -96,7 +98,8 @@ class Triple {
Win32,
Haiku,
Minix,
RTEMS
RTEMS,
NativeClient
};
enum EnvironmentType {
UnknownEnvironment,
@ -134,24 +137,16 @@ class Triple {
/// @{
Triple() : Data(), Arch(InvalidArch) {}
explicit Triple(StringRef Str) : Data(Str), Arch(InvalidArch) {}
explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr)
: Data(ArchStr), Arch(InvalidArch) {
Data += '-';
Data += VendorStr;
Data += '-';
Data += OSStr;
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) {
}
explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr,
StringRef EnvironmentStr)
: Data(ArchStr), Arch(InvalidArch) {
Data += '-';
Data += VendorStr;
Data += '-';
Data += OSStr;
Data += '-';
Data += EnvironmentStr;
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
const Twine &EnvironmentStr)
: Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
EnvironmentStr).str()), Arch(InvalidArch) {
}
/// @}

View File

@ -99,6 +99,9 @@ namespace llvm {
/// A pointer to a StringRef instance.
StringRefKind,
/// A char value reinterpreted as a pointer, to render as a character.
CharKind,
/// An unsigned int value reinterpreted as a pointer, to render as an
/// unsigned decimal integer.
DecUIKind,
@ -126,13 +129,31 @@ namespace llvm {
UHexKind
};
union Child
{
const Twine *twine;
const char *cString;
const std::string *stdString;
const StringRef *stringRef;
char character;
unsigned int decUI;
int decI;
const unsigned long *decUL;
const long *decL;
const unsigned long long *decULL;
const long long *decLL;
const uint64_t *uHex;
};
private:
/// LHS - The prefix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
const void *LHS;
Child LHS;
/// RHS - The suffix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
const void *RHS;
Child RHS;
// enums stored as unsigned chars to save on space while some compilers
// don't support specifying the backing type for an enum
/// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
unsigned char LHSKind;
/// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
@ -147,13 +168,15 @@ namespace llvm {
/// Construct a binary twine.
explicit Twine(const Twine &_LHS, const Twine &_RHS)
: LHS(&_LHS), RHS(&_RHS), LHSKind(TwineKind), RHSKind(TwineKind) {
: LHSKind(TwineKind), RHSKind(TwineKind) {
LHS.twine = &_LHS;
RHS.twine = &_RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct a twine from explicit values.
explicit Twine(const void *_LHS, NodeKind _LHSKind,
const void *_RHS, NodeKind _RHSKind)
explicit Twine(Child _LHS, NodeKind _LHSKind,
Child _RHS, NodeKind _RHSKind)
: LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
assert(isValid() && "Invalid twine!");
}
@ -200,10 +223,10 @@ namespace llvm {
// A twine child should always be binary.
if (getLHSKind() == TwineKind &&
!static_cast<const Twine*>(LHS)->isBinary())
!LHS.twine->isBinary())
return false;
if (getRHSKind() == TwineKind &&
!static_cast<const Twine*>(RHS)->isBinary())
!RHS.twine->isBinary())
return false;
return true;
@ -216,10 +239,10 @@ namespace llvm {
NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
/// printOneChild - Print one child from a twine.
void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const;
void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
/// printOneChildRepr - Print the representation of one child from a twine.
void printOneChildRepr(raw_ostream &OS, const void *Ptr,
void printOneChildRepr(raw_ostream &OS, Child Ptr,
NodeKind Kind) const;
public:
@ -239,7 +262,7 @@ namespace llvm {
/*implicit*/ Twine(const char *Str)
: RHSKind(EmptyKind) {
if (Str[0] != '\0') {
LHS = Str;
LHS.cString = Str;
LHSKind = CStringKind;
} else
LHSKind = EmptyKind;
@ -249,44 +272,70 @@ namespace llvm {
/// Construct from an std::string.
/*implicit*/ Twine(const std::string &Str)
: LHS(&Str), LHSKind(StdStringKind), RHSKind(EmptyKind) {
: LHSKind(StdStringKind), RHSKind(EmptyKind) {
LHS.stdString = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a StringRef.
/*implicit*/ Twine(const StringRef &Str)
: LHS(&Str), LHSKind(StringRefKind), RHSKind(EmptyKind) {
: LHSKind(StringRefKind), RHSKind(EmptyKind) {
LHS.stringRef = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a char.
explicit Twine(char Val)
: LHSKind(CharKind), RHSKind(EmptyKind) {
LHS.character = Val;
}
/// Construct from a signed char.
explicit Twine(signed char Val)
: LHSKind(CharKind), RHSKind(EmptyKind) {
LHS.character = static_cast<char>(Val);
}
/// Construct from an unsigned char.
explicit Twine(unsigned char Val)
: LHSKind(CharKind), RHSKind(EmptyKind) {
LHS.character = static_cast<char>(Val);
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(unsigned Val)
: LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
: LHSKind(DecUIKind), RHSKind(EmptyKind) {
LHS.decUI = Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(int Val)
: LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
: LHSKind(DecIKind), RHSKind(EmptyKind) {
LHS.decI = Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val)
: LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
: LHSKind(DecULKind), RHSKind(EmptyKind) {
LHS.decUL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(const long &Val)
: LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
: LHSKind(DecLKind), RHSKind(EmptyKind) {
LHS.decL = &Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val)
: LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
: LHSKind(DecULLKind), RHSKind(EmptyKind) {
LHS.decULL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(const long long &Val)
: LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
: LHSKind(DecLLKind), RHSKind(EmptyKind) {
LHS.decLL = &Val;
}
// FIXME: Unfortunately, to make sure this is as efficient as possible we
@ -296,13 +345,17 @@ namespace llvm {
/// Construct as the concatenation of a C string and a StringRef.
/*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
: LHS(_LHS), RHS(&_RHS), LHSKind(CStringKind), RHSKind(StringRefKind) {
: LHSKind(CStringKind), RHSKind(StringRefKind) {
LHS.cString = _LHS;
RHS.stringRef = &_RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a StringRef and a C string.
/*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
: LHS(&_LHS), RHS(_RHS), LHSKind(StringRefKind), RHSKind(CStringKind) {
: LHSKind(StringRefKind), RHSKind(CStringKind) {
LHS.stringRef = &_LHS;
RHS.cString = _RHS;
assert(isValid() && "Invalid twine!");
}
@ -318,7 +371,10 @@ namespace llvm {
// Construct a twine to print \arg Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
return Twine(&Val, UHexKind, 0, EmptyKind);
Child LHS, RHS;
LHS.uHex = &Val;
RHS.twine = 0;
return Twine(LHS, UHexKind, RHS, EmptyKind);
}
/// @}
@ -371,9 +427,9 @@ namespace llvm {
switch (getLHSKind()) {
default: assert(0 && "Out of sync with isSingleStringRef");
case EmptyKind: return StringRef();
case CStringKind: return StringRef((const char*)LHS);
case StdStringKind: return StringRef(*(const std::string*)LHS);
case StringRefKind: return *(const StringRef*)LHS;
case CStringKind: return StringRef(LHS.cString);
case StdStringKind: return StringRef(*LHS.stdString);
case StringRefKind: return *LHS.stringRef;
}
}
@ -422,7 +478,9 @@ namespace llvm {
// Otherwise we need to create a new node, taking care to fold in unary
// twines.
const void *NewLHS = this, *NewRHS = &Suffix;
Child NewLHS, NewRHS;
NewLHS.twine = this;
NewRHS.twine = &Suffix;
NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
if (isUnary()) {
NewLHS = LHS;

View File

@ -88,7 +88,7 @@ class AliasAnalysis {
/// getTypeStoreSize - Return the TargetData store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(const Type *Ty);
uint64_t getTypeStoreSize(Type *Ty);
//===--------------------------------------------------------------------===//
/// Alias Queries...
@ -136,6 +136,8 @@ class AliasAnalysis {
Location getLocation(const LoadInst *LI);
Location getLocation(const StoreInst *SI);
Location getLocation(const VAArgInst *VI);
Location getLocation(const AtomicCmpXchgInst *CXI);
Location getLocation(const AtomicRMWInst *RMWI);
static Location getLocationForSource(const MemTransferInst *MTI);
static Location getLocationForDest(const MemIntrinsic *MI);
@ -341,6 +343,11 @@ class AliasAnalysis {
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc);
case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc);
case Instruction::AtomicCmpXchg:
return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
case Instruction::AtomicRMW:
return getModRefInfo((const AtomicRMWInst*)I, Loc);
case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
default: return NoModRef;
@ -406,6 +413,39 @@ class AliasAnalysis {
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for fences) - Return whether information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
// Conservatively correct. (We could possibly be a bit smarter if
// Loc is a alloca that doesn't escape.)
return ModRef;
}
/// getModRefInfo (for fences) - A convenience wrapper.
ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for cmpxchges) - Return whether information about whether
/// a particular cmpxchg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
/// getModRefInfo (for cmpxchges) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
const Value *P, unsigned Size) {
return getModRefInfo(CX, Location(P, Size));
}
/// getModRefInfo (for atomicrmws) - Return whether information about whether
/// a particular atomicrmw modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
/// getModRefInfo (for atomicrmws) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
const Value *P, unsigned Size) {
return getModRefInfo(RMW, Location(P, Size));
}
/// getModRefInfo (for va_args) - Return whether information about whether
/// a particular va_arg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);

View File

@ -111,8 +111,8 @@ class AliasSet : public ilist_node<AliasSet> {
AliasSet *Forward; // Forwarding pointer.
AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
// All calls & invokes in this alias set.
std::vector<AssertingVH<Instruction> > CallSites;
// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction> > UnknownInsts;
// RefCount - Number of nodes pointing to this AliasSet plus the number of
// AliasSets forwarding to it.
@ -147,9 +147,9 @@ class AliasSet : public ilist_node<AliasSet> {
removeFromTracker(AST);
}
CallSite getCallSite(unsigned i) const {
assert(i < CallSites.size());
return CallSite(CallSites[i]);
Instruction *getUnknownInst(unsigned i) const {
assert(i < UnknownInsts.size());
return UnknownInsts[i];
}
public:
@ -253,12 +253,12 @@ class AliasSet : public ilist_node<AliasSet> {
void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
const MDNode *TBAAInfo,
bool KnownMustAlias = false);
void addCallSite(CallSite CS, AliasAnalysis &AA);
void removeCallSite(CallSite CS) {
for (size_t i = 0, e = CallSites.size(); i != e; ++i)
if (CallSites[i] == CS.getInstruction()) {
CallSites[i] = CallSites.back();
CallSites.pop_back();
void addUnknownInst(Instruction *I, AliasAnalysis &AA);
void removeUnknownInst(Instruction *I) {
for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
if (UnknownInsts[i] == I) {
UnknownInsts[i] = UnknownInsts.back();
UnknownInsts.pop_back();
--i; --e; // Revisit the moved entry.
}
}
@ -269,7 +269,7 @@ class AliasSet : public ilist_node<AliasSet> {
///
bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
AliasAnalysis &AA) const;
bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
@ -326,12 +326,10 @@ class AliasSetTracker {
bool add(LoadInst *LI);
bool add(StoreInst *SI);
bool add(VAArgInst *VAAI);
bool add(CallSite CS); // Call/Invoke instructions
bool add(CallInst *CI) { return add(CallSite(CI)); }
bool add(InvokeInst *II) { return add(CallSite(II)); }
bool add(Instruction *I); // Dispatch to one of the other add methods...
void add(BasicBlock &BB); // Add all instructions in basic block
void add(const AliasSetTracker &AST); // Add alias relations from another AST
bool addUnknown(Instruction *I);
/// remove methods - These methods are used to remove all entries that might
/// be aliased by the specified instruction. These methods return true if any
@ -341,11 +339,9 @@ class AliasSetTracker {
bool remove(LoadInst *LI);
bool remove(StoreInst *SI);
bool remove(VAArgInst *VAAI);
bool remove(CallSite CS);
bool remove(CallInst *CI) { return remove(CallSite(CI)); }
bool remove(InvokeInst *II) { return remove(CallSite(II)); }
bool remove(Instruction *I);
void remove(AliasSet &AS);
bool removeUnknown(Instruction *I);
void clear();
@ -429,7 +425,7 @@ class AliasSetTracker {
AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
const MDNode *TBAAInfo);
AliasSet *findAliasSetForCallSite(CallSite CS);
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@ -29,8 +30,8 @@
namespace llvm {
class BlockFrequency;
class MachineBlockFrequency;
class BlockFrequencyInfo;
class MachineBlockFrequencyInfo;
/// BlockFrequencyImpl implements block frequency algorithm for IR and
/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
@ -40,7 +41,7 @@ class MachineBlockFrequency;
template<class BlockT, class FunctionT, class BlockProbInfoT>
class BlockFrequencyImpl {
DenseMap<BlockT *, uint32_t> Freqs;
DenseMap<BlockT *, BlockFrequency> Freqs;
BlockProbInfoT *BPI;
@ -48,7 +49,7 @@ class BlockFrequencyImpl {
typedef GraphTraits< Inverse<BlockT *> > GT;
static const uint32_t START_FREQ = 1024;
const uint32_t EntryFreq;
std::string getBlockName(BasicBlock *BB) const {
return BB->getNameStr();
@ -64,26 +65,21 @@ class BlockFrequencyImpl {
return ss.str();
}
void setBlockFreq(BlockT *BB, uint32_t Freq) {
void setBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] = Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
}
/// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
/// edge probability.
uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const {
BlockFrequency getEdgeFreq(BlockT *Src, BlockT *Dst) const {
BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
uint64_t N = Prob.getNumerator();
uint64_t D = Prob.getDenominator();
uint64_t Res = (N * getBlockFreq(Src)) / D;
assert(Res <= UINT32_MAX);
return (uint32_t) Res;
return getBlockFreq(Src) * Prob;
}
/// incBlockFreq - Increase BB block frequency by FREQ.
///
void incBlockFreq(BlockT *BB, uint32_t Freq) {
void incBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] += Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
<< " --> " << Freqs[BB] << "\n");
@ -95,13 +91,13 @@ class BlockFrequencyImpl {
uint64_t N = Prob.getNumerator();
assert(N && "Illegal division by zero!");
uint64_t D = Prob.getDenominator();
uint64_t Freq = (Freqs[BB] * D) / N;
uint64_t Freq = (Freqs[BB].getFrequency() * D) / N;
// Should we assert it?
if (Freq > UINT32_MAX)
Freq = UINT32_MAX;
Freqs[BB] = (uint32_t) Freq;
Freqs[BB] = BlockFrequency(Freq);
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
<< ") --> " << Freqs[BB] << "\n");
}
@ -136,15 +132,6 @@ class BlockFrequencyImpl {
}
/// Return a probability of getting to the DST block through SRC->DST edge.
///
BranchProbability getBackEdgeProbability(BlockT *Src, BlockT *Dst) const {
uint32_t N = getEdgeFreq(Src, Dst);
uint32_t D = getBlockFreq(Dst);
return BranchProbability(N, D);
}
/// isReachable - Returns if BB block is reachable from the entry.
///
bool isReachable(BlockT *BB) {
@ -160,7 +147,7 @@ class BlockFrequencyImpl {
unsigned a = RPO[Src];
unsigned b = RPO[Dst];
return a > b;
return a >= b;
}
/// getSingleBlockPred - return single BB block predecessor or NULL if
@ -189,7 +176,7 @@ class BlockFrequencyImpl {
setBlockFreq(BB, 0);
if (BB == LoopHead) {
setBlockFreq(BB, START_FREQ);
setBlockFreq(BB, EntryFreq);
return;
}
@ -224,10 +211,10 @@ class BlockFrequencyImpl {
if (!isLoopHead)
return;
assert(START_FREQ >= CycleProb[BB]);
assert(EntryFreq >= CycleProb[BB]);
uint32_t CProb = CycleProb[BB];
uint32_t Numerator = START_FREQ - CProb ? START_FREQ - CProb : 1;
divBlockFreq(BB, BranchProbability(Numerator, START_FREQ));
uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1;
divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
}
/// doLoop - Propagate block frequency down throught the loop.
@ -237,11 +224,13 @@ class BlockFrequencyImpl {
SmallPtrSet<BlockT *, 8> BlocksInLoop;
for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) {
for (rpot_iterator I = rpot_at(Head), E = rpot_at(Tail); ; ++I) {
BlockT *BB = *I;
doBlock(BB, Head, BlocksInLoop);
BlocksInLoop.insert(BB);
if (I == E)
break;
}
// Compute loop's cyclic probability using backedges probabilities.
@ -252,19 +241,23 @@ class BlockFrequencyImpl {
BlockT *Pred = *PI;
assert(Pred);
if (isReachable(Pred) && isBackedge(Pred, Head)) {
BranchProbability Prob = getBackEdgeProbability(Pred, Head);
uint64_t N = Prob.getNumerator();
uint64_t D = Prob.getDenominator();
uint64_t Res = (N * START_FREQ) / D;
uint64_t N = getEdgeFreq(Pred, Head).getFrequency();
uint64_t D = getBlockFreq(Head).getFrequency();
assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!");
uint64_t Res = (N * EntryFreq) / D;
assert(Res <= UINT32_MAX);
CycleProb[Head] += (uint32_t) Res;
DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res
<< " --> " << CycleProb[Head] << "\n");
}
}
}
friend class BlockFrequency;
friend class MachineBlockFrequency;
friend class BlockFrequencyInfo;
friend class MachineBlockFrequencyInfo;
BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { }
void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
Fn = fn;
@ -314,13 +307,12 @@ class BlockFrequencyImpl {
}
public:
/// getBlockFreq - Return block frequency. Never return 0, value must be
/// positive.
uint32_t getBlockFreq(BlockT *BB) const {
typename DenseMap<BlockT *, uint32_t>::const_iterator I = Freqs.find(BB);
/// 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);
if (I != Freqs.end())
return I->second ? I->second : 1;
return 1;
return I->second;
return 0;
}
void print(raw_ostream &OS) const {

View File

@ -1,4 +1,4 @@
//========-------- BlockFrequency.h - Block Frequency Analysis -------========//
//========-------- BlockFrequencyInfo.h - Block Frequency Analysis -------========//
//
// The LLVM Compiler Infrastructure
//
@ -11,10 +11,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H
#define LLVM_ANALYSIS_BLOCKFREQUENCY_H
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
#include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include <climits>
namespace llvm {
@ -23,29 +24,30 @@ class BranchProbabilityInfo;
template<class BlockT, class FunctionT, class BranchProbInfoT>
class BlockFrequencyImpl;
/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate
/// BlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
/// IR basic block frequencies.
class BlockFrequency : public FunctionPass {
class BlockFrequencyInfo : public FunctionPass {
BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
public:
static char ID;
BlockFrequency();
BlockFrequencyInfo();
~BlockFrequency();
~BlockFrequencyInfo();
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
void print(raw_ostream &O, const Module *M) const;
/// getblockFreq - Return block frequency. Never return 0, value must be
/// positive. Please note that initial frequency is equal to 1024. It means
/// getblockFreq - Return block frequency. Return 0 if we don't have the
/// information. Please note that initial frequency is equal to 1024. It means
/// 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 the floating
/// points.
uint32_t getBlockFreq(BasicBlock *BB);
/// the other block frequencies. We do this to avoid using of floating points.
///
BlockFrequency getBlockFreq(BasicBlock *BB) const;
};
}

View File

@ -33,12 +33,12 @@ 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<BasicBlock *, BasicBlock *> Edge;
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
DenseMap<Edge, uint32_t> Weights;
// Get sum of the block successors' weights.
uint32_t getSumForBlock(BasicBlock *BB) const;
uint32_t getSumForBlock(const BasicBlock *BB) const;
public:
static char ID;
@ -53,13 +53,14 @@ class BranchProbabilityInfo : public FunctionPass {
// Returned value is between 1 and UINT32_MAX. Look at
// BranchProbabilityInfo.cpp for details.
uint32_t getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const;
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
// Look at BranchProbabilityInfo.cpp for details. Use it with caution!
void setEdgeWeight(BasicBlock *Src, BasicBlock *Dst, uint32_t Weight);
void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
uint32_t Weight);
// A 'Hot' edge is an edge which probability is >= 80%.
bool isEdgeHot(BasicBlock *Src, BasicBlock *Dst) const;
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;
@ -67,7 +68,8 @@ class BranchProbabilityInfo : public FunctionPass {
// 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(BasicBlock *Src, BasicBlock *Dst) const;
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

View File

@ -18,6 +18,9 @@
#include "llvm/ADT/DenseMap.h"
namespace llvm {
class TargetData;
// CodeMetrics - Calculate size and a few similar metrics for a set of
// basic blocks.
struct CodeMetrics {
@ -46,7 +49,7 @@ namespace llvm {
/// NumCalls - 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.
@ -61,24 +64,24 @@ namespace llvm {
unsigned NumRets;
CodeMetrics() : callsSetJmp(false), isRecursive(false),
containsIndirectBr(false), usesDynamicAlloca(false),
containsIndirectBr(false), usesDynamicAlloca(false),
NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0),
NumInlineCandidates(0), NumVectorInsts(0),
NumRets(0) {}
/// analyzeBasicBlock - Add information about the specified basic block
/// to the current structure.
void analyzeBasicBlock(const BasicBlock *BB);
void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
/// analyzeFunction - Add information about the specified function
/// to the current structure.
void analyzeFunction(Function *F);
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.

View File

@ -27,6 +27,8 @@ namespace llvm {
class TargetData;
class Function;
class Type;
template<typename T>
class ArrayRef;
/// ConstantFoldInstruction - Try to constant fold the specified instruction.
/// If successful, the constant result is returned, if not, null is returned.
@ -47,8 +49,8 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
/// fold instructions like loads and stores, which have no constant expression
/// form.
///
Constant *ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
Constant *const *Ops, unsigned NumOps,
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
const TargetData *TD = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
@ -59,6 +61,12 @@ Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
const TargetData *TD = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is
/// returned if successful; if not, null is returned.
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
ArrayRef<unsigned> Idxs);
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
@ -76,7 +84,7 @@ 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, Constant *const *Operands, unsigned NumOperands);
ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands);
}
#endif

View File

@ -37,6 +37,7 @@ namespace llvm {
class DINameSpace;
class DIVariable;
class DISubrange;
class DILexicalBlockFile;
class DILexicalBlock;
class DISubprogram;
class DITemplateTypeParameter;
@ -48,9 +49,19 @@ namespace llvm {
LLVMContext & VMContext;
MDNode *TheCU;
MDNode *TempEnumTypes;
MDNode *TempRetainTypes;
MDNode *TempSubprograms;
MDNode *TempGVs;
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
SmallVector<Value *, 4> AllEnumTypes;
SmallVector<Value *, 4> AllRetainTypes;
SmallVector<Value *, 4> AllSubprograms;
SmallVector<Value *, 4> AllGVs;
DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
void operator=(const DIBuilder &); // DO NOT IMPLEMENT
@ -59,6 +70,9 @@ namespace llvm {
const MDNode *getCU() { return TheCU; }
enum ComplexAddrKind { OpPlus=1, OpDeref };
/// finalize - Construct any deferred debug info descriptors.
void finalize();
/// createCompileUnit - A CompileUnit provides an anchor for all debugging
/// information generated during this instance of compilation.
/// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
@ -84,6 +98,9 @@ namespace llvm {
/// createEnumerator - Create a single enumerator value.
DIEnumerator createEnumerator(StringRef Name, uint64_t Val);
/// createNullPtrType - Create C++0x nullptr type.
DIType createNullPtrType(StringRef Name);
/// createBasicType - Create debugging information entry for a basic
/// type.
/// @param Name Type name.
@ -447,6 +464,14 @@ namespace llvm {
DIFile File, unsigned LineNo);
/// createLexicalBlockFile - This creates a descriptor for a lexical
/// block with a new file attached. This merely extends the existing
/// lexical block as it crosses a file.
/// @param Scope Lexical block.
/// @param File Source file.
DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
DIFile File);
/// createLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
/// @param Scope Parent lexical scope.

View File

@ -40,6 +40,7 @@ namespace llvm {
class DIFile;
class DISubprogram;
class DILexicalBlock;
class DILexicalBlockFile;
class DIVariable;
class DIType;
@ -84,6 +85,7 @@ namespace llvm {
explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
explicit DIDescriptor(const DIFile F);
explicit DIDescriptor(const DISubprogram F);
explicit DIDescriptor(const DILexicalBlockFile F);
explicit DIDescriptor(const DILexicalBlock F);
explicit DIDescriptor(const DIVariable F);
explicit DIDescriptor(const DIType F);
@ -117,6 +119,7 @@ namespace llvm {
bool isFile() const;
bool isCompileUnit() const;
bool isNameSpace() const;
bool isLexicalBlockFile() const;
bool isLexicalBlock() const;
bool isSubrange() const;
bool isEnumerator() const;
@ -182,6 +185,11 @@ namespace llvm {
StringRef getFlags() const { return getStringField(8); }
unsigned getRunTimeVersion() const { return getUnsignedField(9); }
DIArray getEnumTypes() const;
DIArray getRetainedTypes() const;
DIArray getSubprograms() const;
DIArray getGlobalVariables() const;
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
@ -201,7 +209,10 @@ namespace llvm {
}
StringRef getFilename() const { return getStringField(1); }
StringRef getDirectory() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!");
return getFieldAs<DICompileUnit>(3);
}
};
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
@ -237,6 +248,7 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -291,6 +303,9 @@ namespace llvm {
return getFieldAs<DIFile>(3).getFilename();
}
/// isUnsignedDIType - Return true if type encoding is unsigned.
bool isUnsignedDIType();
/// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor.
void replaceAllUsesWith(DIDescriptor &D);
@ -447,6 +462,7 @@ namespace llvm {
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
@ -545,6 +561,8 @@ namespace llvm {
DISubprogram getFunctionDeclaration() const {
return getFieldAs<DISubprogram>(18);
}
MDNode *getVariablesNodes() const;
DIArray getVariables() const;
};
/// DIGlobalVariable - This is a wrapper for a global variable.
@ -557,12 +575,24 @@ namespace llvm {
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
DIFile F = getFieldAs<DIFile>(6);
return F.getCompileUnit();
}
StringRef getFilename() const {
if (getVersion() <= llvm::LLVMDebugVersion10)
return getContext().getFilename();
return getFieldAs<DIFile>(6).getFilename();
}
StringRef getDirectory() const {
if (getVersion() <= llvm::LLVMDebugVersion10)
return getContext().getDirectory();
return getFieldAs<DIFile>(6).getDirectory();
}
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); }
@ -592,6 +622,7 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -614,6 +645,8 @@ namespace llvm {
return (getUnsignedField(6) & FlagArtificial) != 0;
}
/// getInlinedAt - If this variable is inlined then return inline location.
MDNode *getInlinedAt() const;
/// Verify - Verify that a variable descriptor is well formed.
bool Verify() const;
@ -628,7 +661,9 @@ namespace llvm {
uint64_t getAddrElement(unsigned Idx) const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return getUInt64Field(Idx+6);
return getUInt64Field(Idx+7);
if (getVersion() == llvm::LLVMDebugVersion9)
return getUInt64Field(Idx+7);
return getUInt64Field(Idx+8);
}
/// isBlockByrefVariable - Return true if the variable was declared as
@ -644,6 +679,8 @@ namespace llvm {
/// print - print variable.
void print(raw_ostream &OS) const;
void printExtendedName(raw_ostream &OS) const;
/// dump - print variable to dbgs() with a newline.
void dump() const;
};
@ -665,6 +702,26 @@ namespace llvm {
}
};
/// DILexicalBlockFile - This is a wrapper for a lexical block with
/// a filename change.
class DILexicalBlockFile : public DIScope {
public:
explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getScope().getContext(); }
unsigned getLineNumber() const { return getScope().getLineNumber(); }
unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
StringRef getDirectory() const {
StringRef dir = getFieldAs<DIFile>(2).getDirectory();
return !dir.empty() ? dir : getContext().getDirectory();
}
StringRef getFilename() const {
StringRef filename = getFieldAs<DIFile>(2).getFilename();
assert(!filename.empty() && "Why'd you create this then?");
return filename;
}
DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
};
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
public:
@ -678,6 +735,7 @@ namespace llvm {
return getFieldAs<DIFile>(3).getFilename();
}
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -708,13 +766,27 @@ namespace llvm {
/// getDICompositeType - Find underlying composite type.
DICompositeType getDICompositeType(DIType T);
/// isSubprogramContext - Return true if Context is either a subprogram
/// or another context nested inside a subprogram.
bool isSubprogramContext(const MDNode *Context);
/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
/// to hold function specific information.
NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, StringRef Name);
NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
/// suitable to hold function specific information.
NamedMDNode *getFnSpecificMDNode(const Module &M, StringRef Name);
NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
/// createInlinedVariable - Create a new inlined variable based on current
/// variable.
/// @param DV Current Variable.
/// @param InlinedScope Location at current variable is inlined.
DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
LLVMContext &VMContext);
/// cleanseInlinedVariable - Remove inlined scope from the variable.
DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
class DebugInfoFinder {
public:

View File

@ -23,7 +23,7 @@ class Type;
class Value;
class FindUsedTypes : public ModulePass {
SetVector<const Type *> UsedTypes;
SetVector<Type *> UsedTypes;
public:
static char ID; // Pass identification, replacement for typeid
FindUsedTypes() : ModulePass(ID) {
@ -33,7 +33,7 @@ class FindUsedTypes : public ModulePass {
/// getTypes - After the pass has been run, return the set containing all of
/// the types used in the module.
///
const SetVector<const Type *> &getTypes() const { return UsedTypes; }
const SetVector<Type *> &getTypes() const { return UsedTypes; }
/// Print the types found in the module. If the optional Module parameter is
/// passed in, then the types are printed symbolically if possible, using the
@ -45,7 +45,7 @@ class FindUsedTypes : public ModulePass {
/// IncorporateType - Incorporate one type and all of its subtypes into the
/// collection of used types.
///
void IncorporateType(const Type *Ty);
void IncorporateType(Type *Ty);
/// IncorporateValue - Incorporate all of the types used by this value.
///

View File

@ -140,6 +140,8 @@ class IVUsers : public LoopPass {
static char ID; // Pass ID, replacement for typeid
IVUsers();
Loop *getLoop() const { return L; }
/// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
/// reducible SCEV, recursively add its users to the IVUsesByStride set and
/// return true. Otherwise, return false.

View File

@ -29,6 +29,7 @@ namespace llvm {
class CallSite;
template<class PtrType, unsigned SmallSize>
class SmallPtrSet;
class TargetData;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
@ -113,7 +114,7 @@ namespace llvm {
/// analyzeFunction - Add information about the specified function
/// to the current structure.
void analyzeFunction(Function *F);
void analyzeFunction(Function *F, const TargetData *TD);
/// NeverInline - Returns true if the function should never be
/// inlined into any caller.
@ -124,11 +125,17 @@ namespace llvm {
// 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.

View File

@ -24,6 +24,8 @@ namespace llvm {
class Instruction;
class Value;
class TargetData;
template<typename T>
class ArrayRef;
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
@ -121,9 +123,16 @@ namespace llvm {
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(Value * const *Ops, unsigned NumOps,
Value *SimplifyGEPInst(ArrayRef<Value *> Ops,
const TargetData *TD = 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 DominatorTree *DT = 0);
//=== Helper functions for higher up the class hierarchy.

View File

@ -33,6 +33,7 @@
#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h"
@ -105,7 +106,7 @@ class LoopBase {
if (L == 0) return false;
return contains(L->getParentLoop());
}
/// contains - Return true if the specified basic block is in this loop.
///
bool contains(const BlockT *BB) const {
@ -134,6 +135,11 @@ class LoopBase {
block_iterator block_begin() const { return Blocks.begin(); }
block_iterator block_end() const { return Blocks.end(); }
/// getNumBlocks - Get the number of blocks in this loop in constant time.
unsigned getNumBlocks() const {
return Blocks.size();
}
/// isLoopExiting - True if terminator in the block can branch to another
/// block that is outside of the current loop.
///
@ -479,12 +485,13 @@ class LoopBase {
}
/// verifyLoop - Verify loop structure of this loop and all nested loops.
void verifyLoopNest() const {
void verifyLoopNest(DenseSet<const LoopT*> *Loops) const {
Loops->insert(static_cast<const LoopT *>(this));
// Verify this loop.
verifyLoop();
// Verify the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)
(*I)->verifyLoopNest();
(*I)->verifyLoopNest(Loops);
}
void print(raw_ostream &OS, unsigned Depth = 0) const {
@ -527,7 +534,7 @@ class Loop : public LoopBase<BasicBlock, Loop> {
bool isLoopInvariant(Value *V) const;
/// hasLoopInvariantOperands - Return true if all the operands of the
/// specified instruction are loop invariant.
/// specified instruction are loop invariant.
bool hasLoopInvariantOperands(Instruction *I) const;
/// makeLoopInvariant - If the given value is an instruction inside of the
@ -607,7 +614,7 @@ class Loop : public LoopBase<BasicBlock, Loop> {
/// has a predecessor that is outside the loop.
bool hasDedicatedExits() const;
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
/// This assumes that loop exits are in canonical form.
///
@ -618,7 +625,7 @@ class Loop : public LoopBase<BasicBlock, Loop> {
BasicBlock *getUniqueExitBlock() const;
void dump() const;
private:
friend class LoopInfoBase<BasicBlock, Loop>;
explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
@ -635,13 +642,14 @@ class LoopInfoBase {
DenseMap<BlockT *, LoopT *> BBMap;
std::vector<LoopT *> TopLevelLoops;
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
void operator=(const LoopInfoBase &); // do not implement
LoopInfoBase(const LoopInfo &); // do not implement
public:
LoopInfoBase() { }
~LoopInfoBase() { releaseMemory(); }
void releaseMemory() {
for (typename std::vector<LoopT *>::iterator I =
TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I)
@ -650,7 +658,7 @@ class LoopInfoBase {
BBMap.clear(); // Reset internal state of analysis
TopLevelLoops.clear();
}
/// iterator/begin/end - The interface to the top-level loops in the current
/// function.
///
@ -658,7 +666,7 @@ class LoopInfoBase {
iterator begin() const { return TopLevelLoops.begin(); }
iterator end() const { return TopLevelLoops.end(); }
bool empty() const { return TopLevelLoops.empty(); }
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
/// block is in no loop (for example the entry node), null is returned.
///
@ -667,13 +675,13 @@ class LoopInfoBase {
BBMap.find(const_cast<BlockT*>(BB));
return I != BBMap.end() ? I->second : 0;
}
/// operator[] - same as getLoopFor...
///
const LoopT *operator[](const BlockT *BB) const {
return getLoopFor(BB);
}
/// getLoopDepth - Return the loop nesting level of the specified block. A
/// depth of 0 means the block is not inside any loop.
///
@ -687,7 +695,7 @@ class LoopInfoBase {
const LoopT *L = getLoopFor(BB);
return L && L->getHeader() == BB;
}
/// removeLoop - This removes the specified top-level loop from this loop info
/// object. The loop is not deleted, as it will presumably be inserted into
/// another loop.
@ -698,16 +706,20 @@ class LoopInfoBase {
TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin()));
return L;
}
/// changeLoopFor - Change the top-level loop that contains BB to the
/// specified loop. This should be used by transformations that restructure
/// the loop hierarchy tree.
void changeLoopFor(BlockT *BB, LoopT *L) {
LoopT *&OldLoop = BBMap[BB];
assert(OldLoop && "Block not in a loop yet!");
OldLoop = L;
if (!L) {
typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
if (I != BBMap.end())
BBMap.erase(I);
return;
}
BBMap[BB] = L;
}
/// changeTopLevelLoop - Replace the specified loop in the top-level loops
/// list with the indicated loop.
void changeTopLevelLoop(LoopT *OldLoop,
@ -719,14 +731,14 @@ class LoopInfoBase {
assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 &&
"Loops already embedded into a subloop!");
}
/// addTopLevelLoop - This adds the specified loop to the collection of
/// top-level loops.
void addTopLevelLoop(LoopT *New) {
assert(New->getParentLoop() == 0 && "Loop already in subloop!");
TopLevelLoops.push_back(New);
}
/// removeBlock - This method completely removes BB from all data structures,
/// including all of the Loop objects it is nested in and our mapping from
/// BasicBlocks to loops.
@ -739,16 +751,16 @@ class LoopInfoBase {
BBMap.erase(I);
}
}
// Internals
static bool isNotAlreadyContainedIn(const LoopT *SubLoop,
const LoopT *ParentLoop) {
if (SubLoop == 0) return true;
if (SubLoop == ParentLoop) return false;
return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
}
void Calculate(DominatorTreeBase<BlockT> &DT) {
BlockT *RootNode = DT.getRootNode()->getBlock();
@ -757,7 +769,7 @@ class LoopInfoBase {
if (LoopT *L = ConsiderForLoop(*NI, DT))
TopLevelLoops.push_back(L);
}
LoopT *ConsiderForLoop(BlockT *BB, DominatorTreeBase<BlockT> &DT) {
if (BBMap.find(BB) != BBMap.end()) return 0;// Haven't processed this node?
@ -812,9 +824,9 @@ class LoopInfoBase {
// Normal case, add the block to our loop...
L->Blocks.push_back(X);
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
// Add all of the predecessors of X to the end of the work stack...
TodoStack.insert(TodoStack.end(), InvBlockTraits::child_begin(X),
InvBlockTraits::child_end(X));
@ -878,7 +890,7 @@ class LoopInfoBase {
return L;
}
/// MoveSiblingLoopInto - This method moves the NewChild loop to live inside
/// of the NewParent Loop, instead of being a sibling of it.
void MoveSiblingLoopInto(LoopT *NewChild,
@ -897,7 +909,7 @@ class LoopInfoBase {
InsertLoopInto(NewChild, NewParent);
}
/// InsertLoopInto - This inserts loop L into the specified parent loop. If
/// the parent loop contains a loop which should contain L, the loop gets
/// inserted into L instead.
@ -918,9 +930,9 @@ class LoopInfoBase {
Parent->SubLoops.push_back(L);
L->ParentLoop = Parent;
}
// Debugging
void print(raw_ostream &OS) const {
for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
TopLevelLoops[i]->print(OS);
@ -990,7 +1002,7 @@ class LoopInfo : public FunctionPass {
virtual void releaseMemory() { LI.releaseMemory(); }
virtual void print(raw_ostream &O, const Module* M = 0) const;
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// removeLoop - This removes the specified top-level loop from this loop info
@ -1024,6 +1036,12 @@ class LoopInfo : public FunctionPass {
LI.removeBlock(BB);
}
/// updateUnloop - Update LoopInfo after removing the last backedge from a
/// loop--now the "unloop". This updates the loop forest and parent loops for
/// each block so that Unloop is no longer referenced, but the caller must
/// actually delete the Unloop object.
void updateUnloop(Loop *Unloop);
/// replacementPreservesLCSSAForm - Returns true if replacing From with To
/// everywhere is guaranteed to preserve LCSSA form.
bool replacementPreservesLCSSAForm(Instruction *From, Value *To) {

View File

@ -0,0 +1,186 @@
//===--------- LoopIterator.h - Iterate over loop blocks --------*- 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 iterators to visit the basic blocks within a loop.
//
// These iterators currently visit blocks within subloops as well.
// Unfortunately we have no efficient way of summarizing loop exits which would
// allow skipping subloops during traversal.
//
// If you want to visit all blocks in a loop and don't need an ordered traveral,
// use Loop::block_begin() instead.
//
// This is intentionally designed to work with ill-formed loops in which the
// backedge has been deleted. The only prerequisite is that all blocks
// contained within the loop according to the most recent LoopInfo analysis are
// reachable from the loop header.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
#define LLVM_ANALYSIS_LOOP_ITERATOR_H
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm {
class LoopBlocksTraversal;
/// Store the result of a depth first search within basic blocks contained by a
/// single loop.
///
/// TODO: This could be generalized for any CFG region, or the entire CFG.
class LoopBlocksDFS {
public:
/// Postorder list iterators.
typedef std::vector<BasicBlock*>::const_iterator POIterator;
typedef std::vector<BasicBlock*>::const_reverse_iterator RPOIterator;
friend class LoopBlocksTraversal;
private:
Loop *L;
/// Map each block to its postorder number. A block is only mapped after it is
/// preorder visited by DFS. It's postorder number is initially zero and set
/// to nonzero after it is finished by postorder traversal.
DenseMap<BasicBlock*, unsigned> PostNumbers;
std::vector<BasicBlock*> PostBlocks;
public:
LoopBlocksDFS(Loop *Container) :
L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) {
PostBlocks.reserve(Container->getNumBlocks());
}
Loop *getLoop() const { return L; }
/// Traverse the loop blocks and store the DFS result.
void perform(LoopInfo *LI);
/// Return true if postorder numbers are assigned to all loop blocks.
bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); }
/// Iterate over the cached postorder blocks.
POIterator beginPostorder() const {
assert(isComplete() && "bad loop DFS");
return PostBlocks.begin();
}
POIterator endPostorder() const { return PostBlocks.end(); }
/// Reverse iterate over the cached postorder blocks.
RPOIterator beginRPO() const {
assert(isComplete() && "bad loop DFS");
return PostBlocks.rbegin();
}
RPOIterator endRPO() const { return PostBlocks.rend(); }
/// Return true if this block has been preorder visited.
bool hasPreorder(BasicBlock *BB) const { return PostNumbers.count(BB); }
/// Return true if this block has a postorder number.
bool hasPostorder(BasicBlock *BB) const {
DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
return I != PostNumbers.end() && I->second;
}
/// Get a block's postorder number.
unsigned getPostorder(BasicBlock *BB) const {
DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
assert(I != PostNumbers.end() && "block not visited by DFS");
assert(I->second && "block not finished by DFS");
return I->second;
}
/// Get a block's reverse postorder number.
unsigned getRPO(BasicBlock *BB) const {
return 1 + PostBlocks.size() - getPostorder(BB);
}
void clear() {
PostNumbers.clear();
PostBlocks.clear();
}
};
/// Traverse the blocks in a loop using a depth-first search.
class LoopBlocksTraversal {
public:
/// Graph traversal iterator.
typedef po_iterator<BasicBlock*, LoopBlocksTraversal, true> POTIterator;
private:
LoopBlocksDFS &DFS;
LoopInfo *LI;
public:
LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo) :
DFS(Storage), LI(LInfo) {}
/// Postorder traversal over the graph. This only needs to be done once.
/// po_iterator "automatically" calls back to visitPreorder and
/// finishPostorder to record the DFS result.
POTIterator begin() {
assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing");
assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph");
return po_ext_begin(DFS.L->getHeader(), *this);
}
POTIterator end() {
// po_ext_end interface requires a basic block, but ignores its value.
return po_ext_end(DFS.L->getHeader(), *this);
}
/// Called by po_iterator upon reaching a block via a CFG edge. If this block
/// is contained in the loop and has not been visited, then mark it preorder
/// visited and return true.
///
/// TODO: If anyone is interested, we could record preorder numbers here.
bool visitPreorder(BasicBlock *BB) {
if (!DFS.L->contains(LI->getLoopFor(BB)))
return false;
return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
}
/// Called by po_iterator each time it advances, indicating a block's
/// postorder.
void finishPostorder(BasicBlock *BB) {
assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder");
DFS.PostBlocks.push_back(BB);
DFS.PostNumbers[BB] = DFS.PostBlocks.size();
}
//===----------------------------------------------------------------------
// Implement part of the std::set interface for the purpose of driving the
// generic po_iterator.
/// Return true if the block is outside the loop or has already been visited.
/// Sorry if this is counterintuitive.
bool count(BasicBlock *BB) const {
return !DFS.L->contains(LI->getLoopFor(BB)) || DFS.PostNumbers.count(BB);
}
/// If this block is contained in the loop and has not been visited, return
/// true and assign a preorder number. This is a proxy for visitPreorder
/// called by POIterator.
bool insert(BasicBlock *BB) {
return visitPreorder(BB);
}
};
/// Specialize DFSetTraits to record postorder numbers.
template<> struct DFSetTraits<LoopBlocksTraversal> {
static void finishPostorder(BasicBlock *BB, LoopBlocksTraversal& LBT) {
LBT.finishPostorder(BB);
}
};
} // End namespace llvm
#endif

View File

@ -84,7 +84,7 @@ class LoopPass : public Pass {
class LPPassManager : public FunctionPass, public PMDataManager {
public:
static char ID;
explicit LPPassManager(int Depth);
explicit LPPassManager();
/// run - Execute all of the passes scheduled for execution. Keep track of
/// whether any of the passes modifies the module, and if so, return true.

View File

@ -51,14 +51,14 @@ const CallInst *isArrayMalloc(const Value *I, const TargetData *TD);
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
const PointerType *getMallocType(const CallInst *CI);
PointerType *getMallocType(const CallInst *CI);
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
/// The Type depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
const Type *getMallocAllocatedType(const CallInst *CI);
Type *getMallocAllocatedType(const CallInst *CI);
/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,

View File

@ -52,9 +52,6 @@ namespace llvm {
/// 1. Loads are clobbered by may-alias stores.
/// 2. Loads are considered clobbered by partially-aliased loads. The
/// client may choose to analyze deeper into these cases.
///
/// A dependence query on the first instruction of the entry block will
/// return a clobber(self) result.
Clobber,
/// Def - This is a dependence on the specified instruction which
@ -76,11 +73,27 @@ namespace llvm {
/// operands to the calls are the same.
Def,
/// Other - This marker indicates that the query has no known dependency
/// in the specified block. More detailed state info is encoded in the
/// upper part of the pair (i.e. the Instruction*)
Other
};
/// If DepType is "Other", the upper part of the pair
/// (i.e. the Instruction* part) is instead used to encode more detailed
/// type information as follows
enum OtherType {
/// NonLocal - This marker indicates that the query has no dependency in
/// the specified block. To find out more, the client should query other
/// predecessor blocks.
NonLocal
NonLocal = 0x4,
/// NonFuncLocal - This marker indicates that the query has no
/// dependency in the specified function.
NonFuncLocal = 0x8,
/// Unknown - This marker indicates that the query dependency
/// is unknown.
Unknown = 0xc
};
typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
PairTy Value;
explicit MemDepResult(PairTy V) : Value(V) {}
@ -98,19 +111,21 @@ namespace llvm {
return MemDepResult(PairTy(Inst, Clobber));
}
static MemDepResult getNonLocal() {
return MemDepResult(PairTy(0, NonLocal));
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(NonLocal), Other));
}
static MemDepResult getNonFuncLocal() {
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(NonFuncLocal), Other));
}
static MemDepResult getUnknown() {
return MemDepResult(PairTy(0, Clobber));
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(Unknown), Other));
}
/// isClobber - Return true if this MemDepResult represents a query that is
/// a instruction clobber dependency.
bool isClobber() const { return Value.getInt() == Clobber && getInst(); }
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const { return Value.getInt() == Clobber && !getInst(); }
bool isClobber() const { return Value.getInt() == Clobber; }
/// isDef - Return true if this MemDepResult represents a query that is
/// a instruction definition dependency.
@ -119,11 +134,31 @@ namespace llvm {
/// isNonLocal - Return true if this MemDepResult represents a query that
/// is transparent to the start of the block, but where a non-local hasn't
/// been done.
bool isNonLocal() const { return Value.getInt() == NonLocal; }
bool isNonLocal() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonLocal);
}
/// isNonFuncLocal - Return true if this MemDepResult represents a query
/// that is transparent to the start of the function.
bool isNonFuncLocal() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
}
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(Unknown);
}
/// getInst() - If this is a normal dependency, return the instruction that
/// is depended on. Otherwise, return null.
Instruction *getInst() const { return Value.getPointer(); }
Instruction *getInst() const {
if (Value.getInt() == Other) return NULL;
return Value.getPointer();
}
bool operator==(const MemDepResult &M) const { return Value == M.Value; }
bool operator!=(const MemDepResult &M) const { return Value != M.Value; }

View File

@ -88,7 +88,7 @@ class RGPassManager : public FunctionPass, public PMDataManager {
public:
static char ID;
explicit RGPassManager(int Depth);
explicit RGPassManager();
/// @brief Execute all of the passes scheduled for execution.
///

View File

@ -103,7 +103,7 @@ namespace llvm {
/// getType - Return the LLVM type of this SCEV expression.
///
const Type *getType() const;
Type *getType() const;
/// isZero - Return true if the expression is a constant zero.
///
@ -241,31 +241,94 @@ namespace llvm {
///
ValueExprMapType ValueExprMap;
/// ExitLimit - Information about the number of loop iterations for
/// which a loop exit's branch condition evaluates to the not-taken path.
/// This is a temporary pair of exact and max expressions that are
/// eventually summarized in ExitNotTakenInfo and BackedgeTakenInfo.
struct ExitLimit {
const SCEV *Exact;
const SCEV *Max;
/*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {}
ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {}
/// hasAnyInfo - Test whether this ExitLimit contains any computed
/// information, or whether it's all SCEVCouldNotCompute values.
bool hasAnyInfo() const {
return !isa<SCEVCouldNotCompute>(Exact) ||
!isa<SCEVCouldNotCompute>(Max);
}
};
/// ExitNotTakenInfo - Information about the number of times a particular
/// loop exit may be reached before exiting the loop.
struct ExitNotTakenInfo {
AssertingVH<BasicBlock> ExitingBlock;
const SCEV *ExactNotTaken;
PointerIntPair<ExitNotTakenInfo*, 1> NextExit;
ExitNotTakenInfo() : ExitingBlock(0), ExactNotTaken(0) {}
/// isCompleteList - Return true if all loop exits are computable.
bool isCompleteList() const {
return NextExit.getInt() == 0;
}
void setIncomplete() { NextExit.setInt(1); }
/// getNextExit - Return a pointer to the next exit's not-taken info.
ExitNotTakenInfo *getNextExit() const {
return NextExit.getPointer();
}
void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); }
};
/// BackedgeTakenInfo - Information about the backedge-taken count
/// of a loop. This currently includes an exact count and a maximum count.
///
struct BackedgeTakenInfo {
/// Exact - An expression indicating the exact backedge-taken count of
/// the loop if it is known, or a SCEVCouldNotCompute otherwise.
const SCEV *Exact;
class BackedgeTakenInfo {
/// ExitNotTaken - A list of computable exits and their not-taken counts.
/// Loops almost never have more than one computable exit.
ExitNotTakenInfo ExitNotTaken;
/// Max - An expression indicating the least maximum backedge-taken
/// count of the loop that is known, or a SCEVCouldNotCompute.
const SCEV *Max;
/*implicit*/ BackedgeTakenInfo(const SCEV *exact) :
Exact(exact), Max(exact) {}
public:
BackedgeTakenInfo() : Max(0) {}
BackedgeTakenInfo(const SCEV *exact, const SCEV *max) :
Exact(exact), Max(max) {}
/// Initialize BackedgeTakenInfo from a list of exact exit counts.
BackedgeTakenInfo(
SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts,
bool Complete, const SCEV *MaxCount);
/// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
/// computed information, or whether it's all SCEVCouldNotCompute
/// values.
bool hasAnyInfo() const {
return !isa<SCEVCouldNotCompute>(Exact) ||
!isa<SCEVCouldNotCompute>(Max);
return ExitNotTaken.ExitingBlock || !isa<SCEVCouldNotCompute>(Max);
}
/// getExact - Return an expression indicating the exact backedge-taken
/// count of the loop if it is known, or SCEVCouldNotCompute
/// otherwise. This is the number of times the loop header can be
/// guaranteed to execute, minus one.
const SCEV *getExact(ScalarEvolution *SE) const;
/// getExact - Return the number of times this loop exit may fall through
/// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not
/// to exit via this block before this number of iterations, but may exit
/// via another block.
const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const;
/// getMax - Get the max backedge taken count for the loop.
const SCEV *getMax(ScalarEvolution *SE) const;
/// clear - Invalidate this result and free associated memory.
void clear();
};
/// BackedgeTakenCounts - Cache the backedge-taken count of the loops for
@ -365,64 +428,59 @@ namespace llvm {
/// loop will iterate.
BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
/// ComputeBackedgeTakenCountFromExit - Compute the number of times the
/// backedge of the specified loop will execute if it exits via the
/// specified block.
BackedgeTakenInfo ComputeBackedgeTakenCountFromExit(const Loop *L,
BasicBlock *ExitingBlock);
/// ComputeExitLimit - Compute the number of times the backedge of the
/// specified loop will execute if it exits via the specified block.
ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock);
/// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the
/// backedge of the specified loop will execute if its exit condition
/// were a conditional branch of ExitCond, TBB, and FBB.
BackedgeTakenInfo
ComputeBackedgeTakenCountFromExitCond(const Loop *L,
Value *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeExitLimitFromCond - Compute the number of times the backedge of
/// the specified loop will execute if its exit condition were a conditional
/// branch of ExitCond, TBB, and FBB.
ExitLimit ComputeExitLimitFromCond(const Loop *L,
Value *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of
/// times the backedge of the specified loop will execute if its exit
/// condition were a conditional branch of the ICmpInst ExitCond, TBB,
/// and FBB.
BackedgeTakenInfo
ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
ICmpInst *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeExitLimitFromICmp - Compute the number of times the backedge of
/// the specified loop will execute if its exit condition were a conditional
/// branch of the ICmpInst ExitCond, TBB, and FBB.
ExitLimit ComputeExitLimitFromICmp(const Loop *L,
ICmpInst *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
/// ComputeLoadConstantCompareExitLimit - Given an exit condition
/// of 'icmp op load X, cst', try to see if we can compute the
/// backedge-taken count.
BackedgeTakenInfo
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI,
Constant *RHS,
const Loop *L,
ICmpInst::Predicate p);
ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI,
Constant *RHS,
const Loop *L,
ICmpInst::Predicate p);
/// ComputeBackedgeTakenCountExhaustively - If the loop is known to execute
/// a constant number of times (the condition evolves only from constants),
/// ComputeExitCountExhaustively - If the loop is known to execute a
/// constant number of times (the condition evolves only from constants),
/// try to evaluate a few iterations of the loop until we get the exit
/// condition gets a value of ExitWhen (true or false). If we cannot
/// evaluate the backedge-taken count of the loop, return CouldNotCompute.
const SCEV *ComputeBackedgeTakenCountExhaustively(const Loop *L,
Value *Cond,
bool ExitWhen);
/// evaluate the exit count of the loop, return CouldNotCompute.
const SCEV *ComputeExitCountExhaustively(const Loop *L,
Value *Cond,
bool ExitWhen);
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
/// HowFarToZero - Return the number of times an exit condition comparing
/// the specified value to zero will execute. If not computable, return
/// CouldNotCompute.
BackedgeTakenInfo HowFarToZero(const SCEV *V, const Loop *L);
ExitLimit HowFarToZero(const SCEV *V, const Loop *L);
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
/// HowFarToNonZero - Return the number of times an exit condition checking
/// the specified value for nonzero will execute. If not computable, return
/// CouldNotCompute.
BackedgeTakenInfo HowFarToNonZero(const SCEV *V, const Loop *L);
ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L);
/// HowManyLessThans - Return the number of times a backedge containing the
/// specified less-than comparison will execute. If not computable, return
/// CouldNotCompute. isSigned specifies whether the less-than is signed.
BackedgeTakenInfo HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool isSigned);
/// HowManyLessThans - Return the number of times an exit condition
/// containing the specified less-than comparison will execute. If not
/// computable, return CouldNotCompute. isSigned specifies whether the
/// less-than is signed.
ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool isSigned);
/// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB
/// (which may not be an immediate predecessor) which has exactly one
@ -450,7 +508,8 @@ namespace llvm {
/// FoundLHS, and FoundRHS is true.
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS, const SCEV *FoundRHS);
const SCEV *FoundLHS,
const SCEV *FoundRHS);
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
@ -479,17 +538,17 @@ namespace llvm {
/// the SCEV framework. This primarily includes integer types, and it
/// can optionally include pointer types if the ScalarEvolution class
/// has access to target-specific information.
bool isSCEVable(const Type *Ty) const;
bool isSCEVable(Type *Ty) const;
/// getTypeSizeInBits - Return the size in bits of the specified type,
/// for which isSCEVable must return true.
uint64_t getTypeSizeInBits(const Type *Ty) const;
uint64_t getTypeSizeInBits(Type *Ty) const;
/// getEffectiveSCEVType - Return a type with the same bitwidth as
/// the given type and which represents how SCEV will treat the given
/// type, for which isSCEVable must return true. For pointer types,
/// this is the pointer-sized integer type.
const Type *getEffectiveSCEVType(const Type *Ty) const;
Type *getEffectiveSCEVType(Type *Ty) const;
/// getSCEV - Return a SCEV expression for the full generality of the
/// specified expression.
@ -497,11 +556,11 @@ namespace llvm {
const SCEV *getConstant(ConstantInt *V);
const SCEV *getConstant(const APInt& Val);
const SCEV *getConstant(const Type *Ty, uint64_t V, bool isSigned = false);
const SCEV *getTruncateExpr(const SCEV *Op, const Type *Ty);
const SCEV *getZeroExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
@ -529,6 +588,14 @@ namespace llvm {
Ops.push_back(RHS);
return getMulExpr(Ops, Flags);
}
const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 3> Ops;
Ops.push_back(Op0);
Ops.push_back(Op1);
Ops.push_back(Op2);
return getMulExpr(Ops, Flags);
}
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
const Loop *L, SCEV::NoWrapFlags Flags);
@ -550,19 +617,19 @@ namespace llvm {
/// getSizeOfExpr - Return an expression for sizeof on the given type.
///
const SCEV *getSizeOfExpr(const Type *AllocTy);
const SCEV *getSizeOfExpr(Type *AllocTy);
/// getAlignOfExpr - Return an expression for alignof on the given type.
///
const SCEV *getAlignOfExpr(const Type *AllocTy);
const SCEV *getAlignOfExpr(Type *AllocTy);
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
///
const SCEV *getOffsetOfExpr(const StructType *STy, unsigned FieldNo);
const SCEV *getOffsetOfExpr(StructType *STy, unsigned FieldNo);
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
///
const SCEV *getOffsetOfExpr(const Type *CTy, Constant *FieldNo);
const SCEV *getOffsetOfExpr(Type *CTy, Constant *FieldNo);
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
///
@ -579,33 +646,33 @@ namespace llvm {
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be
/// extended, it is zero extended.
const SCEV *getTruncateOrZeroExtend(const SCEV *V, const Type *Ty);
const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty);
/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be
/// extended, it is sign extended.
const SCEV *getTruncateOrSignExtend(const SCEV *V, const Type *Ty);
const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty);
/// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is zero extended. The conversion must not be narrowing.
const SCEV *getNoopOrZeroExtend(const SCEV *V, const Type *Ty);
const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty);
/// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is sign extended. The conversion must not be narrowing.
const SCEV *getNoopOrSignExtend(const SCEV *V, const Type *Ty);
const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty);
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is extended with unspecified bits. The conversion must not be
/// narrowing.
const SCEV *getNoopOrAnyExtend(const SCEV *V, const Type *Ty);
const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty);
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
/// input value to the specified type. The conversion must not be
/// widening.
const SCEV *getTruncateOrNoop(const SCEV *V, const Type *Ty);
const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty);
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
/// the types using zero-extension, and then perform a umax operation
@ -653,6 +720,23 @@ namespace llvm {
bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
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);
/// 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);
// getExitCount - Get the expression for the number of loop iterations for
// which this loop is guaranteed not to exit via ExitingBlock. Otherwise
// return SCEVCouldNotCompute.
const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock);
/// getBackedgeTakenCount - If the specified loop has a predictable
/// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute
/// object. The backedge-taken count is the number of times the loop header

View File

@ -64,16 +64,34 @@ namespace llvm {
/// in a more literal form.
bool CanonicalMode;
/// When invoked from LSR, the expander is in "strength reduction" mode. The
/// only difference is that phi's are only reused if they are already in
/// "expanded" form.
bool LSRMode;
typedef IRBuilder<true, TargetFolder> BuilderType;
BuilderType Builder;
#ifndef NDEBUG
const char *DebugType;
#endif
friend struct SCEVVisitor<SCEVExpander, Value*>;
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se, const char *name)
: SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {}
CanonicalMode(true), LSRMode(false),
Builder(se.getContext(), TargetFolder(se.TD)) {
#ifndef NDEBUG
DebugType = "";
#endif
}
#ifndef NDEBUG
void setDebugType(const char* s) { DebugType = s; }
#endif
/// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or
@ -88,13 +106,21 @@ namespace llvm {
/// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable
/// starts at zero and steps by one on each iteration.
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty);
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
/// hoistStep - Utility for hoisting an IV increment.
static bool hoistStep(Instruction *IncV, Instruction *InsertPos,
const DominatorTree *DT);
/// 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);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I);
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
/// setIVIncInsertPos - Set the current IV increment loop and position.
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
@ -127,13 +153,14 @@ namespace llvm {
/// is useful for late optimization passes.
void disableCanonicalMode() { CanonicalMode = false; }
void enableLSRMode() { LSRMode = true; }
/// clearInsertPoint - Clear the current insertion point. This is useful
/// if the instruction that had been serving as the insertion point may
/// have been deleted.
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
private:
LLVMContext &getContext() const { return SE.getContext(); }
@ -145,20 +172,20 @@ namespace llvm {
/// reusing an existing cast if a suitable one exists, moving an existing
/// cast if a suitable one exists but isn't in the right place, or
/// or creating a new one.
Value *ReuseOrCreateCast(Value *V, const Type *Ty,
Value *ReuseOrCreateCast(Value *V, Type *Ty,
Instruction::CastOps Op,
BasicBlock::iterator IP);
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
/// which must be possible with a noop cast, doing what we can to
/// share the casts.
Value *InsertNoopCastOfTo(Value *V, const Type *Ty);
Value *InsertNoopCastOfTo(Value *V, Type *Ty);
/// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
/// instead of using ptrtoint+arithmetic+inttoptr.
Value *expandAddToGEP(const SCEV *const *op_begin,
const SCEV *const *op_end,
const PointerType *PTy, const Type *Ty, Value *V);
PointerType *PTy, Type *Ty, Value *V);
Value *expand(const SCEV *S);
@ -166,7 +193,7 @@ namespace llvm {
/// expression into the program. The inserted code is inserted into the
/// SCEVExpander's current insertion point. If a type is specified, the
/// result will be expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV *SH, const Type *Ty = 0);
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
@ -208,11 +235,15 @@ namespace llvm {
void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
const Loop *L,
const Type *ExpandTy,
const Type *IntTy);
Type *ExpandTy,
Type *IntTy);
};
}

View File

@ -42,7 +42,7 @@ namespace llvm {
public:
ConstantInt *getValue() const { return V; }
const Type *getType() const { return V->getType(); }
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVConstant *S) { return true; }
@ -57,14 +57,14 @@ namespace llvm {
class SCEVCastExpr : public SCEV {
protected:
const SCEV *Op;
const Type *Ty;
Type *Ty;
SCEVCastExpr(const FoldingSetNodeIDRef ID,
unsigned SCEVTy, const SCEV *op, const Type *ty);
unsigned SCEVTy, const SCEV *op, Type *ty);
public:
const SCEV *getOperand() const { return Op; }
const Type *getType() const { return Ty; }
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCastExpr *S) { return true; }
@ -83,7 +83,7 @@ namespace llvm {
friend class ScalarEvolution;
SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -101,7 +101,7 @@ namespace llvm {
friend class ScalarEvolution;
SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -119,7 +119,7 @@ namespace llvm {
friend class ScalarEvolution;
SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -158,7 +158,7 @@ namespace llvm {
op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; }
const Type *getType() const { return getOperand(0)->getType(); }
Type *getType() const { return getOperand(0)->getType(); }
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
return (NoWrapFlags)(SubclassData & Mask);
@ -214,7 +214,7 @@ namespace llvm {
}
public:
const Type *getType() const {
Type *getType() const {
// Use the type of the last operand, which is likely to be a pointer
// type, if there is one. This doesn't usually matter, but it can help
// reduce casts when the expressions are expanded.
@ -263,7 +263,7 @@ namespace llvm {
const SCEV *getLHS() const { return LHS; }
const SCEV *getRHS() const { return RHS; }
const Type *getType() const {
Type *getType() const {
// In most cases the types of LHS and RHS will be the same, but in some
// crazy cases one or the other may be a pointer. ScalarEvolution doesn't
// depend on the type for correctness, but handling types carefully can
@ -441,11 +441,11 @@ namespace llvm {
/// folded with other operations into something unrecognizable. This
/// is mainly only useful for pretty-printing and other situations
/// where it isn't absolutely required for these to succeed.
bool isSizeOf(const Type *&AllocTy) const;
bool isAlignOf(const Type *&AllocTy) const;
bool isOffsetOf(const Type *&STy, Constant *&FieldNo) const;
bool isSizeOf(Type *&AllocTy) const;
bool isAlignOf(Type *&AllocTy) const;
bool isOffsetOf(Type *&STy, Constant *&FieldNo) const;
const Type *getType() const { return getValPtr()->getType(); }
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUnknown *S) { return true; }

View File

@ -39,7 +39,7 @@ class Argument : public Value, public ilist_node<Argument> {
/// Argument ctor - If Function argument is specified, this argument is
/// inserted at the end of the argument list for the function.
///
explicit Argument(const Type *Ty, const Twine &Name = "", Function *F = 0);
explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0);
inline const Function *getParent() const { return Parent; }
inline Function *getParent() { return Parent; }

View File

@ -65,8 +65,7 @@ const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
///of alignment with +1 bias
///0 means unaligned (different from
///alignstack(1))
const Attributes Hotpatch = 1<<29; ///< Function should have special
///'hotpatch' sequence in prologue
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
@ -93,7 +92,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
Hotpatch | UWTable | NonLazyBind;
UWTable | NonLazyBind | ReturnsTwice;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
@ -107,7 +106,7 @@ const Attributes MutuallyIncompatible[4] = {
};
/// @brief Which attributes cannot be applied to a type.
Attributes typeIncompatible(const Type *Ty);
Attributes typeIncompatible(Type *Ty);
/// This turns an int alignment (a power of 2, normally) into the
/// form used internally in Attributes.

View File

@ -43,6 +43,10 @@ namespace llvm {
/// 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

@ -22,6 +22,7 @@
namespace llvm {
class LandingPadInst;
class TerminatorInst;
class LLVMContext;
class BlockAddress;
@ -144,6 +145,14 @@ class BasicBlock : public Value, // Basic blocks are data objects also
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
}
/// getFirstInsertionPt - Returns an iterator to the first instruction in this
/// block that is suitable for inserting a non-PHI instruction. In particular,
/// it skips all PHIs and LandingPad instructions.
iterator getFirstInsertionPt();
const_iterator getFirstInsertionPt() const {
return const_cast<BasicBlock*>(this)->getFirstInsertionPt();
}
/// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it.
///
@ -258,6 +267,14 @@ class BasicBlock : public Value, // Basic blocks are data objects also
/// to refer to basic block New instead of to us.
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
/// isLandingPad - Return true if this basic block is a landing pad. I.e.,
/// it's the destination of the 'unwind' edge of an invoke instruction.
bool isLandingPad() const;
/// getLandingPadInst() - Return the landingpad instruction associated with
/// the landing pad.
LandingPadInst *getLandingPadInst();
private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
/// objects using it. This is almost always 0, sometimes one, possibly but

View File

@ -205,6 +205,23 @@ namespace bitc {
BINOP_XOR = 12
};
/// These are values used in the bitcode files to encode AtomicRMW operations.
/// The values of these enums have no fixed relation to the LLVM IR enum
/// values. Changing these will break compatibility with old files.
enum RMWOperations {
RMW_XCHG = 0,
RMW_ADD = 1,
RMW_SUB = 2,
RMW_AND = 3,
RMW_NAND = 4,
RMW_OR = 5,
RMW_XOR = 6,
RMW_MAX = 7,
RMW_MIN = 8,
RMW_UMAX = 9,
RMW_UMIN = 10
};
/// OverflowingBinaryOperatorOptionalFlags - Flags for serializing
/// OverflowingBinaryOperator's SubclassOptionalData contents.
enum OverflowingBinaryOperatorOptionalFlags {
@ -218,6 +235,23 @@ namespace bitc {
PEO_EXACT = 0
};
/// Encoded AtomicOrdering values.
enum AtomicOrderingCodes {
ORDERING_NOTATOMIC = 0,
ORDERING_UNORDERED = 1,
ORDERING_MONOTONIC = 2,
ORDERING_ACQUIRE = 3,
ORDERING_RELEASE = 4,
ORDERING_ACQREL = 5,
ORDERING_SEQCST = 6
};
/// Encoded SynchronizationScope values.
enum AtomicSynchScopeCodes {
SYNCHSCOPE_SINGLETHREAD = 0,
SYNCHSCOPE_CROSSTHREAD = 1
};
// The function body block (FUNCTION_BLOCK_ID) describes function bodies. It
// can contain a constant block (CONSTANTS_BLOCK_ID).
enum FunctionCodes {
@ -266,7 +300,19 @@ namespace bitc {
FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...]
FUNC_CODE_DEBUG_LOC = 35 // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
// ordering, synchscope]
FUNC_CODE_INST_RESUME = 39, // RESUME: [opval]
FUNC_CODE_INST_LANDINGPAD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_STOREATOMIC = 42 // STORE: [ptrty,ptr,val, align, vol
// ordering, synchscope]
};
} // End bitc namespace
} // End llvm namespace

View File

@ -33,12 +33,12 @@ class SelectionDAG;
/// of insertvalue or extractvalue indices that identify a member, return
/// the linearized index of the start of the member.
///
unsigned ComputeLinearIndex(const Type *Ty,
unsigned ComputeLinearIndex(Type *Ty,
const unsigned *Indices,
const unsigned *IndicesEnd,
unsigned CurIndex = 0);
inline unsigned ComputeLinearIndex(const Type *Ty,
inline unsigned ComputeLinearIndex(Type *Ty,
ArrayRef<unsigned> Indices,
unsigned CurIndex = 0) {
return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
@ -51,7 +51,7 @@ inline unsigned ComputeLinearIndex(const Type *Ty,
/// If Offsets is non-null, it points to a vector to be filled in
/// with the in-memory offsets of each of the individual values.
///
void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty,
void ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
SmallVectorImpl<EVT> &ValueVTs,
SmallVectorImpl<uint64_t> *Offsets = 0,
uint64_t StartingOffset = 0);

View File

@ -49,11 +49,6 @@ namespace llvm {
const MachineLoopInfo &loops) :
MF(mf), LIS(lis), Loops(loops) {}
/// CalculateRegClass - recompute the register class for reg from its uses.
/// Since the register class can affect the allocation hint, this function
/// should be called before CalculateWeightAndHint if both are called.
void CalculateRegClass(unsigned reg);
/// CalculateWeightAndHint - (re)compute li's spill weight and allocation
/// hint.
void CalculateWeightAndHint(LiveInterval &li);

View File

@ -54,8 +54,18 @@ class FastISel {
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;
/// The position of the last instruction for materializing constants
/// for use in the current block. It resets to EmitStartPt when it
/// makes sense (for example, it's usually profitable to avoid function
/// calls between the definition and the use)
MachineInstr *LastLocalValue;
/// The top most instruction in the current block that is allowed for
/// emitting local variables. LastLocalValue resets to EmitStartPt when
/// it makes sense (for example, on function calls)
MachineInstr *EmitStartPt;
public:
/// getLastLocalValue - Return the position of the last instruction
/// emitted for materializing constants for use in the current block.
@ -63,7 +73,10 @@ class FastISel {
/// setLastLocalValue - Update the position of the last instruction
/// emitted for materializing constants for use in the current block.
void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; }
void setLastLocalValue(MachineInstr *I) {
EmitStartPt = I;
LastLocalValue = I;
}
/// startNewBlock - Set the current block to which generated machine
/// instructions will be appended, and clear the local CSE map.
@ -358,6 +371,11 @@ class FastISel {
/// be materialized with new instructions.
unsigned materializeRegForValue(const Value *V, MVT VT);
/// flushLocalValueMap - clears LocalValueMap and moves the area for the
/// new local variables to the beginning of the block. It helps to avoid
/// spilling cached variables across heavy instructions like calls.
void flushLocalValueMap();
/// hasTrivialKill - Test whether the given value has exactly one use.
bool hasTrivialKill(const Value *V) const;
};

View File

@ -19,6 +19,7 @@
#include "llvm/Instructions.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#ifndef NDEBUG
@ -139,7 +140,7 @@ class FunctionLoweringInfo {
unsigned CreateReg(EVT VT);
unsigned CreateRegs(const Type *Ty);
unsigned CreateRegs(Type *Ty);
unsigned InitializeRegForValue(const Value *V) {
unsigned &R = ValueMap[V];
@ -198,12 +199,12 @@ class FunctionLoweringInfo {
LiveOutRegInfo[Reg].IsValid = false;
}
/// setByValArgumentFrameIndex - Record frame index for the byval
/// setArgumentFrameIndex - Record frame index for the byval
/// argument.
void setByValArgumentFrameIndex(const Argument *A, int FI);
void setArgumentFrameIndex(const Argument *A, int FI);
/// getByValArgumentFrameIndex - Get frame index for the byval argument.
int getByValArgumentFrameIndex(const Argument *A);
/// getArgumentFrameIndex - Get frame index for the byval argument.
int getArgumentFrameIndex(const Argument *A);
private:
/// LiveOutRegInfo - Information about live out vregs.
@ -220,6 +221,11 @@ void AddCatchInfo(const CallInst &I,
void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad,
MachineModuleInfo *MMI, FunctionLoweringInfo &FLI);
/// AddLandingPadInfo - Extract the exception handling information from the
/// landingpad instruction and add them to the specified machine module info.
void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
MachineBasicBlock *MBB);
} // end namespace llvm
#endif

View File

@ -95,7 +95,7 @@ namespace ISD {
// execution to HANDLER. Many platform-related details also :)
EH_RETURN,
// OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
// This corresponds to the eh.sjlj.setjmp intrinsic.
// It takes an input chain and a pointer to the jump buffer as inputs
// and returns an outchain.
@ -323,6 +323,12 @@ namespace ISD {
// i1 then the high bits must conform to getBooleanContents.
SELECT,
// Select with a vector condition (op #0) and two vector operands (ops #1
// and #2), returning a vector result. All vectors have the same length.
// Much like the scalar select and setcc, each bit in the condition selects
// whether the corresponding result element is taken from op #1 or op #2.
VSELECT,
// Select with condition operator - This selects between a true value and
// a false value (ops #2 and #3) based on the boolean result of comparing
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
@ -333,16 +339,10 @@ namespace ISD {
// true. If the result value type is not i1 then the high bits conform
// to getBooleanContents. The operands to this are the left and right
// operands to compare (ops #0, and #1) and the condition code to compare
// them with (op #2) as a CondCodeSDNode.
// them with (op #2) as a CondCodeSDNode. If the operands are vector types
// then the result type must also be a vector type.
SETCC,
// RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of
// integer elements with all bits of the result elements set to true if the
// comparison is true or all cleared if the comparison is false. The
// operands to this are the left and right operands to compare (LHS/RHS) and
// the condition code to compare them with (COND) as a CondCodeSDNode.
VSETCC,
// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
// integer shift operations, just like ADD/SUB_PARTS. The operation
// ordering is:
@ -566,14 +566,19 @@ namespace ISD {
// HANDLENODE node - Used as a handle for various purposes.
HANDLENODE,
// TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
// It takes as input a token chain, the pointer to the trampoline,
// the pointer to the nested function, the pointer to pass for the
// 'nest' parameter, a SRCVALUE for the trampoline and another for
// the nested function (allowing targets to access the original
// Function*). It produces the result of the intrinsic and a token
// chain as output.
TRAMPOLINE,
// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
// takes as input a token chain, the pointer to the trampoline, the pointer
// to the nested function, the pointer to pass for the 'nest' parameter, a
// SRCVALUE for the trampoline and another for the nested function (allowing
// targets to access the original Function*). It produces a token chain as
// output.
INIT_TRAMPOLINE,
// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
// It takes a pointer to the trampoline and produces a (possibly) new
// pointer to the same trampoline with platform-specific adjustments
// applied. The pointer it returns points to an executable block of code.
ADJUST_TRAMPOLINE,
// TRAP - Trapping instruction
TRAP,
@ -592,22 +597,27 @@ namespace ISD {
// and produces an output chain.
MEMBARRIER,
// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
// This corresponds to the fence instruction. It takes an input chain, and
// two integer constants: an AtomicOrdering and a SynchronizationScope.
ATOMIC_FENCE,
// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
// This corresponds to "load atomic" instruction.
ATOMIC_LOAD,
// OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val)
// This corresponds to "store atomic" instruction.
ATOMIC_STORE,
// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
// this corresponds to the atomic.lcs intrinsic.
// cmp is compared to *ptr, and if equal, swap is stored in *ptr.
// the return is always the original value in *ptr
// This corresponds to the cmpxchg instruction.
ATOMIC_CMP_SWAP,
// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
// this corresponds to the atomic.swap intrinsic.
// amt is stored to *ptr atomically.
// the return is always the original value in *ptr
ATOMIC_SWAP,
// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
// this corresponds to the atomic.load.[OpName] intrinsic.
// op(*ptr, amt) is stored to *ptr atomically.
// the return is always the original value in *ptr
// These correspond to the atomicrmw instruction.
ATOMIC_SWAP,
ATOMIC_LOAD_ADD,
ATOMIC_LOAD_SUB,
ATOMIC_LOAD_AND,

View File

@ -0,0 +1,248 @@
//===- LexicalScopes.cpp - Collecting lexical scope info -*- 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 LexicalScopes analysis.
//
// This pass collects lexical scope information and maps machine instructions
// to respective lexical scopes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_LEXICALSCOPES_H
#define LLVM_CODEGEN_LEXICALSCOPES_H
#include "llvm/Metadata.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/ValueHandle.h"
#include <utility>
namespace llvm {
class MachineInstr;
class MachineBasicBlock;
class MachineFunction;
class LexicalScope;
//===----------------------------------------------------------------------===//
/// InsnRange - This is used to track range of instructions with identical
/// lexical scope.
///
typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
//===----------------------------------------------------------------------===//
/// LexicalScopes - This class provides interface to collect and use lexical
/// scoping information from machine instruction.
///
class LexicalScopes {
public:
LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { }
virtual ~LexicalScopes();
/// initialize - Scan machine function and constuct lexical scope nest.
virtual void initialize(const MachineFunction &);
/// releaseMemory - release memory.
virtual void releaseMemory();
/// empty - Return true if there is any lexical scope information available.
bool empty() { return CurrentFnLexicalScope == NULL; }
/// isCurrentFunctionScope - Return true if given lexical scope represents
/// current function.
bool isCurrentFunctionScope(const LexicalScope *LS) {
return LS == CurrentFnLexicalScope;
}
/// getCurrentFunctionScope - Return lexical scope for the current function.
LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;}
/// getMachineBasicBlocks - Populate given set using machine basic blocks
/// which have machine instructions that belong to lexical scope identified by
/// DebugLoc.
void getMachineBasicBlocks(DebugLoc DL,
SmallPtrSet<const MachineBasicBlock*, 4> &MBBs);
/// dominates - Return true if DebugLoc's lexical scope dominates at least one
/// machine instruction's lexical scope in a given machine basic block.
bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
LexicalScope *findLexicalScope(DebugLoc DL);
/// getAbstractScopesList - Return a reference to list of abstract scopes.
ArrayRef<LexicalScope *> getAbstractScopesList() const {
return AbstractScopesList;
}
/// findAbstractScope - Find an abstract scope or return NULL.
LexicalScope *findAbstractScope(const MDNode *N) {
return AbstractScopeMap.lookup(N);
}
/// findInlinedScope - Find an inlined scope for the given DebugLoc or return
/// NULL.
LexicalScope *findInlinedScope(DebugLoc DL) {
return InlinedLexicalScopeMap.lookup(DL);
}
/// findLexicalScope - Find regular lexical scope or return NULL.
LexicalScope *findLexicalScope(const MDNode *N) {
return LexicalScopeMap.lookup(N);
}
/// dump - Print data structures to dbgs().
void dump();
private:
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
/// getOrCreateRegularScope - Find or create a regular lexical scope.
LexicalScope *getOrCreateRegularScope(MDNode *Scope);
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *getOrCreateAbstractScope(const MDNode *N);
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &M);
void constructScopeNest(LexicalScope *Scope);
void assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &M);
private:
const MachineFunction *MF;
/// LexicalScopeMap - Tracks the scopes in the current function. Owns the
/// contained LexicalScope*s.
DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current function.
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
/// AbstractScopes owns its LexicalScope*s.
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
/// AbstractScopesList - Tracks abstract scopes constructed while processing
/// a function.
SmallVector<LexicalScope *, 4>AbstractScopesList;
/// CurrentFnLexicalScope - Top level scope for the current function.
///
LexicalScope *CurrentFnLexicalScope;
};
//===----------------------------------------------------------------------===//
/// LexicalScope - This class is used to track scope information.
///
class LexicalScope {
public:
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) {
if (Parent)
Parent->addChild(this);
}
virtual ~LexicalScope() {}
// Accessors.
LexicalScope *getParent() const { return Parent; }
const MDNode *getDesc() const { return Desc; }
const MDNode *getInlinedAt() const { return InlinedAtLocation; }
const MDNode *getScopeNode() const { return Desc; }
bool isAbstractScope() const { return AbstractScope; }
SmallVector<LexicalScope *, 4> &getChildren() { return Children; }
SmallVector<InsnRange, 4> &getRanges() { return Ranges; }
/// addChild - Add a child scope.
void addChild(LexicalScope *S) { Children.push_back(S); }
/// openInsnRange - This scope covers instruction range starting from MI.
void openInsnRange(const MachineInstr *MI) {
if (!FirstInsn)
FirstInsn = MI;
if (Parent)
Parent->openInsnRange(MI);
}
/// extendInsnRange - Extend the current instruction range covered by
/// this scope.
void extendInsnRange(const MachineInstr *MI) {
assert (FirstInsn && "MI Range is not open!");
LastInsn = MI;
if (Parent)
Parent->extendInsnRange(MI);
}
/// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
/// until now. This is used when a new scope is encountered while walking
/// machine instructions.
void closeInsnRange(LexicalScope *NewScope = NULL) {
assert (LastInsn && "Last insn missing!");
Ranges.push_back(InsnRange(FirstInsn, LastInsn));
FirstInsn = NULL;
LastInsn = NULL;
// If Parent dominates NewScope then do not close Parent's instruction
// range.
if (Parent && (!NewScope || !Parent->dominates(NewScope)))
Parent->closeInsnRange(NewScope);
}
/// dominates - Return true if current scope dominsates given lexical scope.
bool dominates(const LexicalScope *S) const {
if (S == this)
return true;
if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
return true;
return false;
}
// Depth First Search support to walk and manipulate LexicalScope hierarchy.
unsigned getDFSOut() const { return DFSOut; }
void setDFSOut(unsigned O) { DFSOut = O; }
unsigned getDFSIn() const { return DFSIn; }
void setDFSIn(unsigned I) { DFSIn = I; }
/// dump - print lexical scope.
void dump() const;
private:
LexicalScope *Parent; // Parent to this scope.
AssertingVH<const MDNode> Desc; // Debug info descriptor.
AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
// scope is inlined.
bool AbstractScope; // Abstract Scope
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
// Contents not owned.
SmallVector<InsnRange, 4> Ranges;
const MachineInstr *LastInsn; // Last instruction of this scope.
const MachineInstr *FirstInsn; // First instruction of this scope.
unsigned DFSIn, DFSOut; // In & Out Depth use to determine
// scope nesting.
mutable unsigned IndentLevel; // Private state for dump()
};
} // end llvm namespace
#endif

View File

@ -100,6 +100,7 @@ namespace llvm {
bool isDefByCopy() const { return copy != 0; }
/// Returns true if one or more kills are PHI nodes.
/// Obsolete, do not use!
bool hasPHIKill() const { return flags & HAS_PHI_KILL; }
/// Set the PHI kill flag on this value.
void setHasPHIKill(bool hasKill) {
@ -313,7 +314,6 @@ namespace llvm {
/// RenumberValues - Renumber all values in order of appearance and remove
/// unused values.
/// Recalculate phi-kill flags in case any phi-def values were removed.
void RenumberValues(LiveIntervals &lis);
/// isOnlyLROfValNo - Return true if the specified live range is the only
@ -411,6 +411,14 @@ namespace llvm {
return I == end() ? 0 : I->valno;
}
/// getVNInfoBefore - Return the VNInfo that is live up to but not
/// necessarilly including Idx, or NULL. Use this to find the reaching def
/// used by an instruction at this SlotIndex position.
VNInfo *getVNInfoBefore(SlotIndex Idx) const {
const_iterator I = FindLiveRangeContaining(Idx.getPrevSlot());
return I == end() ? 0 : I->valno;
}
/// FindLiveRangeContaining - Return an iterator to the live range that
/// contains the specified index, or end() if there is none.
iterator FindLiveRangeContaining(SlotIndex Idx) {
@ -452,10 +460,10 @@ namespace llvm {
addRangeFrom(LR, ranges.begin());
}
/// extendInBlock - If this interval is live before UseIdx in the basic
/// block that starts at StartIdx, extend it to be live at UseIdx and return
/// the value. If there is no live range before UseIdx, return NULL.
VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx);
/// extendInBlock - If this interval is live before Kill in the basic block
/// that starts at StartIdx, extend it to be live up to Kill, and return
/// the value. If there is no live range before Kill, return NULL.
VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill);
/// join - Join two live intervals (this, and other) together. This applies
/// mappings to the value numbers in the LHS/RHS intervals as specified. If

View File

@ -25,6 +25,8 @@
namespace llvm {
class LiveStacks : public MachineFunctionPass {
const TargetRegisterInfo *TRI;
/// Special pool allocator for VNInfo's (LiveInterval val#).
///
VNInfo::Allocator VNInfoAllocator;

View File

@ -231,6 +231,7 @@ class LiveVariables : public MachineFunctionPass {
}
assert(Removed && "Register is not used by this instruction!");
(void)Removed;
return true;
}
@ -265,6 +266,7 @@ class LiveVariables : public MachineFunctionPass {
}
}
assert(Removed && "Register is not defined by this instruction!");
(void)Removed;
return true;
}

View File

@ -232,7 +232,7 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
/// setIsLandingPad - Indicates the block is a landing pad. That is
/// this basic block is entered via an exception handler.
void setIsLandingPad() { IsLandingPad = true; }
void setIsLandingPad(bool V = true) { IsLandingPad = V; }
/// getLandingPadSuccessor - If this block has a successor that is a landing
/// pad, return it. Otherwise return NULL.

View File

@ -1,4 +1,4 @@
//====----- MachineBlockFrequency.h - MachineBlock Frequency Analysis ----====//
//====----- MachineBlockFrequencyInfo.h - MachineBlock Frequency Analysis ----====//
//
// The LLVM Compiler Infrastructure
//
@ -11,10 +11,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H
#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H
#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/BlockFrequency.h"
#include <climits>
namespace llvm {
@ -23,29 +24,29 @@ class MachineBranchProbabilityInfo;
template<class BlockT, class FunctionT, class BranchProbInfoT>
class BlockFrequencyImpl;
/// MachineBlockFrequency pass uses BlockFrequencyImpl implementation to estimate
/// MachineBlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
/// machine basic block frequencies.
class MachineBlockFrequency : public MachineFunctionPass {
class MachineBlockFrequencyInfo : public MachineFunctionPass {
BlockFrequencyImpl<MachineBasicBlock, MachineFunction, MachineBranchProbabilityInfo> *MBFI;
public:
static char ID;
MachineBlockFrequency();
MachineBlockFrequencyInfo();
~MachineBlockFrequency();
~MachineBlockFrequencyInfo();
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnMachineFunction(MachineFunction &F);
/// getblockFreq - Return block frequency. Never return 0, value must be
/// positive. Please note that initial frequency is equal to 1024. It means
/// getblockFreq - Return block frequency. Return 0 if we don't have the
/// information. Please note that initial frequency is equal to 1024. It means
/// 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 the floating
/// points.
uint32_t getBlockFreq(MachineBasicBlock *MBB);
/// the other block frequencies. We do this to avoid using of floating points.
///
BlockFrequency getBlockFreq(MachineBasicBlock *MBB) const;
};
}

View File

@ -34,15 +34,15 @@ class raw_ostream;
/// Abstract base class for all machine specific constantpool value subclasses.
///
class MachineConstantPoolValue {
const Type *Ty;
Type *Ty;
public:
explicit MachineConstantPoolValue(const Type *ty) : Ty(ty) {}
explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {}
virtual ~MachineConstantPoolValue() {}
/// getType - get type of this MachineConstantPoolValue.
///
const Type *getType() const { return Ty; }
Type *getType() const { return Ty; }
/// getRelocationInfo - This method classifies the entry according to
@ -54,7 +54,7 @@ class MachineConstantPoolValue {
virtual int getExistingMachineCPValue(MachineConstantPool *CP,
unsigned Alignment) = 0;
virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
/// print - Implement operator<<
virtual void print(raw_ostream &O) const = 0;
@ -104,7 +104,7 @@ class MachineConstantPoolEntry {
return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
}
const Type *getType() const;
Type *getType() const;
/// getRelocationInfo - This method classifies the entry according to
/// whether or not it may generate a relocation entry. This must be

View File

@ -174,6 +174,10 @@ class MachineFrameInfo {
/// StackProtectorIdx - The frame index for the stack protector.
int StackProtectorIdx;
/// FunctionContextIdx - The frame index for the function context. Used for
/// SjLj exceptions.
int FunctionContextIdx;
/// MaxCallFrameSize - This contains the size of the largest call frame if the
/// target uses frame setup/destroy pseudo instructions (as defined in the
/// TargetFrameInfo class). This information is important for frame pointer
@ -220,6 +224,7 @@ class MachineFrameInfo {
AdjustsStack = false;
HasCalls = false;
StackProtectorIdx = -1;
FunctionContextIdx = -1;
MaxCallFrameSize = 0;
CSIValid = false;
LocalFrameSize = 0;
@ -244,6 +249,11 @@ class MachineFrameInfo {
int getStackProtectorIndex() const { return StackProtectorIdx; }
void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
/// getFunctionContextIndex/setFunctionContextIndex - Return the index for the
/// function context object. This object is used for SjLj exceptions.
int getFunctionContextIndex() const { return FunctionContextIdx; }
void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
/// isFrameAddressTaken - This method may be called any time after instruction
/// selection is complete to determine if there is a call to
/// \@llvm.frameaddress in this function.

View File

@ -32,6 +32,7 @@ namespace llvm {
template <typename T> class SmallVectorImpl;
class AliasAnalysis;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
class MachineFunction;
class MachineMemOperand;
@ -58,8 +59,6 @@ class MachineInstr : public ilist_node<MachineInstr> {
};
private:
const MCInstrDesc *MCID; // Instruction descriptor.
uint16_t NumImplicitOps; // Number of implicit operands (which
// are determined at construction time).
uint8_t Flags; // Various bits of additional
// information about machine
@ -78,9 +77,6 @@ class MachineInstr : public ilist_node<MachineInstr> {
MachineBasicBlock *Parent; // Pointer to the owning basic block.
DebugLoc debugLoc; // Source line information.
// OperandComplete - Return true if it's illegal to add a new operand
bool OperandsComplete() const;
MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT
void operator=(const MachineInstr&); // DO NOT IMPLEMENT
@ -393,6 +389,30 @@ class MachineInstr : public ilist_node<MachineInstr> {
/// none is found.
int findFirstPredOperandIdx() const;
/// findInlineAsmFlagIdx() - Find the index of the flag word operand that
/// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if
/// getOperand(OpIdx) does not belong to an inline asm operand group.
///
/// If GroupNo is not NULL, it will receive the number of the operand group
/// containing OpIdx.
///
/// The flag operand is an immediate that can be decoded with methods like
/// InlineAsm::hasRegClassConstraint().
///
int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const;
/// getRegClassConstraint - Compute the static register class constraint for
/// operand OpIdx. For normal instructions, this is derived from the
/// MCInstrDesc. For inline assembly it is derived from the flag words.
///
/// Returns NULL if the static register classs constraint cannot be
/// determined.
///
const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI) const;
/// isRegTiedToUseOperand - Given the index of a register def operand,
/// check if the register def is tied to a source operand, due to either
/// two-address elimination or inline assembly constraints. Returns the

View File

@ -34,7 +34,7 @@
#include "llvm/Pass.h"
#include "llvm/GlobalValue.h"
#include "llvm/Metadata.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DebugLoc.h"
@ -107,36 +107,42 @@ class MachineModuleInfo : public ImmutablePass {
/// want.
MachineModuleInfoImpl *ObjFileMMI;
// FrameMoves - List of moves done by a function's prolog. Used to construct
// frame maps by debug and exception handling consumers.
/// FrameMoves - List of moves done by a function's prolog. Used to construct
/// frame maps by debug and exception handling consumers.
std::vector<MachineMove> FrameMoves;
// LandingPads - List of LandingPadInfo describing the landing pad information
// in the current function.
/// CompactUnwindEncoding - If the target supports it, this is the compact
/// unwind encoding. It replaces a function's CIE and FDE.
uint32_t CompactUnwindEncoding;
/// LandingPads - List of LandingPadInfo describing the landing pad
/// information in the current function.
std::vector<LandingPadInfo> LandingPads;
// Map of invoke call site index values to associated begin EH_LABEL for
// the current function.
/// LPadToCallSiteMap - Map a landing pad's EH symbol to the call site
/// indexes.
DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
/// CallSiteMap - Map of invoke call site index values to associated begin
/// EH_LABEL for the current function.
DenseMap<MCSymbol*, unsigned> CallSiteMap;
// The current call site index being processed, if any. 0 if none.
/// CurCallSite - The current call site index being processed, if any. 0 if
/// none.
unsigned CurCallSite;
// TypeInfos - List of C++ TypeInfo used in the current function.
//
/// TypeInfos - List of C++ TypeInfo used in the current function.
std::vector<const GlobalVariable *> TypeInfos;
// FilterIds - List of typeids encoding filters used in the current function.
//
/// FilterIds - List of typeids encoding filters used in the current function.
std::vector<unsigned> FilterIds;
// FilterEnds - List of the indices in FilterIds corresponding to filter
// terminators.
//
/// FilterEnds - List of the indices in FilterIds corresponding to filter
/// terminators.
std::vector<unsigned> FilterEnds;
// Personalities - Vector of all personality functions ever seen. Used to emit
// common EH frames.
/// Personalities - Vector of all personality functions ever seen. Used to
/// emit common EH frames.
std::vector<const Function *> Personalities;
/// UsedFunctions - The functions in the @llvm.used list in a more easily
@ -144,7 +150,6 @@ class MachineModuleInfo : public ImmutablePass {
/// llvm.compiler.used.
SmallPtrSet<const Function *, 32> UsedFunctions;
/// AddrLabelSymbols - This map keeps track of which symbol is being used for
/// the specified basic block's address of label.
MMIAddrLabelMap *AddrLabelSymbols;
@ -156,8 +161,9 @@ class MachineModuleInfo : public ImmutablePass {
/// in this module.
bool DbgInfoAvailable;
/// True if this module calls VarArg function with floating point arguments.
/// This is used to emit an undefined reference to fltused on Windows targets.
/// CallsExternalVAFunctionWithFloatingPointArguments - True if this module
/// calls VarArg function with floating point arguments. This is used to emit
/// an undefined reference to fltused on Windows targets.
bool CallsExternalVAFunctionWithFloatingPointArguments;
public:
@ -170,7 +176,8 @@ class MachineModuleInfo : public ImmutablePass {
MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL.
// Real constructor.
MachineModuleInfo(const MCAsmInfo &MAI, const TargetAsmInfo *TAI);
MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
const MCObjectFileInfo *MOFI);
~MachineModuleInfo();
bool doInitialization();
@ -229,6 +236,15 @@ class MachineModuleInfo : public ImmutablePass {
/// handling comsumers.
std::vector<MachineMove> &getFrameMoves() { return FrameMoves; }
/// getCompactUnwindEncoding - Returns the compact unwind encoding for a
/// function if the target supports the encoding. This encoding replaces a
/// function's CIE and FDE.
uint32_t getCompactUnwindEncoding() const { return CompactUnwindEncoding; }
/// setCompactUnwindEncoding - Set the compact unwind encoding for a function
/// if the target supports the encoding.
void setCompactUnwindEncoding(uint32_t Enc) { CompactUnwindEncoding = Enc; }
/// getAddrLabelSymbol - Return the symbol to be used for the specified basic
/// block when its address is taken. This cannot be its normal LBB label
/// because the block may be accessed outside its containing function.
@ -286,12 +302,12 @@ class MachineModuleInfo : public ImmutablePass {
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
///
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
std::vector<const GlobalVariable *> &TyInfo);
ArrayRef<const GlobalVariable *> TyInfo);
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
///
void addFilterTypeInfo(MachineBasicBlock *LandingPad,
std::vector<const GlobalVariable *> &TyInfo);
ArrayRef<const GlobalVariable *> TyInfo);
/// addCleanup - Add a cleanup action for a landing pad.
///
@ -315,18 +331,42 @@ class MachineModuleInfo : public ImmutablePass {
return LandingPads;
}
/// setCallSiteBeginLabel - Map the begin label for a call site
/// setCallSiteLandingPad - Map the landing pad's EH symbol to the call
/// site indexes.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
/// getCallSiteLandingPad - Get the call site indexes for a landing pad EH
/// symbol.
SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
assert(hasCallSiteLandingPad(Sym) &&
"missing call site number for landing pad!");
return LPadToCallSiteMap[Sym];
}
/// hasCallSiteLandingPad - Return true if the landing pad Eh symbol has an
/// associated call site.
bool hasCallSiteLandingPad(MCSymbol *Sym) {
return !LPadToCallSiteMap[Sym].empty();
}
/// setCallSiteBeginLabel - Map the begin label for a call site.
void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
CallSiteMap[BeginLabel] = Site;
}
/// getCallSiteBeginLabel - Get the call site number for a begin label
/// getCallSiteBeginLabel - Get the call site number for a begin label.
unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) {
assert(CallSiteMap.count(BeginLabel) &&
assert(hasCallSiteBeginLabel(BeginLabel) &&
"Missing call site number for EH_LABEL!");
return CallSiteMap[BeginLabel];
}
/// hasCallSiteBeginLabel - Return true if the begin label has a call site
/// number associated with it.
bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) {
return CallSiteMap[BeginLabel] != 0;
}
/// setCurrentCallSite - Set the call site currently being processed.
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }

View File

@ -83,8 +83,23 @@ class MachineOperand {
/// This is only valid on definitions of registers.
bool IsDead : 1;
/// IsUndef - True if this is a register def / use of "undef", i.e. register
/// defined by an IMPLICIT_DEF. This is only valid on registers.
/// IsUndef - True if this register operand reads an "undef" value, i.e. the
/// read value doesn't matter. This flag can be set on both use and def
/// operands. On a sub-register def operand, it refers to the part of the
/// register that isn't written. On a full-register def operand, it is a
/// noop. See readsReg().
///
/// This is only valid on registers.
///
/// Note that an instruction may have multiple <undef> operands referring to
/// the same register. In that case, the instruction may depend on those
/// operands reading the same dont-care value. For example:
///
/// %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef>
///
/// Any register can be used for %vreg2, and its value doesn't matter, but
/// the two operands must be the same register.
///
bool IsUndef : 1;
/// IsEarlyClobber - True if this MO_Register 'def' operand is written to
@ -253,6 +268,15 @@ class MachineOperand {
return IsDebug;
}
/// readsReg - Returns true if this operand reads the previous value of its
/// register. A use operand with the <undef> flag set doesn't read its
/// register. A sub-register def implicitly reads the other parts of the
/// register being redefined unless the <undef> flag is set.
bool readsReg() const {
assert(isReg() && "Wrong MachineOperand accessor");
return !isUndef() && (isUse() || getSubReg());
}
/// getNextOperandForReg - Return the next MachineOperand in the function that
/// uses or defines this register.
MachineOperand *getNextOperandForReg() const {

View File

@ -25,6 +25,12 @@ namespace llvm {
/// registers, including vreg register classes, use/def chains for registers,
/// etc.
class MachineRegisterInfo {
const TargetRegisterInfo *const TRI;
/// IsSSA - True when the machine function is in SSA form and virtual
/// registers have a single def.
bool IsSSA;
/// VRegInfo - Information we keep for each virtual register.
///
/// Each element in this list contains the register class of the vreg and the
@ -65,7 +71,23 @@ class MachineRegisterInfo {
public:
explicit MachineRegisterInfo(const TargetRegisterInfo &TRI);
~MachineRegisterInfo();
//===--------------------------------------------------------------------===//
// Function State
//===--------------------------------------------------------------------===//
// isSSA - Returns true when the machine function is in SSA form. Early
// passes require the machine function to be in SSA form where every virtual
// register has a single defining instruction.
//
// The TwoAddressInstructionPass and PHIElimination passes take the machine
// function out of SSA form when they introduce multiple defs per virtual
// register.
bool isSSA() const { return IsSSA; }
// leaveSSA - Indicates that the machine function is no longer in SSA form.
void leaveSSA() { IsSSA = false; }
//===--------------------------------------------------------------------===//
// Register Info
//===--------------------------------------------------------------------===//
@ -195,12 +217,25 @@ class MachineRegisterInfo {
void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
/// constrainRegClass - Constrain the register class of the specified virtual
/// register to be a common subclass of RC and the current register class.
/// Return the new register class, or NULL if no such class exists.
/// register to be a common subclass of RC and the current register class,
/// but only if the new class has at least MinNumRegs registers. Return the
/// new register class, or NULL if no such class exists.
/// This should only be used when the constraint is known to be trivial, like
/// GR32 -> GR32_NOSP. Beware of increasing register pressure.
///
const TargetRegisterClass *constrainRegClass(unsigned Reg,
const TargetRegisterClass *RC);
const TargetRegisterClass *RC,
unsigned MinNumRegs = 0);
/// recomputeRegClass - Try to find a legal super-class of Reg's register
/// class that still satisfies the constraints from the instructions using
/// Reg. Returns true if Reg was upgraded.
///
/// This method can be used after constraints have been removed from a
/// virtual register, for example after removing instructions or splitting
/// the live range.
///
bool recomputeRegClass(unsigned Reg, const TargetMachine&);
/// createVirtualRegister - Create and return a new virtual register in the
/// function with the specified register class.

View File

@ -24,7 +24,7 @@ namespace llvm {
class MachineFunctionPass;
class PassInfo;
class TargetLowering;
class RegisterCoalescer;
class TargetRegisterClass;
class raw_ostream;
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
@ -81,6 +81,9 @@ namespace llvm {
/// register allocators.
extern char &TwoAddressInstructionPassID;
/// RegisteCoalescer pass - This pass merges live ranges to eliminate copies.
extern char &RegisterCoalescerPassID;
/// SpillPlacement analysis. Suggest optimal placement of spill code between
/// basic blocks.
///
@ -125,21 +128,15 @@ namespace llvm {
///
FunctionPass *createDefaultPBQPRegisterAllocator();
/// RegisterCoalescer Pass - Coalesce all copies possible. Can run
/// independently of the register allocator.
///
RegisterCoalescer *createRegisterCoalescer();
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
/// and eliminates abstract frame references.
///
FunctionPass *createPrologEpilogCodeInserter();
/// LowerSubregs Pass - This pass lowers subregs to register-register copies
/// which yields suboptimal, but correct code if the register allocator
/// cannot coalesce all subreg operations during allocation.
/// ExpandPostRAPseudos Pass - This pass expands pseudo instructions after
/// register allocation.
///
FunctionPass *createLowerSubregsPass();
FunctionPass *createExpandPostRAPseudosPass();
/// createPostRAScheduler - This pass performs post register allocation
/// scheduling.
@ -229,6 +226,14 @@ namespace llvm {
///
FunctionPass *createExpandISelPseudosPass();
/// createExecutionDependencyFixPass - This pass fixes execution time
/// problems with dependent instructions, such as switching execution
/// domains to match.
///
/// The pass will examine instructions using and defining registers in RC.
///
FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
} // End llvm namespace
#endif

View File

@ -450,6 +450,10 @@ class SelectionDAG {
SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
const int *MaskElts);
/// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
/// integer type VT, by either any-extending or truncating it.
SDValue getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
/// getSExtOrTrunc - Convert Op, which must be of integer type, to the
/// integer type VT, by either sign-extending or truncating it.
SDValue getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
@ -560,17 +564,13 @@ class SelectionDAG {
///
SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
"Cannot compare scalars to vectors");
assert(LHS.getValueType().isVector() == VT.isVector() &&
"Cannot compare scalars to vectors");
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
/// getVSetCC - Helper function to make it easier to build VSetCC's nodes
/// if you just have an ISD::CondCode instead of an SDValue.
///
SDValue getVSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
/// getSelectCC - Helper function to make it easier to build SelectCC's if you
/// just have an ISD::CondCode instead of an SDValue.
///
@ -589,19 +589,37 @@ class SelectionDAG {
/// takes 3 operands
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
MachinePointerInfo PtrInfo, unsigned Alignment=0);
MachinePointerInfo PtrInfo, unsigned Alignment,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
MachineMemOperand *MMO);
MachineMemOperand *MMO,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes 2 operands.
/// getAtomic - Gets a node for an atomic op, produces result (if relevant)
/// and chain and takes 2 operands.
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, const Value* PtrVal,
unsigned Alignment = 0);
unsigned Alignment, AtomicOrdering Ordering,
SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val,
MachineMemOperand *MMO);
SDValue Ptr, SDValue Val, MachineMemOperand *MMO,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes 1 operand.
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
SDValue Chain, SDValue Ptr, const Value* PtrVal,
unsigned Alignment,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
SDValue Chain, SDValue Ptr, MachineMemOperand *MMO,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
/// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
/// result and takes a list of operands. Opcode may be INTRINSIC_VOID,

View File

@ -20,6 +20,7 @@
#define LLVM_CODEGEN_SELECTIONDAGNODES_H
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist_node.h"
@ -917,6 +918,13 @@ class MemSDNode : public SDNode {
bool isVolatile() const { return (SubclassData >> 5) & 1; }
bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
AtomicOrdering getOrdering() const {
return AtomicOrdering((SubclassData >> 7) & 15);
}
SynchronizationScope getSynchScope() const {
return SynchronizationScope((SubclassData >> 11) & 1);
}
/// Returns the SrcValue and offset that describes the location of the access
const Value *getSrcValue() const { return MMO->getValue(); }
int64_t getSrcValueOffset() const { return MMO->getOffset(); }
@ -968,6 +976,8 @@ class MemSDNode : public SDNode {
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
N->getOpcode() == ISD::ATOMIC_LOAD ||
N->getOpcode() == ISD::ATOMIC_STORE ||
N->isTargetMemoryOpcode();
}
};
@ -977,6 +987,23 @@ class MemSDNode : public SDNode {
class AtomicSDNode : public MemSDNode {
SDUse Ops[4];
void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) {
// This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
assert((Ordering & 15) == Ordering &&
"Ordering may not require more than 4 bits!");
assert((SynchScope & 1) == SynchScope &&
"SynchScope may not require more than 1 bit!");
SubclassData |= Ordering << 7;
SubclassData |= SynchScope << 11;
assert(getOrdering() == Ordering && "Ordering encoding error!");
assert(getSynchScope() == SynchScope && "Synch-scope encoding error!");
assert((readMem() || getOrdering() <= Monotonic) &&
"Acquire/Release MachineMemOperand must be a load!");
assert((writeMem() || getOrdering() <= Monotonic) &&
"Acquire/Release MachineMemOperand must be a store!");
}
public:
// Opc: opcode for atomic
// VTL: value type list
@ -988,20 +1015,28 @@ class AtomicSDNode : public MemSDNode {
// Align: alignment of memory
AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO)
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, dl, VTL, MemVT, MMO) {
assert(readMem() && "Atomic MachineMemOperand is not a load!");
assert(writeMem() && "Atomic MachineMemOperand is not a store!");
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Cmp, Swp);
}
AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
SDValue Chain, SDValue Ptr,
SDValue Val, MachineMemOperand *MMO)
SDValue Val, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, dl, VTL, MemVT, MMO) {
assert(readMem() && "Atomic MachineMemOperand is not a load!");
assert(writeMem() && "Atomic MachineMemOperand is not a store!");
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Val);
}
AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
SDValue Chain, SDValue Ptr,
MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, dl, VTL, MemVT, MMO) {
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr);
}
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getVal() const { return getOperand(2); }
@ -1025,7 +1060,9 @@ class AtomicSDNode : public MemSDNode {
N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX;
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
N->getOpcode() == ISD::ATOMIC_LOAD ||
N->getOpcode() == ISD::ATOMIC_STORE;
}
};
@ -1291,7 +1328,7 @@ class ConstantPoolSDNode : public SDNode {
unsigned getAlignment() const { return Alignment; }
unsigned char getTargetFlags() const { return TargetFlags; }
const Type *getType() const;
Type *getType() const;
static bool classof(const ConstantPoolSDNode *) { return true; }
static bool classof(const SDNode *N) {

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file implements SlotIndex and related classes. The purpuse of SlotIndex
// This file implements SlotIndex and related classes. The purpose of SlotIndex
// is to describe a position at which a register can become live, or cease to
// be live.
//

View File

@ -33,42 +33,13 @@ namespace llvm {
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
protected:
/// TLSDataSection - Section directive for Thread Local data.
///
const MCSection *TLSDataSection; // Defaults to ".tdata".
/// TLSBSSSection - Section directive for Thread Local uninitialized data.
/// Null if this target doesn't support a BSS section.
///
const MCSection *TLSBSSSection; // Defaults to ".tbss".
const MCSection *DataRelSection;
const MCSection *DataRelLocalSection;
const MCSection *DataRelROSection;
const MCSection *DataRelROLocalSection;
const MCSection *MergeableConst4Section;
const MCSection *MergeableConst8Section;
const MCSection *MergeableConst16Section;
public:
TargetLoweringObjectFileELF();
~TargetLoweringObjectFileELF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
virtual const MCSection *getWin64EHFuncTableSection(StringRef) const {
return NULL;
}
virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;}
virtual ~TargetLoweringObjectFileELF() {}
virtual void emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
const MCSymbol *Sym) const;
const MCSection *getDataRelSection() const { return DataRelSection; }
/// getSectionForConstant - Given a constant with the SectionKind, return a
/// section that it should be placed in.
virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
@ -99,48 +70,8 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
/// TLSDataSection - Section for thread local data.
///
const MCSection *TLSDataSection; // Defaults to ".tdata".
/// TLSBSSSection - Section for thread local uninitialized data.
///
const MCSection *TLSBSSSection; // Defaults to ".tbss".
/// TLSTLVSection - Section for thread local structure information.
/// Contains the source code name of the variable, visibility and a pointer
/// to the initial value (.tdata or .tbss).
const MCSection *TLSTLVSection; // Defaults to ".tlv".
/// TLSThreadInitSection - Section for thread local data initialization
/// functions.
const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
const MCSection *CStringSection;
const MCSection *UStringSection;
const MCSection *TextCoalSection;
const MCSection *ConstTextCoalSection;
const MCSection *ConstDataSection;
const MCSection *DataCoalSection;
const MCSection *DataCommonSection;
const MCSection *DataBSSSection;
const MCSection *FourByteConstantSection;
const MCSection *EightByteConstantSection;
const MCSection *SixteenByteConstantSection;
const MCSection *LazySymbolPointerSection;
const MCSection *NonLazySymbolPointerSection;
public:
TargetLoweringObjectFileMachO();
~TargetLoweringObjectFileMachO() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
virtual const MCSection *getWin64EHFuncTableSection(StringRef) const {
return NULL;
}
virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;}
virtual ~TargetLoweringObjectFileMachO() {}
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
@ -158,30 +89,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
Mangler *) const;
/// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
/// text symbols into.
const MCSection *getTextCoalSection() const {
return TextCoalSection;
}
/// getConstTextCoalSection - Return the "__TEXT,__const_coal" section
/// we put weak read-only symbols into.
const MCSection *getConstTextCoalSection() const {
return ConstTextCoalSection;
}
/// getLazySymbolPointerSection - Return the section corresponding to
/// the .lazy_symbol_pointer directive.
const MCSection *getLazySymbolPointerSection() const {
return LazySymbolPointerSection;
}
/// getNonLazySymbolPointerSection - Return the section corresponding to
/// the .non_lazy_symbol_pointer directive.
const MCSection *getNonLazySymbolPointerSection() const {
return NonLazySymbolPointerSection;
}
/// getExprForDwarfGlobalReference - The mach-o version of this method
/// defaults to returning a stub reference.
virtual const MCExpr *
@ -193,30 +100,13 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
virtual MCSymbol *
getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfo *MMI) const;
virtual unsigned getPersonalityEncoding() const;
virtual unsigned getLSDAEncoding() const;
virtual unsigned getFDEEncoding(bool CFI) const;
virtual unsigned getTTypeEncoding() const;
};
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
const MCSection *DrectveSection;
const MCSection *PDataSection;
const MCSection *XDataSection;
public:
TargetLoweringObjectFileCOFF();
~TargetLoweringObjectFileCOFF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
virtual const MCSection *getWin64EHFuncTableSection(StringRef) const;
virtual const MCSection *getWin64EHTableSection(StringRef) const;
virtual const MCSection *getDrectveSection() const { return DrectveSection; }
virtual ~TargetLoweringObjectFileCOFF() {}
virtual const MCSection *
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,

View File

@ -144,14 +144,14 @@ namespace llvm {
/// isFloatingPoint - Return true if this is a FP, or a vector FP type.
bool isFloatingPoint() const {
return ((SimpleTy >= MVT::f32 && SimpleTy <= MVT::ppcf128) ||
(SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64));
(SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64));
}
/// isInteger - Return true if this is an integer, or a vector integer type.
bool isInteger() const {
return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
(SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64));
(SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64));
}
/// isVector - Return true if this is a vector value type.
@ -380,7 +380,7 @@ namespace llvm {
struct EVT {
private:
MVT V;
const Type *LLVMTy;
Type *LLVMTy;
public:
EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
@ -438,6 +438,21 @@ namespace llvm {
return MVT::INVALID_SIMPLE_VALUE_TYPE;
}
/// changeVectorElementTypeToInteger - Return a vector with the same number
/// of elements as this vector, but with the element type converted to an
/// integer type with the same bitwidth.
EVT changeVectorElementTypeToInteger() const {
if (!isSimple())
return changeExtendedVectorElementTypeToInteger();
MVT EltTy = getSimpleVT().getVectorElementType();
unsigned BitWidth = EltTy.getSizeInBits();
MVT IntTy = MVT::getIntegerVT(BitWidth);
MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
"Simple vector VT not representable by simple integer vector VT!");
return VecTy;
}
/// isSimple - Test if the given EVT is simple (as opposed to being
/// extended).
bool isSimple() const {
@ -645,12 +660,12 @@ namespace llvm {
/// getTypeForEVT - This method returns an LLVM type corresponding to the
/// specified EVT. For integer types, this returns an unsigned type. Note
/// that this will abort for types that cannot be represented.
const Type *getTypeForEVT(LLVMContext &Context) const;
Type *getTypeForEVT(LLVMContext &Context) const;
/// getEVT - Return the value type corresponding to the specified type.
/// This returns all pointers as iPTR. If HandleUnknown is true, unknown
/// types are returned as Other, otherwise they are invalid.
static EVT getEVT(const Type *Ty, bool HandleUnknown = false);
static EVT getEVT(Type *Ty, bool HandleUnknown = false);
intptr_t getRawBits() {
if (isSimple())
@ -674,6 +689,7 @@ namespace llvm {
// Methods for handling the Extended-type case in functions above.
// These are all out-of-line to prevent users of this header file
// from having a dependency on Type.h.
EVT changeExtendedVectorElementTypeToInteger() const;
static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
unsigned NumElements);

View File

@ -1,54 +0,0 @@
//===--- Action.h - The LLVM Compiler Driver --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Action - encapsulates a single shell command.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H
#define LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H
#include <string>
#include <vector>
namespace llvmc {
typedef std::vector<std::string> StrVector;
/// Action - A class that encapsulates a single shell command.
class Action {
/// Command_ - The actual command (for example, 'ls').
std::string Command_;
/// Args_ - Command arguments. Stdout redirection ("> file") is allowed.
std::vector<std::string> Args_;
/// StopCompilation_ - Should we stop compilation after executing
/// this action?
bool StopCompilation_;
/// OutFile_ - The output file name.
std::string OutFile_;
public:
void Construct (const std::string& C, const StrVector& A,
bool S, const std::string& O) {
Command_ = C;
Args_ = A;
StopCompilation_ = S;
OutFile_ = O;
}
bool IsConstructed () { return (Command_.size() != 0);}
/// Execute - Executes the command. Returns -1 on error.
int Execute () const;
bool StopCompilation () const { return StopCompilation_; }
const std::string& OutFile() { return OutFile_; }
};
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H

View File

@ -1,40 +0,0 @@
//===--- AutoGenerated.h - The LLVM Compiler Driver -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Interface to the autogenerated driver code.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H
#define LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H
namespace llvmc {
class LanguageMap;
class CompilationGraph;
namespace autogenerated {
int PreprocessOptions();
int PopulateLanguageMap(LanguageMap& langMap);
int PopulateCompilationGraph(CompilationGraph& graph);
inline int RunInitialization (LanguageMap& M, CompilationGraph& G) {
if (int ret = PreprocessOptions())
return ret;
if (int ret = PopulateLanguageMap(M))
return ret;
if (int ret = PopulateCompilationGraph(G))
return ret;
return 0;
}
}
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H

View File

@ -1,39 +0,0 @@
//===--- BuiltinOptions.h - The LLVM Compiler Driver ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Declarations of all global command-line option variables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H
#define LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H
#include "llvm/Support/CommandLine.h"
#include <string>
namespace llvmc {
namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; }
extern llvm::cl::list<std::string> InputFilenames;
extern llvm::cl::opt<std::string> OutputFilename;
extern llvm::cl::opt<std::string> TempDirname;
extern llvm::cl::list<std::string> Languages;
extern llvm::cl::opt<bool> DryRun;
extern llvm::cl::opt<bool> Time;
extern llvm::cl::opt<bool> VerboseMode;
extern llvm::cl::opt<bool> CheckGraph;
extern llvm::cl::opt<bool> ViewGraph;
extern llvm::cl::opt<bool> WriteGraph;
extern llvm::cl::opt<SaveTempsEnum::Values> SaveTemps;
} // End namespace llvmc.
#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H

View File

@ -1,127 +0,0 @@
//===- Common.td - Common definitions for LLVMC2 ----------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains common definitions used in llvmc tool description files.
//
//===----------------------------------------------------------------------===//
class Tool<list<dag> l> {
list<dag> properties = l;
}
// Possible Tool properties.
def in_language;
def out_language;
def output_suffix;
def command;
def out_file_option;
def in_file_option;
def join;
def sink;
def works_on_empty;
def actions;
// Possible option types.
def alias_option;
def switch_option;
def switch_list_option;
def parameter_option;
def parameter_list_option;
def prefix_option;
def prefix_list_option;
// Possible option properties.
def help;
def hidden;
def init;
def multi_val;
def one_or_more;
def zero_or_more;
def optional;
def really_hidden;
def required;
def comma_separated;
def forward_not_split;
// The 'case' construct.
def case;
// Boolean constants.
class Bool<bit val> {
bit Value = val;
}
def true : Bool<1>;
def false : Bool<0>;
// Boolean operators.
def and;
def or;
def not;
// Primitive tests.
def switch_on;
def parameter_equals;
def element_in_list;
def input_languages_contain;
def empty;
def not_empty;
def default;
def single_input_file;
def multiple_input_files;
def any_switch_on;
def any_not_empty;
def any_empty;
// Possible actions.
def append_cmd;
def forward;
def forward_as;
def forward_value;
def forward_transformed_value;
def stop_compilation;
def no_out_file;
def unpack_values;
def warning;
def error;
def set_option;
def unset_option;
// Increase the edge weight.
def inc_weight;
// Option list - a single place to specify options.
class OptionList<list<dag> l> {
list<dag> options = l;
}
// Option preprocessor - actions taken during plugin loading.
class OptionPreprocessor<dag d> {
dag preprocessor = d;
}
// Map from suffixes to language names
def lang_to_suffixes;
class LanguageMap<list<dag> l> {
list<dag> map = l;
}
// Compilation graph
def edge;
def optional_edge;
class CompilationGraph<list<dag> l> {
list<dag> edges = l;
}

View File

@ -1,330 +0,0 @@
//===--- CompilationGraph.h - The LLVM Compiler Driver ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Compilation graph - definition.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H
#define LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H
#include "llvm/CompilerDriver/Tool.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
#include <cassert>
#include <string>
namespace llvmc {
class CompilationGraph;
typedef llvm::StringSet<> InputLanguagesSet;
/// LanguageMap - Maps from extensions to language names.
class LanguageMap : public llvm::StringMap<std::string> {
public:
/// GetLanguage - Find the language name corresponding to a given file.
const std::string* GetLanguage(const llvm::sys::Path&) const;
};
/// Edge - Represents an edge of the compilation graph.
class Edge : public llvm::RefCountedBaseVPTR {
public:
Edge(const std::string& T) : ToolName_(T) {}
virtual ~Edge() {}
const std::string& ToolName() const { return ToolName_; }
virtual int Weight(const InputLanguagesSet& InLangs) const = 0;
private:
std::string ToolName_;
};
/// SimpleEdge - An edge that has no properties.
class SimpleEdge : public Edge {
public:
SimpleEdge(const std::string& T) : Edge(T) {}
int Weight(const InputLanguagesSet&) const { return 1; }
};
/// Node - A node (vertex) of the compilation graph.
struct Node {
// A Node holds a list of the outward edges.
typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type;
typedef container_type::iterator iterator;
typedef container_type::const_iterator const_iterator;
Node() : OwningGraph(0), InEdges(0) {}
Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {}
Node(CompilationGraph* G, Tool* T) :
OwningGraph(G), ToolPtr(T), InEdges(0) {}
bool HasChildren() const { return !OutEdges.empty(); }
const std::string Name() const
{ return ToolPtr ? ToolPtr->Name() : "root"; }
// Iteration.
iterator EdgesBegin() { return OutEdges.begin(); }
const_iterator EdgesBegin() const { return OutEdges.begin(); }
iterator EdgesEnd() { return OutEdges.end(); }
const_iterator EdgesEnd() const { return OutEdges.end(); }
/// AddEdge - Add an outward edge. Takes ownership of the provided
/// Edge object.
void AddEdge(Edge* E);
// Inward edge counter. Used to implement topological sort.
void IncrInEdges() { ++InEdges; }
void DecrInEdges() { --InEdges; }
bool HasNoInEdges() const { return InEdges == 0; }
// Needed to implement NodeChildIterator/GraphTraits
CompilationGraph* OwningGraph;
// The corresponding Tool.
// WARNING: ToolPtr can be NULL (for the root node).
llvm::IntrusiveRefCntPtr<Tool> ToolPtr;
// Links to children.
container_type OutEdges;
// Inward edge counter. Updated in
// CompilationGraph::insertEdge(). Used for topological sorting.
unsigned InEdges;
};
class NodesIterator;
/// CompilationGraph - The compilation graph itself.
class CompilationGraph {
/// nodes_map_type - The main data structure.
typedef llvm::StringMap<Node> nodes_map_type;
/// tools_vector_type, tools_map_type - Data structures used to
/// map from language names to tools. (We can have several tools
/// associated with each language name, hence the need for a
/// vector.)
typedef
llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> tools_vector_type;
typedef llvm::StringMap<tools_vector_type> tools_map_type;
/// ToolsMap - Map from language names to lists of tool names.
tools_map_type ToolsMap;
/// NodesMap - Map from tool names to Tool objects.
nodes_map_type NodesMap;
public:
typedef nodes_map_type::iterator nodes_iterator;
typedef nodes_map_type::const_iterator const_nodes_iterator;
CompilationGraph();
/// insertNode - Insert a new node into the graph. Takes
/// ownership of the object.
void insertNode(Tool* T);
/// insertEdge - Insert a new edge into the graph. Takes ownership
/// of the Edge object. Returns non-zero value on error.
int insertEdge(const std::string& A, Edge* E);
/// Build - Build target(s) from the input file set. Command-line options
/// are passed implicitly as global variables. Returns non-zero value on
/// error (usually the failed program's exit code).
int Build(llvm::sys::Path const& TempDir, const LanguageMap& LangMap);
/// Check - Check the compilation graph for common errors like cycles,
/// input/output language mismatch and multiple default edges. Prints error
/// messages and in case it finds any errors.
int Check();
/// getNode - Return a reference to the node corresponding to the given tool
/// name. Returns 0 on error.
Node* getNode(const std::string& ToolName);
const Node* getNode(const std::string& ToolName) const;
/// viewGraph - This function is meant for use from the debugger. You can
/// just say 'call G->viewGraph()' and a ghostview window should pop up from
/// the program, displaying the compilation graph. This depends on there
/// being a 'dot' and 'gv' program in your path.
void viewGraph();
/// writeGraph - Write Graphviz .dot source file to the current direcotry.
int writeGraph(const std::string& OutputFilename);
// GraphTraits support.
friend NodesIterator GraphBegin(CompilationGraph*);
friend NodesIterator GraphEnd(CompilationGraph*);
private:
// Helper functions.
/// getToolsVector - Return a reference to the list of tool names
/// corresponding to the given language name. Returns 0 on error.
const tools_vector_type* getToolsVector(const std::string& LangName) const;
/// PassThroughGraph - Pass the input file through the toolchain starting at
/// StartNode.
int PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
const InputLanguagesSet& InLangs,
const llvm::sys::Path& TempDir,
const LanguageMap& LangMap) const;
/// FindToolChain - Find head of the toolchain corresponding to
/// the given file.
const Node* FindToolChain(const llvm::sys::Path& In,
const std::string* ForceLanguage,
InputLanguagesSet& InLangs,
const LanguageMap& LangMap) const;
/// BuildInitial - Traverse the initial parts of the toolchains. Returns
/// non-zero value on error.
int BuildInitial(InputLanguagesSet& InLangs,
const llvm::sys::Path& TempDir,
const LanguageMap& LangMap);
/// TopologicalSort - Sort the nodes in topological order. Returns non-zero
/// value on error.
int TopologicalSort(std::vector<const Node*>& Out);
/// TopologicalSortFilterJoinNodes - Call TopologicalSort and filter the
/// resulting list to include only Join nodes. Returns non-zero value on
/// error.
int TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out);
// Functions used to implement Check().
/// CheckLanguageNames - Check that output/input language names match for
/// all nodes. Returns non-zero value on error (number of errors
/// encountered).
int CheckLanguageNames() const;
/// CheckMultipleDefaultEdges - check that there are no multiple default
/// default edges. Returns non-zero value on error (number of errors
/// encountered).
int CheckMultipleDefaultEdges() const;
/// CheckCycles - Check that there are no cycles in the graph. Returns
/// non-zero value on error (number of errors encountered).
int CheckCycles();
};
// GraphTraits support code.
/// NodesIterator - Auxiliary class needed to implement GraphTraits
/// support. Can be generalised to something like value_iterator
/// for map-like containers.
class NodesIterator : public CompilationGraph::nodes_iterator {
typedef CompilationGraph::nodes_iterator super;
typedef NodesIterator ThisType;
typedef Node* pointer;
typedef Node& reference;
public:
NodesIterator(super I) : super(I) {}
inline reference operator*() const {
return super::operator->()->second;
}
inline pointer operator->() const {
return &super::operator->()->second;
}
};
inline NodesIterator GraphBegin(CompilationGraph* G) {
return NodesIterator(G->NodesMap.begin());
}
inline NodesIterator GraphEnd(CompilationGraph* G) {
return NodesIterator(G->NodesMap.end());
}
/// NodeChildIterator - Another auxiliary class needed by GraphTraits.
class NodeChildIterator : public
std::iterator<std::bidirectional_iterator_tag, Node, ptrdiff_t> {
typedef NodeChildIterator ThisType;
typedef Node::container_type::iterator iterator;
CompilationGraph* OwningGraph;
iterator EdgeIter;
public:
typedef Node* pointer;
typedef Node& reference;
NodeChildIterator(Node* N, iterator I) :
OwningGraph(N->OwningGraph), EdgeIter(I) {}
const ThisType& operator=(const ThisType& I) {
assert(OwningGraph == I.OwningGraph);
EdgeIter = I.EdgeIter;
return *this;
}
inline bool operator==(const ThisType& I) const {
assert(OwningGraph == I.OwningGraph);
return EdgeIter == I.EdgeIter;
}
inline bool operator!=(const ThisType& I) const {
return !this->operator==(I);
}
inline pointer operator*() const {
return OwningGraph->getNode((*EdgeIter)->ToolName());
}
inline pointer operator->() const {
return this->operator*();
}
ThisType& operator++() { ++EdgeIter; return *this; } // Preincrement
ThisType operator++(int) { // Postincrement
ThisType tmp = *this;
++*this;
return tmp;
}
inline ThisType& operator--() { --EdgeIter; return *this; } // Predecrement
inline ThisType operator--(int) { // Postdecrement
ThisType tmp = *this;
--*this;
return tmp;
}
};
}
namespace llvm {
template <>
struct GraphTraits<llvmc::CompilationGraph*> {
typedef llvmc::CompilationGraph GraphType;
typedef llvmc::Node NodeType;
typedef llvmc::NodeChildIterator ChildIteratorType;
static NodeType* getEntryNode(GraphType* G) {
return G->getNode("root");
}
static ChildIteratorType child_begin(NodeType* N) {
return ChildIteratorType(N, N->OutEdges.begin());
}
static ChildIteratorType child_end(NodeType* N) {
return ChildIteratorType(N, N->OutEdges.end());
}
typedef llvmc::NodesIterator nodes_iterator;
static nodes_iterator nodes_begin(GraphType *G) {
return GraphBegin(G);
}
static nodes_iterator nodes_end(GraphType *G) {
return GraphEnd(G);
}
};
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H

View File

@ -1,29 +0,0 @@
//===--- Error.h - The LLVM Compiler Driver ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Error handling.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H
#define LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
namespace llvmc {
inline void PrintError(llvm::StringRef Err) {
extern const char* ProgramName;
llvm::errs() << ProgramName << ": " << Err << '\n';
}
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H

View File

@ -1,21 +0,0 @@
//===--- Main.h - The LLVM Compiler Driver ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Entry point for the driver executable.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H
#define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H
namespace llvmc {
int Main(int argc, char** argv);
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H

View File

@ -1,23 +0,0 @@
//===--- Main.inc - The LLVM Compiler Driver --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Default main() for the driver executable.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC
#define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC
#include "llvm/CompilerDriver/Main.h"
int main(int argc, char** argv) {
return llvmc::Main(argc, argv);
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC

View File

@ -1,100 +0,0 @@
//===--- Tool.h - The LLVM Compiler Driver ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Tool abstract base class - an interface to tool descriptions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H
#define LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H
#include "llvm/CompilerDriver/Action.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
#include <string>
#include <vector>
#include <utility>
namespace llvmc {
class LanguageMap;
typedef std::vector<std::pair<unsigned, std::string> > ArgsVector;
typedef std::vector<llvm::sys::Path> PathVector;
typedef std::vector<std::string> StrVector;
typedef llvm::StringSet<> InputLanguagesSet;
/// Tool - Represents a single tool.
class Tool : public llvm::RefCountedBaseVPTR {
public:
virtual ~Tool() {}
/// GenerateAction - Generate an Action given particular command-line
/// options. Returns non-zero value on error.
virtual int GenerateAction (Action& Out,
const PathVector& inFiles,
const bool HasChildren,
const llvm::sys::Path& TempDir,
const InputLanguagesSet& InLangs,
const LanguageMap& LangMap) const = 0;
/// GenerateAction - Generate an Action given particular command-line
/// options. Returns non-zero value on error.
virtual int GenerateAction (Action& Out,
const llvm::sys::Path& inFile,
const bool HasChildren,
const llvm::sys::Path& TempDir,
const InputLanguagesSet& InLangs,
const LanguageMap& LangMap) const = 0;
virtual const char* Name() const = 0;
virtual const char** InputLanguages() const = 0;
virtual const char** OutputLanguages() const = 0;
virtual bool IsJoin() const = 0;
virtual bool WorksOnEmpty() const = 0;
protected:
/// OutFileName - Generate the output file name.
llvm::sys::Path OutFilename(const llvm::sys::Path& In,
const llvm::sys::Path& TempDir,
bool StopCompilation,
const char* OutputSuffix) const;
StrVector SortArgs(ArgsVector& Args) const;
};
/// JoinTool - A Tool that has an associated input file list.
class JoinTool : public Tool {
public:
void AddToJoinList(const llvm::sys::Path& P) { JoinList_.push_back(P); }
void ClearJoinList() { JoinList_.clear(); }
bool JoinListEmpty() const { return JoinList_.empty(); }
int GenerateAction(Action& Out,
const bool HasChildren,
const llvm::sys::Path& TempDir,
const InputLanguagesSet& InLangs,
const LanguageMap& LangMap) const {
return GenerateAction(Out, JoinList_, HasChildren, TempDir, InLangs,
LangMap);
}
// We shouldn't shadow base class's version of GenerateAction.
using Tool::GenerateAction;
private:
PathVector JoinList_;
};
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H

View File

@ -43,7 +43,7 @@ class Constant : public User {
Constant(const Constant &); // Do not implement
protected:
Constant(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
void destroyConstantImpl();
@ -52,6 +52,10 @@ class Constant : public User {
/// getNullValue.
bool isNullValue() const;
/// isAllOnesValue - Return true if this is the value that would be returned by
/// getAllOnesValue.
bool isAllOnesValue() const;
/// isNegativeZeroValue - Return true if the value is what would be returned
/// by getZeroValueForNegation.
bool isNegativeZeroValue() const;
@ -128,16 +132,16 @@ class Constant : public User {
assert(0 && "Constants that do not have operands cannot be using 'From'!");
}
static Constant *getNullValue(const Type* Ty);
static Constant *getNullValue(Type* Ty);
/// @returns the value for an integer constant of the given type that has all
/// its bits set to true.
/// @brief Get the all ones value
static Constant *getAllOnesValue(const Type* Ty);
static Constant *getAllOnesValue(Type* Ty);
/// getIntegerValue - Return the value for an integer or pointer constant,
/// or a vector thereof, with the given scalar value.
static Constant *getIntegerValue(const Type* Ty, const APInt &V);
static Constant *getIntegerValue(Type* Ty, const APInt &V);
/// removeDeadConstantUsers - If there are any dead constant users dangling
/// off of this constant, remove them. This method is useful for clients

View File

@ -47,7 +47,7 @@ struct ConvertConstantType;
class ConstantInt : public Constant {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT
ConstantInt(const IntegerType *Ty, const APInt& V);
ConstantInt(IntegerType *Ty, const APInt& V);
APInt Val;
protected:
// allocate space for exactly zero operands
@ -57,12 +57,12 @@ class ConstantInt : public Constant {
public:
static ConstantInt *getTrue(LLVMContext &Context);
static ConstantInt *getFalse(LLVMContext &Context);
static Constant *getTrue(const Type *Ty);
static Constant *getFalse(const Type *Ty);
static Constant *getTrue(Type *Ty);
static Constant *getFalse(Type *Ty);
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false);
static Constant *get(Type *Ty, uint64_t V, bool isSigned = false);
/// Return a ConstantInt with the specified integer value for the specified
/// type. If the type is wider than 64 bits, the value will be zero-extended
@ -70,7 +70,7 @@ class ConstantInt : public Constant {
/// be interpreted as a 64-bit signed integer and sign-extended to fit
/// the type.
/// @brief Get a ConstantInt for a specific value.
static ConstantInt *get(const IntegerType *Ty, uint64_t V,
static ConstantInt *get(IntegerType *Ty, uint64_t V,
bool isSigned = false);
/// Return a ConstantInt with the specified value for the specified type. The
@ -78,8 +78,8 @@ class ConstantInt : public Constant {
/// either getSExtValue() or getZExtValue() will yield a correctly sized and
/// signed value for the type Ty.
/// @brief Get a ConstantInt for a specific signed value.
static ConstantInt *getSigned(const IntegerType *Ty, int64_t V);
static Constant *getSigned(const Type *Ty, int64_t V);
static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
static Constant *getSigned(Type *Ty, int64_t V);
/// Return a ConstantInt with the specified value and an implied Type. The
/// type is the integer type that corresponds to the bit width of the value.
@ -87,12 +87,12 @@ class ConstantInt : public Constant {
/// Return a ConstantInt constructed from the string strStart with the given
/// radix.
static ConstantInt *get(const IntegerType *Ty, StringRef Str,
static ConstantInt *get(IntegerType *Ty, StringRef Str,
uint8_t radix);
/// If Ty is a vector type, return a Constant with a splat of the given
/// value. Otherwise return a ConstantInt for the given value.
static Constant *get(const Type* Ty, const APInt& V);
static Constant *get(Type* Ty, const APInt& V);
/// Return the constant as an APInt value reference. This allows clients to
/// obtain a copy of the value, with all its precision in tact.
@ -133,8 +133,8 @@ class ConstantInt : public Constant {
/// getType - Specialize the getType() method to always return an IntegerType,
/// which reduces the amount of casting needed in parts of the compiler.
///
inline const IntegerType *getType() const {
return reinterpret_cast<const IntegerType*>(Value::getType());
inline IntegerType *getType() const {
return reinterpret_cast<IntegerType*>(Value::getType());
}
/// This static method returns true if the type Ty is big enough to
@ -146,8 +146,8 @@ class ConstantInt : public Constant {
/// to the appropriate unsigned type before calling the method.
/// @returns true if V is a valid value for type Ty
/// @brief Determine if the value is in range for the given type.
static bool isValueValidForType(const Type *Ty, uint64_t V);
static bool isValueValidForType(const Type *Ty, int64_t V);
static bool isValueValidForType(Type *Ty, uint64_t V);
static bool isValueValidForType(Type *Ty, int64_t V);
bool isNegative() const { return Val.isNegative(); }
@ -170,7 +170,7 @@ class ConstantInt : public Constant {
/// to true.
/// @returns true iff this constant's bits are all set to true.
/// @brief Determine if the value is all ones.
bool isAllOnesValue() const {
bool isMinusOne() const {
return Val.isAllOnesValue();
}
@ -203,7 +203,7 @@ class ConstantInt : public Constant {
/// value.
/// @returns true iff this constant is greater or equal to the given number.
/// @brief Determine if the value is greater or equal to the given number.
bool uge(uint64_t Num) {
bool uge(uint64_t Num) const {
return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
}
@ -233,7 +233,7 @@ class ConstantFP : public Constant {
ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT
friend class LLVMContextImpl;
protected:
ConstantFP(const Type *Ty, const APFloat& V);
ConstantFP(Type *Ty, const APFloat& V);
protected:
// allocate space for exactly zero operands
void *operator new(size_t s) {
@ -243,20 +243,20 @@ class ConstantFP : public Constant {
/// Floating point negation must be implemented with f(x) = -0.0 - x. This
/// method returns the negative zero constant for floating point or vector
/// floating point types; for all other types, it returns the null value.
static Constant *getZeroValueForNegation(const Type *Ty);
static Constant *getZeroValueForNegation(Type *Ty);
/// get() - This returns a ConstantFP, or a vector containing a splat of a
/// ConstantFP, for the specified value in the specified type. This should
/// only be used for simple constant values like 2.0/1.0 etc, that are
/// known-valid both as host double and as the target format.
static Constant *get(const Type* Ty, double V);
static Constant *get(const Type* Ty, StringRef Str);
static Constant *get(Type* Ty, double V);
static Constant *get(Type* Ty, StringRef Str);
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
static ConstantFP *getNegativeZero(const Type* Ty);
static ConstantFP *getInfinity(const Type *Ty, bool Negative = false);
static ConstantFP *getNegativeZero(Type* Ty);
static ConstantFP *getInfinity(Type *Ty, bool Negative = false);
/// isValueValidForType - return true if Ty is big enough to represent V.
static bool isValueValidForType(const Type *Ty, const APFloat &V);
static bool isValueValidForType(Type *Ty, const APFloat &V);
inline const APFloat &getValueAPF() const { return Val; }
/// isZero - Return true if the value is positive or negative zero.
@ -300,7 +300,7 @@ class ConstantAggregateZero : public Constant {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT
protected:
explicit ConstantAggregateZero(const Type *ty)
explicit ConstantAggregateZero(Type *ty)
: Constant(ty, ConstantAggregateZeroVal, 0, 0) {}
protected:
// allocate space for exactly zero operands
@ -308,7 +308,7 @@ class ConstantAggregateZero : public Constant {
return User::operator new(s, 0);
}
public:
static ConstantAggregateZero* get(const Type *Ty);
static ConstantAggregateZero* get(Type *Ty);
virtual void destroyConstant();
@ -329,10 +329,10 @@ class ConstantArray : public Constant {
std::vector<Constant*> >;
ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT
protected:
ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
public:
// ConstantArray accessors
static Constant *get(const ArrayType *T, ArrayRef<Constant*> V);
static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
/// This method constructs a ConstantArray and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
@ -349,8 +349,8 @@ class ConstantArray : public Constant {
/// getType - Specialize the getType() method to always return an ArrayType,
/// which reduces the amount of casting needed in parts of the compiler.
///
inline const ArrayType *getType() const {
return reinterpret_cast<const ArrayType*>(Value::getType());
inline ArrayType *getType() const {
return reinterpret_cast<ArrayType*>(Value::getType());
}
/// isString - This method returns true if the array is an array of i8 and
@ -390,7 +390,7 @@ struct OperandTraits<ConstantArray> :
public VariadicOperandTraits<ConstantArray> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
//===----------------------------------------------------------------------===//
// ConstantStruct - Constant Struct Declarations
@ -400,11 +400,11 @@ class ConstantStruct : public Constant {
std::vector<Constant*> >;
ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT
protected:
ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
public:
// ConstantStruct accessors
static Constant *get(const StructType *T, ArrayRef<Constant*> V);
static Constant *get(const StructType *T, ...) END_WITH_NULL;
static Constant *get(StructType *T, ArrayRef<Constant*> V);
static Constant *get(StructType *T, ...) END_WITH_NULL;
/// getAnon - Return an anonymous struct that has the specified
/// elements. If the struct is possibly empty, then you must specify a
@ -431,8 +431,8 @@ class ConstantStruct : public Constant {
/// getType() specialization - Reduce amount of casting...
///
inline const StructType *getType() const {
return reinterpret_cast<const StructType*>(Value::getType());
inline StructType *getType() const {
return reinterpret_cast<StructType*>(Value::getType());
}
virtual void destroyConstant();
@ -450,7 +450,7 @@ struct OperandTraits<ConstantStruct> :
public VariadicOperandTraits<ConstantStruct> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
//===----------------------------------------------------------------------===//
@ -461,7 +461,7 @@ class ConstantVector : public Constant {
std::vector<Constant*> >;
ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT
protected:
ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
public:
// ConstantVector accessors
static Constant *get(ArrayRef<Constant*> V);
@ -472,8 +472,8 @@ class ConstantVector : public Constant {
/// getType - Specialize the getType() method to always return a VectorType,
/// which reduces the amount of casting needed in parts of the compiler.
///
inline const VectorType *getType() const {
return reinterpret_cast<const VectorType*>(Value::getType());
inline VectorType *getType() const {
return reinterpret_cast<VectorType*>(Value::getType());
}
/// This function will return true iff every element in this vector constant
@ -501,7 +501,7 @@ struct OperandTraits<ConstantVector> :
public VariadicOperandTraits<ConstantVector> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
//===----------------------------------------------------------------------===//
/// ConstantPointerNull - a constant pointer value that points to null
@ -511,8 +511,8 @@ class ConstantPointerNull : public Constant {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
ConstantPointerNull(const ConstantPointerNull &); // DO NOT IMPLEMENT
protected:
explicit ConstantPointerNull(const PointerType *T)
: Constant(reinterpret_cast<const Type*>(T),
explicit ConstantPointerNull(PointerType *T)
: Constant(reinterpret_cast<Type*>(T),
Value::ConstantPointerNullVal, 0, 0) {}
protected:
@ -522,15 +522,15 @@ class ConstantPointerNull : public Constant {
}
public:
/// get() - Static factory methods - Return objects of the specified value
static ConstantPointerNull *get(const PointerType *T);
static ConstantPointerNull *get(PointerType *T);
virtual void destroyConstant();
/// getType - Specialize the getType() method to always return an PointerType,
/// which reduces the amount of casting needed in parts of the compiler.
///
inline const PointerType *getType() const {
return reinterpret_cast<const PointerType*>(Value::getType());
inline PointerType *getType() const {
return reinterpret_cast<PointerType*>(Value::getType());
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -575,7 +575,7 @@ struct OperandTraits<BlockAddress> :
public FixedNumOperandTraits<BlockAddress, 2> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
//===----------------------------------------------------------------------===//
@ -591,7 +591,7 @@ class ConstantExpr : public Constant {
friend struct ConvertConstantType<ConstantExpr, Type>;
protected:
ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
: Constant(ty, ConstantExprVal, Ops, NumOps) {
// Operation type (an Instruction opcode) is stored as the SubclassData.
setValueSubclassData(Opcode);
@ -605,23 +605,23 @@ class ConstantExpr : public Constant {
/// getAlignOf constant expr - computes the alignment of a type in a target
/// independent way (Note: the return type is an i64).
static Constant *getAlignOf(const Type *Ty);
static Constant *getAlignOf(Type *Ty);
/// getSizeOf constant expr - computes the (alloc) size of a type (in
/// address-units, not bits) in a target independent way (Note: the return
/// type is an i64).
///
static Constant *getSizeOf(const Type *Ty);
static Constant *getSizeOf(Type *Ty);
/// getOffsetOf constant expr - computes the offset of a struct field in a
/// target independent way (Note: the return type is an i64).
///
static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo);
static Constant *getOffsetOf(StructType *STy, unsigned FieldNo);
/// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
/// which supports any aggregate type, and any Constant index.
///
static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo);
static Constant *getOffsetOf(Type *Ty, Constant *FieldNo);
static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
static Constant *getFNeg(Constant *C);
@ -648,18 +648,18 @@ class ConstantExpr : public Constant {
bool HasNUW = false, bool HasNSW = false);
static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getTrunc (Constant *C, const Type *Ty);
static Constant *getSExt (Constant *C, const Type *Ty);
static Constant *getZExt (Constant *C, const Type *Ty);
static Constant *getFPTrunc (Constant *C, const Type *Ty);
static Constant *getFPExtend(Constant *C, const Type *Ty);
static Constant *getUIToFP (Constant *C, const Type *Ty);
static Constant *getSIToFP (Constant *C, const Type *Ty);
static Constant *getFPToUI (Constant *C, const Type *Ty);
static Constant *getFPToSI (Constant *C, const Type *Ty);
static Constant *getPtrToInt(Constant *C, const Type *Ty);
static Constant *getIntToPtr(Constant *C, const Type *Ty);
static Constant *getBitCast (Constant *C, const Type *Ty);
static Constant *getTrunc (Constant *C, Type *Ty);
static Constant *getSExt (Constant *C, Type *Ty);
static Constant *getZExt (Constant *C, Type *Ty);
static Constant *getFPTrunc (Constant *C, Type *Ty);
static Constant *getFPExtend(Constant *C, Type *Ty);
static Constant *getUIToFP (Constant *C, Type *Ty);
static Constant *getSIToFP (Constant *C, Type *Ty);
static Constant *getFPToUI (Constant *C, Type *Ty);
static Constant *getFPToSI (Constant *C, Type *Ty);
static Constant *getPtrToInt(Constant *C, Type *Ty);
static Constant *getIntToPtr(Constant *C, Type *Ty);
static Constant *getBitCast (Constant *C, Type *Ty);
static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
@ -708,44 +708,44 @@ class ConstantExpr : public Constant {
static Constant *getCast(
unsigned ops, ///< The opcode for the conversion
Constant *C, ///< The constant to be converted
const Type *Ty ///< The type to which the constant is converted
Type *Ty ///< The type to which the constant is converted
);
// @brief Create a ZExt or BitCast cast constant expression
static Constant *getZExtOrBitCast(
Constant *C, ///< The constant to zext or bitcast
const Type *Ty ///< The type to zext or bitcast C to
Type *Ty ///< The type to zext or bitcast C to
);
// @brief Create a SExt or BitCast cast constant expression
static Constant *getSExtOrBitCast(
Constant *C, ///< The constant to sext or bitcast
const Type *Ty ///< The type to sext or bitcast C to
Type *Ty ///< The type to sext or bitcast C to
);
// @brief Create a Trunc or BitCast cast constant expression
static Constant *getTruncOrBitCast(
Constant *C, ///< The constant to trunc or bitcast
const Type *Ty ///< The type to trunc or bitcast C to
Type *Ty ///< The type to trunc or bitcast C to
);
/// @brief Create a BitCast or a PtrToInt cast constant expression
static Constant *getPointerCast(
Constant *C, ///< The pointer value to be casted (operand 0)
const Type *Ty ///< The type to which cast should be made
Type *Ty ///< The type to which cast should be made
);
/// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
static Constant *getIntegerCast(
Constant *C, ///< The integer constant to be casted
const Type *Ty, ///< The integer type to cast to
Type *Ty, ///< The integer type to cast to
bool isSigned ///< Whether C should be treated as signed or not
);
/// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
static Constant *getFPCast(
Constant *C, ///< The integer constant to be casted
const Type *Ty ///< The integer type to cast to
Type *Ty ///< The integer type to cast to
);
/// @brief Return true if this is a convert constant expression
@ -788,25 +788,40 @@ class ConstantExpr : public Constant {
/// all elements must be Constant's.
///
static Constant *getGetElementPtr(Constant *C,
Constant *const *IdxList, unsigned NumIdx,
ArrayRef<Constant *> IdxList,
bool InBounds = false) {
return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds);
return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(),
IdxList.size()),
InBounds);
}
static Constant *getGetElementPtr(Constant *C,
Value *const *IdxList, unsigned NumIdx,
Constant *Idx,
bool InBounds = false) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return getGetElementPtr(C, cast<Value>(Idx), InBounds);
}
static Constant *getGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList,
bool InBounds = false);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
static Constant *getInBoundsGetElementPtr(Constant *C,
Constant *const *IdxList,
unsigned NumIdx) {
return getGetElementPtr(C, IdxList, NumIdx, true);
ArrayRef<Constant *> IdxList) {
return getGetElementPtr(C, IdxList, true);
}
static Constant *getInBoundsGetElementPtr(Constant *C,
Value* const *IdxList,
unsigned NumIdx) {
return getGetElementPtr(C, IdxList, NumIdx, true);
Constant *Idx) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return getGetElementPtr(C, Idx, true);
}
static Constant *getInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) {
return getGetElementPtr(C, IdxList, true);
}
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
@ -845,7 +860,7 @@ class ConstantExpr : public Constant {
/// operands replaced with the specified values and with the specified result
/// type. The specified array must have the same number of operands as our
/// current one.
Constant *getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const;
Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
virtual void destroyConstant();
virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
@ -869,7 +884,7 @@ struct OperandTraits<ConstantExpr> :
public VariadicOperandTraits<ConstantExpr, 1> {
};
DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
//===----------------------------------------------------------------------===//
/// UndefValue - 'undef' values are things that do not have specified contents.
@ -886,7 +901,7 @@ class UndefValue : public Constant {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
UndefValue(const UndefValue &); // DO NOT IMPLEMENT
protected:
explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {}
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, 0, 0) {}
protected:
// allocate space for exactly zero operands
void *operator new(size_t s) {
@ -896,7 +911,7 @@ class UndefValue : public Constant {
/// get() - Static factory methods - Return an 'undef' object of the specified
/// type.
///
static UndefValue *get(const Type *T);
static UndefValue *get(Type *T);
virtual void destroyConstant();

View File

@ -0,0 +1,68 @@
//===-- DIContext.h ---------------------------------------------*- 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 DIContext, an abstract data structure that holds
// debug information data.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_DICONTEXT_H
#define LLVM_DEBUGINFO_DICONTEXT_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include <cstring>
namespace llvm {
class raw_ostream;
/// DILineInfo - a format-neutral container for source line information.
class DILineInfo {
const char *FileName;
uint32_t Line;
uint32_t Column;
public:
DILineInfo() : FileName("<invalid>"), Line(0), Column(0) {}
DILineInfo(const char *fileName, uint32_t line, uint32_t column)
: FileName(fileName), Line(line), Column(column) {}
const char *getFileName() const { return FileName; }
uint32_t getLine() const { return Line; }
uint32_t getColumn() const { return Column; }
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
std::strcmp(FileName, RHS.FileName) == 0;
}
bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS);
}
};
class DIContext {
public:
virtual ~DIContext();
/// getDWARFContext - get a context for binary DWARF data.
static DIContext *getDWARFContext(bool isLittleEndian,
StringRef infoSection,
StringRef abbrevSection,
StringRef aRangeSection = StringRef(),
StringRef lineSection = StringRef(),
StringRef stringSection = StringRef());
virtual void dump(raw_ostream &OS) = 0;
virtual DILineInfo getLineInfoForAddress(uint64_t address) = 0;
};
}
#endif

View File

@ -96,26 +96,26 @@ class IntegerType : public Type {
class FunctionType : public Type {
FunctionType(const FunctionType &); // Do not implement
const FunctionType &operator=(const FunctionType &); // Do not implement
FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
public:
/// FunctionType::get - This static method is the primary way of constructing
/// a FunctionType.
///
static FunctionType *get(const Type *Result,
static FunctionType *get(Type *Result,
ArrayRef<Type*> Params, bool isVarArg);
/// FunctionType::get - Create a FunctionType taking no parameters.
///
static FunctionType *get(const Type *Result, bool isVarArg);
static FunctionType *get(Type *Result, bool isVarArg);
/// isValidReturnType - Return true if the specified type is valid as a return
/// type.
static bool isValidReturnType(const Type *RetTy);
static bool isValidReturnType(Type *RetTy);
/// isValidArgumentType - Return true if the specified type is valid as an
/// argument type.
static bool isValidArgumentType(const Type *ArgTy);
static bool isValidArgumentType(Type *ArgTy);
bool isVarArg() const { return getSubclassData(); }
Type *getReturnType() const { return ContainedTys[0]; }
@ -150,8 +150,8 @@ class CompositeType : public Type {
/// getTypeAtIndex - Given an index value into the type, return the type of
/// the element.
///
Type *getTypeAtIndex(const Value *V) const;
Type *getTypeAtIndex(unsigned Idx) const;
Type *getTypeAtIndex(const Value *V);
Type *getTypeAtIndex(unsigned Idx);
bool indexValid(const Value *V) const;
bool indexValid(unsigned Idx) const;
@ -166,10 +166,25 @@ class CompositeType : public Type {
};
/// StructType - Class to represent struct types, both normal and packed.
/// Besides being optionally packed, structs can be either "anonymous" or may
/// have an identity. Anonymous structs are uniqued by structural equivalence,
/// but types are each unique when created, and optionally have a name.
/// StructType - Class to represent struct types. There are two different kinds
/// of struct types: Literal structs and Identified structs.
///
/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must
/// always have a body when created. You can get one of these by using one of
/// the StructType::get() forms.
///
/// Identified structs (e.g. %foo or %42) may optionally have a name and are not
/// uniqued. The names for identified structs are managed at the LLVMContext
/// level, so there can only be a single identified struct with a given name in
/// a particular LLVMContext. Identified structs may also optionally be opaque
/// (have no body specified). You get one of these by using one of the
/// StructType::create() forms.
///
/// Independent of what kind of struct you have, the body of a struct type are
/// laid out in memory consequtively with the elements directly one after the
/// other (if the struct is packed) or (if not packed) with padding between the
/// elements as defined by TargetData (which is required to match what the code
/// generator for a target expects).
///
class StructType : public CompositeType {
StructType(const StructType &); // Do not implement
@ -180,13 +195,13 @@ class StructType : public CompositeType {
// This is the contents of the SubClassData field.
SCDB_HasBody = 1,
SCDB_Packed = 2,
SCDB_IsAnonymous = 4
SCDB_IsLiteral = 4
};
/// SymbolTableEntry - For a named struct that actually has a name, this is a
/// pointer to the symbol table entry (maintained by LLVMContext) for the
/// struct. This is null if the type is an anonymous struct or if it is
/// a named type that has an empty name.
/// struct. This is null if the type is an literal struct or if it is
/// a identified type that has an empty name.
///
void *SymbolTableEntry;
public:
@ -194,20 +209,23 @@ class StructType : public CompositeType {
delete [] ContainedTys; // Delete the body.
}
/// StructType::createNamed - This creates a named struct with no body
/// specified. If the name is empty, it creates an unnamed struct, which has
/// a unique identity but no actual name.
static StructType *createNamed(LLVMContext &Context, StringRef Name);
/// StructType::create - This creates an identified struct.
static StructType *create(LLVMContext &Context, StringRef Name);
static StructType *create(LLVMContext &Context);
static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements,
bool isPacked = false);
static StructType *createNamed(LLVMContext &Context, StringRef Name,
ArrayRef<Type*> Elements,
bool isPacked = false);
static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL;
static StructType *create(ArrayRef<Type*> Elements,
StringRef Name,
bool isPacked = false);
static StructType *create(ArrayRef<Type*> Elements);
static StructType *create(LLVMContext &Context,
ArrayRef<Type*> Elements,
StringRef Name,
bool isPacked = false);
static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements);
static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL;
/// StructType::get - This static method is the primary way to create a
/// StructType.
/// literal StructType.
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
bool isPacked = false);
@ -223,9 +241,9 @@ class StructType : public CompositeType {
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
/// isAnonymous - Return true if this type is uniqued by structural
/// equivalence, false if it has an identity.
bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;}
/// isLiteral - Return true if this type is uniqued by structural
/// equivalence, false if it is a struct definition.
bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; }
/// isOpaque - Return true if this is a type with an identity that has no body
/// specified yet. These prints as 'opaque' in .ll files.
@ -236,21 +254,21 @@ class StructType : public CompositeType {
/// getName - Return the name for this struct type if it has an identity.
/// This may return an empty string for an unnamed struct type. Do not call
/// this on an anonymous type.
/// this on an literal type.
StringRef getName() const;
/// setName - Change the name of this type to the specified name, or to a name
/// with a suffix if there is a collision. Do not call this on an anonymous
/// with a suffix if there is a collision. Do not call this on an literal
/// type.
void setName(StringRef Name);
/// setBody - Specify a body for an opaque type.
/// setBody - Specify a body for an opaque identified type.
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
void setBody(Type *elt1, ...) END_WITH_NULL;
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(const Type *ElemTy);
static bool isValidElementType(Type *ElemTy);
// Iterator access to the elements.
@ -260,7 +278,7 @@ class StructType : public CompositeType {
/// isLayoutIdentical - Return true if this is layout identical to the
/// specified struct.
bool isLayoutIdentical(const StructType *Other) const;
bool isLayoutIdentical(StructType *Other) const;
// Random access to the elements
unsigned getNumElements() const { return NumContainedTys; }
@ -321,11 +339,11 @@ class ArrayType : public SequentialType {
/// ArrayType::get - This static method is the primary way to construct an
/// ArrayType
///
static ArrayType *get(const Type *ElementType, uint64_t NumElements);
static ArrayType *get(Type *ElementType, uint64_t NumElements);
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(const Type *ElemTy);
static bool isValidElementType(Type *ElemTy);
uint64_t getNumElements() const { return NumElements; }
@ -348,13 +366,13 @@ class VectorType : public SequentialType {
/// VectorType::get - This static method is the primary way to construct an
/// VectorType.
///
static VectorType *get(const Type *ElementType, unsigned NumElements);
static VectorType *get(Type *ElementType, unsigned NumElements);
/// VectorType::getInteger - This static method gets a VectorType with the
/// same number of elements as the input type, and the element type is an
/// integer type of the same width as the input element type.
///
static VectorType *getInteger(const VectorType *VTy) {
static VectorType *getInteger(VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
return VectorType::get(EltTy, VTy->getNumElements());
@ -364,7 +382,7 @@ class VectorType : public SequentialType {
/// getInteger except that the element types are twice as wide as the
/// elements in the input type.
///
static VectorType *getExtendedElementVectorType(const VectorType *VTy) {
static VectorType *getExtendedElementVectorType(VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
return VectorType::get(EltTy, VTy->getNumElements());
@ -374,7 +392,7 @@ class VectorType : public SequentialType {
/// getInteger except that the element types are half as wide as the
/// elements in the input type.
///
static VectorType *getTruncatedElementVectorType(const VectorType *VTy) {
static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
assert((EltBits & 1) == 0 &&
"Cannot truncate vector element with odd bit-width");
@ -384,7 +402,7 @@ class VectorType : public SequentialType {
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(const Type *ElemTy);
static bool isValidElementType(Type *ElemTy);
/// @brief Return the number of elements in the Vector type.
unsigned getNumElements() const { return NumElements; }
@ -411,17 +429,17 @@ class PointerType : public SequentialType {
public:
/// PointerType::get - This constructs a pointer to an object of the specified
/// type in a numbered address space.
static PointerType *get(const Type *ElementType, unsigned AddressSpace);
static PointerType *get(Type *ElementType, unsigned AddressSpace);
/// PointerType::getUnqual - This constructs a pointer to an object of the
/// specified type in the generic address space (address space zero).
static PointerType *getUnqual(const Type *ElementType) {
static PointerType *getUnqual(Type *ElementType) {
return PointerType::get(ElementType, 0);
}
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(const Type *ElemTy);
static bool isValidElementType(Type *ElemTy);
/// @brief Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return getSubclassData(); }

View File

@ -18,6 +18,7 @@
#include <vector>
#include <map>
#include <string>
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
@ -119,9 +120,7 @@ class ExecutionEngine {
/// optimize for the case where there is only one module.
SmallVector<Module*, 1> Modules;
void setTargetData(const TargetData *td) {
TD = td;
}
void setTargetData(const TargetData *td) { TD = td; }
/// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV);
@ -143,8 +142,7 @@ class ExecutionEngine {
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
TargetMachine *TM);
static ExecutionEngine *(*InterpCtor)(Module *M,
std::string *ErrorStr);
static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
/// LazyFunctionCreator - If an unknown function is needed, this function
/// pointer is invoked to create it. If this returns null, the JIT will
@ -186,7 +184,7 @@ class ExecutionEngine {
bool ForceInterpreter = false,
std::string *ErrorStr = 0,
CodeGenOpt::Level OptLevel =
CodeGenOpt::Default,
CodeGenOpt::Default,
bool GVsWithCode = true);
/// createJIT - This is the factory method for creating a JIT for the current
@ -199,10 +197,11 @@ class ExecutionEngine {
std::string *ErrorStr = 0,
JITMemoryManager *JMM = 0,
CodeGenOpt::Level OptLevel =
CodeGenOpt::Default,
CodeGenOpt::Default,
bool GVsWithCode = true,
Reloc::Model RM = Reloc::Default,
CodeModel::Model CMM =
CodeModel::Default);
CodeModel::JITDefault);
/// addModule - Add a Module to the list of modules that we can JIT from.
/// Note that this takes ownership of the Module: when the ExecutionEngine is
@ -314,7 +313,7 @@ class ExecutionEngine {
/// GenericValue *. It is not a pointer to a GenericValue containing the
/// address at which to store Val.
void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr,
const Type *Ty);
Type *Ty);
void InitializeMemory(const Constant *Init, void *Addr);
@ -440,7 +439,7 @@ class ExecutionEngine {
GenericValue getConstantValue(const Constant *C);
void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
const Type *Ty);
Type *Ty);
};
namespace EngineKind {
@ -463,6 +462,7 @@ class EngineBuilder {
CodeGenOpt::Level OptLevel;
JITMemoryManager *JMM;
bool AllocateGVsWithCode;
Reloc::Model RelocModel;
CodeModel::Model CMModel;
std::string MArch;
std::string MCPU;
@ -476,7 +476,8 @@ class EngineBuilder {
OptLevel = CodeGenOpt::Default;
JMM = NULL;
AllocateGVsWithCode = false;
CMModel = CodeModel::Default;
RelocModel = Reloc::Default;
CMModel = CodeModel::JITDefault;
UseMCJIT = false;
}
@ -517,8 +518,16 @@ class EngineBuilder {
return *this;
}
/// setRelocationModel - Set the relocation model that the ExecutionEngine
/// target is using. Defaults to target specific default "Reloc::Default".
EngineBuilder &setRelocationModel(Reloc::Model RM) {
RelocModel = RM;
return *this;
}
/// setCodeModel - Set the CodeModel that the ExecutionEngine target
/// data is using. Defaults to target specific default "CodeModel::Default".
/// data is using. Defaults to target specific default
/// "CodeModel::JITDefault".
EngineBuilder &setCodeModel(CodeModel::Model M) {
CMModel = M;
return *this;
@ -569,6 +578,8 @@ class EngineBuilder {
StringRef MArch,
StringRef MCPU,
const SmallVectorImpl<std::string>& MAttrs,
Reloc::Model RM,
CodeModel::Model CM,
std::string *Err);
ExecutionEngine *create();

View File

@ -117,11 +117,11 @@ class Function : public GlobalValue,
/// function is automatically inserted into the end of the function list for
/// the module.
///
Function(const FunctionType *Ty, LinkageTypes Linkage,
Function(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = 0);
public:
static Function *Create(const FunctionType *Ty, LinkageTypes Linkage,
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = 0) {
return new(0) Function(Ty, Linkage, N, M);
}

View File

@ -23,7 +23,6 @@
namespace llvm {
class Module;
class Constant;
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
@ -41,11 +40,11 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
}
/// GlobalAlias ctor - If a parent module is specified, the alias is
/// automatically inserted into the end of the specified module's alias list.
GlobalAlias(const Type *Ty, LinkageTypes Linkage, const Twine &Name = "",
GlobalAlias(Type *Ty, LinkageTypes Linkage, const Twine &Name = "",
Constant* Aliasee = 0, Module *Parent = 0);
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
@ -60,10 +59,10 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
/// set/getAliasee - These methods retrive and set alias target.
void setAliasee(Constant *GV);
const Constant *getAliasee() const {
return cast_or_null<Constant>(getOperand(0));
return getOperand(0);
}
Constant *getAliasee() {
return cast_or_null<Constant>(getOperand(0));
return getOperand(0);
}
/// getAliasedGlobal() - Aliasee can be either global or bitcast of
/// global. This method retrives the global for both aliasee flavours.
@ -88,7 +87,7 @@ struct OperandTraits<GlobalAlias> :
public FixedNumOperandTraits<GlobalAlias, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Value)
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant)
} // End llvm namespace

View File

@ -57,7 +57,7 @@ class GlobalValue : public Constant {
};
protected:
GlobalValue(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
GlobalValue(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
LinkageTypes linkage, const Twine &Name)
: Constant(ty, vty, Ops, NumOps), Parent(0),
Linkage(linkage), Visibility(DefaultVisibility), Alignment(0),

View File

@ -50,12 +50,12 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
}
/// GlobalVariable ctor - If a parent module is specified, the global is
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = 0, const Twine &Name = "",
bool ThreadLocal = false, unsigned AddressSpace = 0);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
GlobalVariable(Module &M, const Type *Ty, bool isConstant,
GlobalVariable(Module &M, Type *Ty, bool isConstant,
LinkageTypes Linkage, Constant *Initializer,
const Twine &Name,
GlobalVariable *InsertBefore = 0, bool ThreadLocal = false,

View File

@ -65,7 +65,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeBasicCallGraphPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);
void initializeBlockPlacementPass(PassRegistry&);
void initializeBranchProbabilityInfoPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
@ -143,9 +143,8 @@ void initializeLowerAtomicPass(PassRegistry&);
void initializeLowerExpectIntrinsicPass(PassRegistry&);
void initializeLowerIntrinsicsPass(PassRegistry&);
void initializeLowerInvokePass(PassRegistry&);
void initializeLowerSetJmpPass(PassRegistry&);
void initializeLowerSwitchPass(PassRegistry&);
void initializeMachineBlockFrequencyPass(PassRegistry&);
void initializeMachineBlockFrequencyInfoPass(PassRegistry&);
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
void initializeMachineCSEPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
@ -220,7 +219,6 @@ void initializeStripNonDebugSymbolsPass(PassRegistry&);
void initializeStripSymbolsPass(PassRegistry&);
void initializeStrongPHIEliminationPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDupPass(PassRegistry&);
void initializeTargetDataPass(PassRegistry&);
void initializeTargetLibraryInfoPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);

View File

@ -43,7 +43,7 @@ class InlineAsm : public Value {
bool HasSideEffects;
bool IsAlignStack;
InlineAsm(const PointerType *Ty, const std::string &AsmString,
InlineAsm(PointerType *Ty, const std::string &AsmString,
const std::string &Constraints, bool hasSideEffects,
bool isAlignStack);
virtual ~InlineAsm();
@ -55,7 +55,7 @@ class InlineAsm : public Value {
/// InlineAsm::get - Return the specified uniqued inline asm string.
///
static InlineAsm *get(const FunctionType *Ty, StringRef AsmString,
static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack = false);
@ -79,7 +79,7 @@ class InlineAsm : public Value {
/// the specified constraint string is legal for the type. This returns true
/// if legal, false if not.
///
static bool Verify(const FunctionType *Ty, StringRef Constraints);
static bool Verify(FunctionType *Ty, StringRef Constraints);
// Constraint String Parsing
enum ConstraintPrefix {
@ -219,6 +219,7 @@ class InlineAsm : public Value {
static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind");
return Kind | (NumOps << 3);
}
@ -227,9 +228,24 @@ class InlineAsm : public Value {
/// to a previous output operand.
static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
unsigned MatchedOperandNo) {
assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
}
/// getFlagWordForRegClass - Augment an existing flag word returned by
/// getFlagWord with the required register class for the following register
/// operands.
/// A tied use operand cannot have a register class, use the register class
/// from the def operand instead.
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
// Store RC + 1, reserve the value 0 to mean 'no register class'.
++RC;
assert(RC <= 0x7fff && "Too large register class ID");
assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
return InputFlag | (RC << 16);
}
static unsigned getKind(unsigned Flags) {
return Flags & 7;
}
@ -259,6 +275,19 @@ class InlineAsm : public Value {
return true;
}
/// hasRegClassConstraint - Returns true if the flag contains a register
/// class constraint. Sets RC to the register class ID.
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
if (Flag & Flag_MatchingOperand)
return false;
unsigned High = Flag >> 16;
// getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
// stores RC + 1.
if (!High)
return false;
RC = High - 1;
return true;
}
};

View File

@ -34,12 +34,12 @@ class LLVMContext;
///
class TerminatorInst : public Instruction {
protected:
TerminatorInst(const Type *Ty, Instruction::TermOps iType,
TerminatorInst(Type *Ty, Instruction::TermOps iType,
Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0)
: Instruction(Ty, iType, Ops, NumOps, InsertBefore) {}
TerminatorInst(const Type *Ty, Instruction::TermOps iType,
TerminatorInst(Type *Ty, Instruction::TermOps iType,
Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
: Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
@ -91,12 +91,12 @@ class UnaryInstruction : public Instruction {
void *operator new(size_t, unsigned); // Do not implement
protected:
UnaryInstruction(const Type *Ty, unsigned iType, Value *V,
UnaryInstruction(Type *Ty, unsigned iType, Value *V,
Instruction *IB = 0)
: Instruction(Ty, iType, &Op<0>(), 1, IB) {
Op<0>() = V;
}
UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
: Instruction(Ty, iType, &Op<0>(), 1, IAE) {
Op<0>() = V;
}
@ -141,9 +141,9 @@ class BinaryOperator : public Instruction {
void *operator new(size_t, unsigned); // Do not implement
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd);
virtual BinaryOperator *clone_impl() const;
public:
@ -390,13 +390,13 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
class CastInst : public UnaryInstruction {
protected:
/// @brief Constructor with insert-before-instruction semantics for subclasses
CastInst(const Type *Ty, unsigned iType, Value *S,
CastInst(Type *Ty, unsigned iType, Value *S,
const Twine &NameStr = "", Instruction *InsertBefore = 0)
: UnaryInstruction(Ty, iType, S, InsertBefore) {
setName(NameStr);
}
/// @brief Constructor with insert-at-end-of-block semantics for subclasses
CastInst(const Type *Ty, unsigned iType, Value *S,
CastInst(Type *Ty, unsigned iType, Value *S,
const Twine &NameStr, BasicBlock *InsertAtEnd)
: UnaryInstruction(Ty, iType, S, InsertAtEnd) {
setName(NameStr);
@ -411,7 +411,7 @@ class CastInst : public UnaryInstruction {
static CastInst *Create(
Instruction::CastOps, ///< The opcode of the cast instruction
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -424,7 +424,7 @@ class CastInst : public UnaryInstruction {
static CastInst *Create(
Instruction::CastOps, ///< The opcode for the cast instruction
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which operand is casted
Type *Ty, ///< The type to which operand is casted
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
@ -432,7 +432,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a ZExt or BitCast cast instruction
static CastInst *CreateZExtOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -440,7 +440,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a ZExt or BitCast cast instruction
static CastInst *CreateZExtOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which operand is casted
Type *Ty, ///< The type to which operand is casted
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
@ -448,7 +448,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a SExt or BitCast cast instruction
static CastInst *CreateSExtOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -456,7 +456,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a SExt or BitCast cast instruction
static CastInst *CreateSExtOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which operand is casted
Type *Ty, ///< The type to which operand is casted
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
@ -464,7 +464,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a BitCast or a PtrToInt cast instruction
static CastInst *CreatePointerCast(
Value *S, ///< The pointer value to be casted (operand 0)
const Type *Ty, ///< The type to which operand is casted
Type *Ty, ///< The type to which operand is casted
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
@ -472,7 +472,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a BitCast or a PtrToInt cast instruction
static CastInst *CreatePointerCast(
Value *S, ///< The pointer value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -480,7 +480,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
static CastInst *CreateIntegerCast(
Value *S, ///< The pointer value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
bool isSigned, ///< Whether to regard S as signed or not
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
@ -489,7 +489,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
static CastInst *CreateIntegerCast(
Value *S, ///< The integer value to be casted (operand 0)
const Type *Ty, ///< The integer type to which operand is casted
Type *Ty, ///< The integer type to which operand is casted
bool isSigned, ///< Whether to regard S as signed or not
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
@ -498,7 +498,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
static CastInst *CreateFPCast(
Value *S, ///< The floating point value to be casted
const Type *Ty, ///< The floating point type to cast to
Type *Ty, ///< The floating point type to cast to
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -506,7 +506,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
static CastInst *CreateFPCast(
Value *S, ///< The floating point value to be casted
const Type *Ty, ///< The floating point type to cast to
Type *Ty, ///< The floating point type to cast to
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
@ -514,7 +514,7 @@ class CastInst : public UnaryInstruction {
/// @brief Create a Trunc or BitCast cast instruction
static CastInst *CreateTruncOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which cast should be made
Type *Ty, ///< The type to which cast should be made
const Twine &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the instruction
);
@ -522,15 +522,15 @@ class CastInst : public UnaryInstruction {
/// @brief Create a Trunc or BitCast cast instruction
static CastInst *CreateTruncOrBitCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< The type to which operand is casted
Type *Ty, ///< The type to which operand is casted
const Twine &Name, ///< The name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
/// @brief Check whether it is valid to call getCastOpcode for these types.
static bool isCastable(
const Type *SrcTy, ///< The Type from which the value should be cast.
const Type *DestTy ///< The Type to which the value should be cast.
Type *SrcTy, ///< The Type from which the value should be cast.
Type *DestTy ///< The Type to which the value should be cast.
);
/// Returns the opcode necessary to cast Val into Ty using usual casting
@ -539,7 +539,7 @@ class CastInst : public UnaryInstruction {
static Instruction::CastOps getCastOpcode(
const Value *Val, ///< The value to cast
bool SrcIsSigned, ///< Whether to treat the source as signed
const Type *Ty, ///< The Type to which the value should be casted
Type *Ty, ///< The Type to which the value should be casted
bool DstIsSigned ///< Whether to treate the dest. as signed
);
@ -568,14 +568,14 @@ class CastInst : public UnaryInstruction {
/// @brief Determine if the described cast is a no-op cast.
static bool isNoopCast(
Instruction::CastOps Opcode, ///< Opcode of cast
const Type *SrcTy, ///< SrcTy of cast
const Type *DstTy, ///< DstTy of cast
const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
Type *SrcTy, ///< SrcTy of cast
Type *DstTy, ///< DstTy of cast
Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
);
/// @brief Determine if this cast is a no-op cast.
bool isNoopCast(
const Type *IntPtrTy ///< Integer type corresponding to pointer
Type *IntPtrTy ///< Integer type corresponding to pointer
) const;
/// Determine how a pair of casts can be eliminated, if they can be at all.
@ -587,10 +587,10 @@ class CastInst : public UnaryInstruction {
static unsigned isEliminableCastPair(
Instruction::CastOps firstOpcode, ///< Opcode of first cast
Instruction::CastOps secondOpcode, ///< Opcode of second cast
const Type *SrcTy, ///< SrcTy of 1st cast
const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
const Type *DstTy, ///< DstTy of 2nd cast
const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
Type *SrcTy, ///< SrcTy of 1st cast
Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
Type *DstTy, ///< DstTy of 2nd cast
Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
);
/// @brief Return the opcode of this CastInst
@ -599,15 +599,15 @@ class CastInst : public UnaryInstruction {
}
/// @brief Return the source type, as a convenience
const Type* getSrcTy() const { return getOperand(0)->getType(); }
Type* getSrcTy() const { return getOperand(0)->getType(); }
/// @brief Return the destination type, as a convenience
const Type* getDestTy() const { return getType(); }
Type* getDestTy() const { return getType(); }
/// This method can be used to determine if a cast from S to DstTy using
/// Opcode op is valid or not.
/// @returns true iff the proposed cast is valid.
/// @brief Determine if a cast is valid without creating one.
static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy);
static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const CastInst *) { return true; }
@ -629,11 +629,11 @@ class CmpInst : public Instruction {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
CmpInst(); // do not implement
protected:
CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred,
CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
Value *LHS, Value *RHS, const Twine &Name = "",
Instruction *InsertBefore = 0);
CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred,
CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
Value *LHS, Value *RHS, const Twine &Name,
BasicBlock *InsertAtEnd);
@ -825,8 +825,8 @@ class CmpInst : public Instruction {
}
/// @brief Create a result type for fcmp/icmp
static const Type* makeCmpResultType(const Type* opnd_type) {
if (const VectorType* vt = dyn_cast<const VectorType>(opnd_type)) {
static Type* makeCmpResultType(Type* opnd_type) {
if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
return VectorType::get(Type::getInt1Ty(opnd_type->getContext()),
vt->getNumElements());
}

View File

@ -100,76 +100,80 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst)
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
HANDLE_TERM_INST ( 6, Unwind , UnwindInst)
HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
LAST_TERM_INST ( 7)
HANDLE_TERM_INST ( 7, Resume , ResumeInst)
HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst)
LAST_TERM_INST ( 8)
// Standard binary operators...
FIRST_BINARY_INST( 8)
HANDLE_BINARY_INST( 8, Add , BinaryOperator)
HANDLE_BINARY_INST( 9, FAdd , BinaryOperator)
HANDLE_BINARY_INST(10, Sub , BinaryOperator)
HANDLE_BINARY_INST(11, FSub , BinaryOperator)
HANDLE_BINARY_INST(12, Mul , BinaryOperator)
HANDLE_BINARY_INST(13, FMul , BinaryOperator)
HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
HANDLE_BINARY_INST(17, URem , BinaryOperator)
HANDLE_BINARY_INST(18, SRem , BinaryOperator)
HANDLE_BINARY_INST(19, FRem , BinaryOperator)
FIRST_BINARY_INST( 9)
HANDLE_BINARY_INST( 9, Add , BinaryOperator)
HANDLE_BINARY_INST(10, FAdd , BinaryOperator)
HANDLE_BINARY_INST(11, Sub , BinaryOperator)
HANDLE_BINARY_INST(12, FSub , BinaryOperator)
HANDLE_BINARY_INST(13, Mul , BinaryOperator)
HANDLE_BINARY_INST(14, FMul , BinaryOperator)
HANDLE_BINARY_INST(15, UDiv , BinaryOperator)
HANDLE_BINARY_INST(16, SDiv , BinaryOperator)
HANDLE_BINARY_INST(17, FDiv , BinaryOperator)
HANDLE_BINARY_INST(18, URem , BinaryOperator)
HANDLE_BINARY_INST(19, SRem , BinaryOperator)
HANDLE_BINARY_INST(20, FRem , BinaryOperator)
// Logical operators (integer operands)
HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(23, And , BinaryOperator)
HANDLE_BINARY_INST(24, Or , BinaryOperator)
HANDLE_BINARY_INST(25, Xor , BinaryOperator)
LAST_BINARY_INST(25)
HANDLE_BINARY_INST(21, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(24, And , BinaryOperator)
HANDLE_BINARY_INST(25, Or , BinaryOperator)
HANDLE_BINARY_INST(26, Xor , BinaryOperator)
LAST_BINARY_INST(26)
// Memory operators...
FIRST_MEMORY_INST(26)
HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(28, Store , StoreInst )
HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(29)
FIRST_MEMORY_INST(27)
HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(29, Store , StoreInst )
HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
HANDLE_MEMORY_INST(31, Fence , FenceInst )
HANDLE_MEMORY_INST(32, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(33, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(33)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(30)
HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(41)
FIRST_CAST_INST(34)
HANDLE_CAST_INST(34, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(35, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(36, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(37, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(38, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(39, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(40, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(41, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(42, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(43, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(44, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(45, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(45)
// Other operators...
FIRST_OTHER_INST(42)
HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate
LAST_OTHER_INST(54)
FIRST_OTHER_INST(46)
HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction.
LAST_OTHER_INST(59)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@ -223,6 +223,13 @@ class Instruction : public User, public ilist_node<Instruction> {
///
bool mayReadFromMemory() const;
/// mayReadOrWriteMemory - Return true if this instruction may read or
/// write memory.
///
bool mayReadOrWriteMemory() const {
return mayReadFromMemory() || mayWriteToMemory();
}
/// mayThrow - Return true if this instruction may throw an exception.
///
bool mayThrow() const;
@ -365,9 +372,9 @@ class Instruction : public User, public ilist_node<Instruction> {
return getSubclassDataFromValue() & ~HasMetadataBit;
}
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0);
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd);
virtual Instruction *clone_impl() const = 0;

File diff suppressed because it is too large Load Diff

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