diff options
Diffstat (limited to 'include')
95 files changed, 2013 insertions, 1070 deletions
diff --git a/include/llvm-c/BitReader.h b/include/llvm-c/BitReader.h index 59269ce..6db6607 100644 --- a/include/llvm-c/BitReader.h +++ b/include/llvm-c/BitReader.h @@ -36,18 +36,28 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule, char **OutMessage); -/* Reads a module from the specified path, returning via the OutMP parameter - a module provider which performs lazy deserialization. Returns 0 on success. - Optionally returns a human-readable error message via OutMessage. */ -LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, - LLVMModuleProviderRef *OutMP, - char **OutMessage); +/** Reads a module from the specified path, returning via the OutMP parameter + a module provider which performs lazy deserialization. Returns 0 on success. + Optionally returns a human-readable error message via OutMessage. */ +LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, + LLVMMemoryBufferRef MemBuf, + LLVMModuleRef *OutM, + char **OutMessage); + +LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, + char **OutMessage); + +/** Deprecated: Use LLVMGetBitcodeModuleInContext instead. */ LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef *OutMP, char **OutMessage); +/** Deprecated: Use LLVMGetBitcodeModule instead. */ +LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, + LLVMModuleProviderRef *OutMP, + char **OutMessage); #ifdef __cplusplus } diff --git a/include/llvm-c/BitWriter.h b/include/llvm-c/BitWriter.h index 008ff9f..bcbfb11 100644 --- a/include/llvm-c/BitWriter.h +++ b/include/llvm-c/BitWriter.h @@ -28,13 +28,16 @@ extern "C" { /*===-- Operations on modules ---------------------------------------------===*/ -/* Writes a module to an open file descriptor. Returns 0 on success. - Closes the Handle. Use dup first if this is not what you want. */ -int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle); - -/* Writes a module to the specified path. Returns 0 on success. */ +/** Writes a module to the specified path. Returns 0 on success. */ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path); +/** Writes a module to an open file descriptor. Returns 0 on success. */ +int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose, + int Unbuffered); + +/** Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file + descriptor. Returns 0 on success. Closes the Handle. */ +int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle); #ifdef __cplusplus } diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 98358fe..733b92c 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -92,11 +92,8 @@ typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef; /** See the llvm::PassManagerBase class. */ typedef struct LLVMOpaquePassManager *LLVMPassManagerRef; -/** - * Used to iterate through the uses of a Value, allowing access to all Values - * that use this Value. See the llvm::Use and llvm::value_use_iterator classes. - */ -typedef struct LLVMOpaqueUseIterator *LLVMUseIteratorRef; +/** Used to get the users and usees of a Value. See the llvm::Use class. */ +typedef struct LLVMOpaqueUse *LLVMUseRef; typedef enum { LLVMZExtAttribute = 1<<0, @@ -115,67 +112,81 @@ typedef enum { LLVMOptimizeForSizeAttribute = 1<<13, LLVMStackProtectAttribute = 1<<14, LLVMStackProtectReqAttribute = 1<<15, + LLVMAlignment = 31<<16, LLVMNoCaptureAttribute = 1<<21, LLVMNoRedZoneAttribute = 1<<22, LLVMNoImplicitFloatAttribute = 1<<23, LLVMNakedAttribute = 1<<24, - LLVMInlineHintAttribute = 1<<25 + LLVMInlineHintAttribute = 1<<25, + LLVMStackAlignment = 7<<26 } LLVMAttribute; typedef enum { + /* Terminator Instructions */ LLVMRet = 1, LLVMBr = 2, LLVMSwitch = 3, - LLVMInvoke = 4, - LLVMUnwind = 5, - LLVMUnreachable = 6, - LLVMAdd = 7, - LLVMFAdd = 8, - LLVMSub = 9, - LLVMFSub = 10, - LLVMMul = 11, - LLVMFMul = 12, - LLVMUDiv = 13, - LLVMSDiv = 14, - LLVMFDiv = 15, - LLVMURem = 16, - LLVMSRem = 17, - LLVMFRem = 18, - LLVMShl = 19, - LLVMLShr = 20, - LLVMAShr = 21, - LLVMAnd = 22, - LLVMOr = 23, - LLVMXor = 24, - LLVMMalloc = 25, - LLVMFree = 26, - LLVMAlloca = 27, - LLVMLoad = 28, - LLVMStore = 29, - LLVMGetElementPtr = 30, - LLVMTrunk = 31, - LLVMZExt = 32, - LLVMSExt = 33, - LLVMFPToUI = 34, - LLVMFPToSI = 35, - LLVMUIToFP = 36, - LLVMSIToFP = 37, - LLVMFPTrunc = 38, - LLVMFPExt = 39, - LLVMPtrToInt = 40, - LLVMIntToPtr = 41, - LLVMBitCast = 42, - LLVMICmp = 43, - LLVMFCmp = 44, - LLVMPHI = 45, - LLVMCall = 46, - LLVMSelect = 47, - LLVMVAArg = 50, - LLVMExtractElement = 51, - LLVMInsertElement = 52, - LLVMShuffleVector = 53, - LLVMExtractValue = 54, - LLVMInsertValue = 55 + LLVMIndirectBr = 4, + LLVMInvoke = 5, + LLVMUnwind = 6, + LLVMUnreachable = 7, + + /* Standard Binary Operators */ + LLVMAdd = 8, + LLVMFAdd = 9, + LLVMSub = 10, + LLVMFSub = 11, + LLVMMul = 12, + LLVMFMul = 13, + LLVMUDiv = 14, + LLVMSDiv = 15, + LLVMFDiv = 16, + LLVMURem = 17, + LLVMSRem = 18, + LLVMFRem = 19, + + /* Logical Operators */ + LLVMShl = 20, + LLVMLShr = 21, + LLVMAShr = 22, + LLVMAnd = 23, + LLVMOr = 24, + LLVMXor = 25, + + /* Memory Operators */ + LLVMAlloca = 26, + LLVMLoad = 27, + LLVMStore = 28, + LLVMGetElementPtr = 29, + + /* Cast Operators */ + LLVMTrunc = 30, + LLVMZExt = 31, + LLVMSExt = 32, + LLVMFPToUI = 33, + LLVMFPToSI = 34, + LLVMUIToFP = 35, + LLVMSIToFP = 36, + LLVMFPTrunc = 37, + LLVMFPExt = 38, + LLVMPtrToInt = 39, + LLVMIntToPtr = 40, + LLVMBitCast = 41, + + /* Other Operators */ + LLVMICmp = 42, + LLVMFCmp = 43, + LLVMPHI = 44, + LLVMCall = 45, + LLVMSelect = 46, + /* UserOp1 */ + /* UserOp2 */ + LLVMVAArg = 49, + LLVMExtractElement = 50, + LLVMInsertElement = 51, + LLVMShuffleVector = 52, + LLVMExtractValue = 53, + LLVMInsertValue = 54 } LLVMOpcode; typedef enum { @@ -193,7 +204,8 @@ typedef enum { LLVMPointerTypeKind, /**< Pointers */ LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ - LLVMMetadataTypeKind /**< Metadata */ + LLVMMetadataTypeKind, /**< Metadata */ + LLVMUnionTypeKind /**< Unions */ } LLVMTypeKind; typedef enum { @@ -269,13 +281,19 @@ typedef enum { void LLVMDisposeMessage(char *Message); -/*===-- Modules -----------------------------------------------------------===*/ +/*===-- Contexts ----------------------------------------------------------===*/ /* Create and destroy contexts. */ LLVMContextRef LLVMContextCreate(void); LLVMContextRef LLVMGetGlobalContext(void); void LLVMContextDispose(LLVMContextRef C); +unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name, + unsigned SLen); +unsigned LLVMGetMDKindID(const char* Name, unsigned SLen); + +/*===-- Modules -----------------------------------------------------------===*/ + /* Create and destroy modules. */ /** See llvm::Module::Module. */ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID); @@ -372,6 +390,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); +/* Operations on union types */ +LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, + unsigned ElementCount); +LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount); +unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy); +void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest); + /* Operations on array, pointer, and vector types (sequence types) */ LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); @@ -477,6 +502,9 @@ const char *LLVMGetValueName(LLVMValueRef Val); void LLVMSetValueName(LLVMValueRef Val, const char *Name); void LLVMDumpValue(LLVMValueRef Val); void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal); +int LLVMHasMetadata(LLVMValueRef Val); +LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID); +void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); /* Conversion functions. Return the input value if it is an instance of the specified class, otherwise NULL. See llvm::dyn_cast_or_null<>. */ @@ -485,10 +513,10 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal); LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST) /* Operations on Uses */ -LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val); -LLVMUseIteratorRef LLVMGetNextUse(LLVMUseIteratorRef U); -LLVMValueRef LLVMGetUser(LLVMUseIteratorRef U); -LLVMValueRef LLVMGetUsedValue(LLVMUseIteratorRef U); +LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val); +LLVMUseRef LLVMGetNextUse(LLVMUseRef U); +LLVMValueRef LLVMGetUser(LLVMUseRef U); +LLVMValueRef LLVMGetUsedValue(LLVMUseRef U); /* Operations on Users */ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index); @@ -502,6 +530,14 @@ LLVMBool LLVMIsNull(LLVMValueRef Val); LLVMBool LLVMIsUndef(LLVMValueRef Val); LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); +/* Operations on metadata */ +LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, + unsigned SLen); +LLVMValueRef LLVMMDString(const char *Str, unsigned SLen); +LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, + unsigned Count); +LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); + /* Operations on scalar constants */ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, LLVMBool SignExtend); @@ -531,20 +567,28 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed); LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size); +LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val); /* Constant expressions */ LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal); LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty); LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty); LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal); +LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal); +LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal); LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal); LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal); LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); @@ -610,6 +654,7 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, const char *Constraints, LLVMBool HasSideEffects, LLVMBool IsAlignStack); +LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB); /* Operations on global variables, functions, and aliases (globals) */ LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global); @@ -625,6 +670,9 @@ void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes); /* Operations on global variables */ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name); +LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty, + const char *Name, + unsigned AddressSpace); LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name); LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M); LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M); @@ -745,6 +793,11 @@ void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr, const char *Name); void LLVMDisposeBuilder(LLVMBuilderRef Builder); +/* Metadata */ +void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L); +LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder); +void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst); + /* Terminators */ LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef); LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V); @@ -755,6 +808,8 @@ LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If, LLVMBasicBlockRef Then, LLVMBasicBlockRef Else); LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V, LLVMBasicBlockRef Else, unsigned NumCases); +LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr, + unsigned NumDests); LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, @@ -766,19 +821,32 @@ LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest); +/* Add a destination to the indirectbr instruction */ +void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest); + /* Arithmetic */ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); +LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); +LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); LLVMValueRef LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); +LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); +LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); LLVMValueRef LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, @@ -807,7 +875,14 @@ LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); +LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name); LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name); +LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V, + const char *Name); +LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V, + const char *Name); LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name); LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name); @@ -866,6 +941,8 @@ LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); +LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/ @@ -947,6 +1024,9 @@ LLVMPassManagerRef LLVMCreatePassManager(void); provider. It does not take ownership of the module provider. This type of pipeline is suitable for code generation and JIT compilation tasks. See llvm::FunctionPassManager::FunctionPassManager. */ +LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M); + +/** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */ LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP); /** Initializes, executes on the provided module, and finalizes all of the @@ -1018,7 +1098,7 @@ namespace llvm { DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef ) - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef ) + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef ) DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef ) /* LLVMModuleProviderRef exists for historical reasons, but now just holds a * Module. diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h index 151c935..5a98a77 100644 --- a/include/llvm-c/ExecutionEngine.h +++ b/include/llvm-c/ExecutionEngine.h @@ -55,14 +55,30 @@ void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal); /*===-- Operations on execution engines -----------------------------------===*/ +LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE, + LLVMModuleRef M, + char **OutError); + +LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, + LLVMModuleRef M, + char **OutError); + +LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, + LLVMModuleRef M, + unsigned OptLevel, + char **OutError); + +/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */ LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, char **OutError); +/** Deprecated: Use LLVMCreateInterpreterForModule instead. */ LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp, LLVMModuleProviderRef MP, char **OutError); +/** Deprecated: Use LLVMCreateJITCompilerForModule instead. */ LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, @@ -84,8 +100,15 @@ LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F, void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F); +void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M); + +/** Deprecated: Use LLVMAddModule instead. */ void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP); +LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M, + LLVMModuleRef *OutMod, char **OutError); + +/** Deprecated: Use LLVMRemoveModule instead. */ LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP, LLVMModuleRef *OutMod, char **OutError); diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index f81109a..3cccc81 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -173,11 +173,16 @@ namespace llvm { fcZero }; + enum uninitializedTag { + uninitialized + }; + // Constructors. APFloat(const fltSemantics &); // Default construct to 0.0 APFloat(const fltSemantics &, const StringRef &); APFloat(const fltSemantics &, integerPart); - APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0); + APFloat(const fltSemantics &, fltCategory, bool negative); + APFloat(const fltSemantics &, uninitializedTag); explicit APFloat(double d); explicit APFloat(float f); explicit APFloat(const APInt &, bool isIEEE = false); @@ -199,7 +204,26 @@ namespace llvm { /// default. The value is truncated as necessary. static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, unsigned type = 0) { - return APFloat(Sem, fcNaN, Negative, type); + if (type) { + APInt fill(64, type); + return getQNaN(Sem, Negative, &fill); + } else { + return getQNaN(Sem, Negative, 0); + } + } + + /// getQNan - Factory for QNaN values. + static APFloat getQNaN(const fltSemantics &Sem, + bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, false, Negative, payload); + } + + /// getSNan - Factory for SNaN values. + static APFloat getSNaN(const fltSemantics &Sem, + bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, true, Negative, payload); } /// getLargest - Returns the largest finite number in the given @@ -320,7 +344,7 @@ namespace llvm { /// 1.01E-2 4 1 1.01E-2 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0, - unsigned FormatMaxPadding = 3); + unsigned FormatMaxPadding = 3) const; private: @@ -350,7 +374,9 @@ namespace llvm { opStatus modSpecials(const APFloat &); /* Miscellany. */ - void makeNaN(unsigned = 0); + static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill); + void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0); opStatus normalize(roundingMode, lostFraction); opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); cmpResult compareAbsoluteValue(const APFloat &) const; diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 88aa995..3f67ffb 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -150,7 +150,17 @@ class APInt { return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; } + /// Converts a string into a number. The string must be non-empty + /// and well-formed as a number of the given base. The bit-width + /// must be sufficient to hold the result. + /// /// This is used by the constructors that take string arguments. + /// + /// StringRef::getAsInteger is superficially similar but (1) does + /// not assume that the string is well-formed and (2) grows the + /// result to hold the input. + /// + /// @param radix 2, 8, 10, or 16 /// @brief Convert a char array into an APInt void fromString(unsigned numBits, const StringRef &str, uint8_t radix); @@ -571,6 +581,21 @@ public: /// @brief Bitwise OR assignment operator. APInt& operator|=(const APInt& RHS); + /// Performs a bitwise OR operation on this APInt and RHS. RHS is + /// logically zero-extended or truncated to match the bit-width of + /// the LHS. + /// + /// @brief Bitwise OR assignment operator. + APInt& operator|=(uint64_t RHS) { + if (isSingleWord()) { + VAL |= RHS; + clearUnusedBits(); + } else { + pVal[0] |= RHS; + } + return *this; + } + /// Performs a bitwise XOR operation on this APInt and RHS. The result is /// assigned to *this. /// @returns *this after XORing with RHS. @@ -1308,6 +1333,9 @@ public: /// Set the given bit of a bignum. Zero-based. static void tcSetBit(integerPart *, unsigned int bit); + /// Clear the given bit of a bignum. Zero-based. + static void tcClearBit(integerPart *, unsigned int bit); + /// Returns the bit number of the least or most significant set bit /// of a number. If the input number has no bits set -1U is /// returned. diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h index 1facfa0..45ba198 100644 --- a/include/llvm/ADT/DeltaAlgorithm.h +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -52,7 +52,7 @@ private: /// \return - The test result. bool GetTestResult(const changeset_ty &Changes); - /// Split - Partition a set of changes \arg Sinto one or two subsets. + /// Split - Partition a set of changes \arg S into one or two subsets. void Split(const changeset_ty &S, changesetlist_ty &Res); /// Delta - Minimize a set of \arg Changes which has been partioned into diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index f5f3d49..d9d6f73 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -203,7 +203,7 @@ public: return member_iterator(I->getLeader()); } member_iterator findLeader(const ElemTy &V) const { - return findLeader(TheMapping.find(V)); + return findLeader(TheMapping.find(ECValue(V))); } diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index d538295..b5ca374 100644 --- a/include/llvm/ADT/ScopedHashTable.h +++ b/include/llvm/ADT/ScopedHashTable.h @@ -36,10 +36,10 @@ namespace llvm { -template <typename K, typename V> +template <typename K, typename V, typename KInfo = DenseMapInfo<K> > class ScopedHashTable; -template <typename K, typename V> +template <typename K, typename V, typename KInfo = DenseMapInfo<K> > class ScopedHashTableVal { ScopedHashTableVal *NextInScope; ScopedHashTableVal *NextForKey; @@ -61,35 +61,39 @@ public: ScopedHashTableVal *getNextInScope() { return NextInScope; } }; -template <typename K, typename V> +template <typename K, typename V, typename KInfo = DenseMapInfo<K> > class ScopedHashTableScope { /// HT - The hashtable that we are active for. - ScopedHashTable<K, V> &HT; + ScopedHashTable<K, V, KInfo> &HT; /// PrevScope - This is the scope that we are shadowing in HT. ScopedHashTableScope *PrevScope; /// LastValInScope - This is the last value that was inserted for this scope /// or null if none have been inserted yet. - ScopedHashTableVal<K,V> *LastValInScope; + ScopedHashTableVal<K, V, KInfo> *LastValInScope; void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT public: - ScopedHashTableScope(ScopedHashTable<K, V> &HT); + ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &HT); ~ScopedHashTableScope(); private: - friend class ScopedHashTable<K, V>; - ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; } - void setLastValInScope(ScopedHashTableVal<K,V> *Val) { LastValInScope = Val; } + friend class ScopedHashTable<K, V, KInfo>; + ScopedHashTableVal<K, V, KInfo> *getLastValInScope() { + return LastValInScope; + } + void setLastValInScope(ScopedHashTableVal<K, V, KInfo> *Val) { + LastValInScope = Val; + } }; -template <typename K, typename V> +template <typename K, typename V, typename KInfo = DenseMapInfo<K> > class ScopedHashTableIterator { - ScopedHashTableVal<K,V> *Node; + ScopedHashTableVal<K, V, KInfo> *Node; public: - ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){} + ScopedHashTableIterator(ScopedHashTableVal<K, V, KInfo> *node) : Node(node) {} V &operator*() const { assert(Node && "Dereference end()"); @@ -117,35 +121,43 @@ public: }; -template <typename K, typename V> +template <typename K, typename V, typename KInfo> class ScopedHashTable { - DenseMap<K, ScopedHashTableVal<K,V>*> TopLevelMap; - ScopedHashTableScope<K, V> *CurScope; + DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap; + ScopedHashTableScope<K, V, KInfo> *CurScope; ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED - friend class ScopedHashTableScope<K, V>; + friend class ScopedHashTableScope<K, V, KInfo>; public: ScopedHashTable() : CurScope(0) {} ~ScopedHashTable() { assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } + bool count(const K &Key) const { + return TopLevelMap.count(Key); + } + + V lookup(const K &Key) { + return TopLevelMap[Key]->getValue(); + } + void insert(const K &Key, const V &Val) { assert(CurScope && "No scope active!"); - ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key]; + ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key]; - KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(), - KeyEntry, Key, Val); + KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(), + KeyEntry, Key, Val); CurScope->setLastValInScope(KeyEntry); } - typedef ScopedHashTableIterator<K, V> iterator; + typedef ScopedHashTableIterator<K, V, KInfo> iterator; iterator end() { return iterator(0); } iterator begin(const K &Key) { - typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I = + typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I = TopLevelMap.find(Key); if (I == TopLevelMap.end()) return end(); return iterator(I->second); @@ -154,28 +166,29 @@ public: /// ScopedHashTableScope ctor - Install this as the current scope for the hash /// table. -template <typename K, typename V> -ScopedHashTableScope<K, V>::ScopedHashTableScope(ScopedHashTable<K, V> &ht) - : HT(ht) { +template <typename K, typename V, typename KInfo> +ScopedHashTableScope<K, V, KInfo>:: + ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &ht) : HT(ht) { PrevScope = HT.CurScope; HT.CurScope = this; LastValInScope = 0; } -template <typename K, typename V> -ScopedHashTableScope<K, V>::~ScopedHashTableScope() { +template <typename K, typename V, typename KInfo> +ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() { assert(HT.CurScope == this && "Scope imbalance!"); HT.CurScope = PrevScope; // Pop and delete all values corresponding to this scope. - while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) { + while (ScopedHashTableVal<K, V, KInfo> *ThisEntry = LastValInScope) { // Pop this value out of the TopLevelMap. if (ThisEntry->getNextForKey() == 0) { assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry && "Scope imbalance!"); HT.TopLevelMap.erase(ThisEntry->getKey()); } else { - ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()]; + ScopedHashTableVal<K, V, KInfo> *&KeyEntry = + HT.TopLevelMap[ThisEntry->getKey()]; assert(KeyEntry == ThisEntry && "Scope imbalance!"); KeyEntry = ThisEntry->getNextForKey(); } diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index c29fc9f..ef08125 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -225,7 +225,7 @@ struct NextPowerOfTwo { }; -/// SmallPtrSet - This class implements a set which is optimizer for holding +/// SmallPtrSet - This class implements a set which is optimized for holding /// SmallSize or less elements. This internally rounds up SmallSize to the next /// power of two if it is not already a power of two. See the comments above /// SmallPtrSetImpl for details of the algorithm. diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 3064af3..9257770 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -18,6 +18,7 @@ namespace llvm { template<typename T> class SmallVectorImpl; + class APInt; /// StringRef - Represent a constant reference to a string, i.e. a character /// array and a length, which need not be null terminated. @@ -273,6 +274,19 @@ namespace llvm { // TODO: Provide overloads for int/unsigned that check for overflow. + /// getAsInteger - Parse the current string as an integer of the + /// specified radix, or of an autosensed radix if the radix given + /// is 0. The current value in Result is discarded, and the + /// storage is changed to be wide enough to store the parsed + /// integer. + /// + /// Returns true if the string does not solely consist of a valid + /// non-empty number in the appropriate base. + /// + /// APInt::fromString is superficially similar but assumes the + /// string is well-formed in the given radix. + bool getAsInteger(unsigned Radix, APInt &Result) const; + /// @} /// @name Substring Operations /// @{ @@ -355,7 +369,7 @@ namespace llvm { /// \param A - Where to put the substrings. /// \param Separator - The string to split on. /// \param MaxSplit - The maximum number of times the string is split. - /// \parm KeepEmpty - True if empty substring should be added. + /// \param KeepEmpty - True if empty substring should be added. void split(SmallVectorImpl<StringRef> &A, StringRef Separator, int MaxSplit = -1, bool KeepEmpty = true) const; diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 8798b0e..be31ea0 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -73,6 +73,7 @@ public: x86, // X86: i[3-9]86 x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore + mblaze, // MBlaze: mblaze InvalidArch }; diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index ccf0105..f105c20 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -459,9 +459,11 @@ namespace llvm { if (DbgNode && !isLexicalBlock()) DbgNode = 0; } - DIScope getContext() const { return getFieldAs<DIScope>(1); } - StringRef getDirectory() const { return getContext().getDirectory(); } - StringRef getFilename() const { return getContext().getFilename(); } + DIScope getContext() const { return getFieldAs<DIScope>(1); } + StringRef getDirectory() const { return getContext().getDirectory(); } + StringRef getFilename() const { return getContext().getFilename(); } + unsigned getLineNumber() const { return getUnsignedField(2); } + unsigned getColumnNumber() const { return getUnsignedField(3); } }; /// DINameSpace - A wrapper for a C++ style name space. @@ -636,7 +638,8 @@ namespace llvm { /// CreateLexicalBlock - This creates a descriptor for a lexical block /// with the specified parent context. - DILexicalBlock CreateLexicalBlock(DIDescriptor Context); + DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0, + unsigned Col = 0); /// CreateNameSpace - This creates new descriptor for a namespace /// with the specified parent context. diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 31c19c4..1e94f30 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -52,7 +52,7 @@ protected: Roots(), IsPostDominators(isPostDom) {} public: - /// getRoots - Return the root blocks of the current CFG. This may include + /// getRoots - Return the root blocks of the current CFG. This may include /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). /// @@ -225,7 +225,7 @@ protected: DenseMap<NodeT*, InfoRec> Info; void reset() { - for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), + for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), E = DomTreeNodes.end(); I != E; ++I) delete I->second; DomTreeNodes.clear(); @@ -248,7 +248,7 @@ protected: for (typename GraphTraits<Inverse<N> >::ChildIteratorType PI = GraphTraits<Inverse<N> >::child_begin(NewBB), PE = GraphTraits<Inverse<N> >::child_end(NewBB); PI != PE; ++PI) - PredBlocks.push_back(*PI); + PredBlocks.push_back(*PI); assert(!PredBlocks.empty() && "No predblocks??"); @@ -310,7 +310,7 @@ public: if (DomTreeNodes.size() != OtherDomTreeNodes.size()) return true; - for (typename DomTreeNodeMapType::const_iterator + for (typename DomTreeNodeMapType::const_iterator I = this->DomTreeNodes.begin(), E = this->DomTreeNodes.end(); I != E; ++I) { NodeT *BB = I->first; @@ -361,7 +361,7 @@ public: return properlyDominates(getNode(A), getNode(B)); } - bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, + bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, const DomTreeNodeBase<NodeT> *B) const { const DomTreeNodeBase<NodeT> *IDom; if (A == 0 || B == 0) return false; @@ -374,7 +374,7 @@ public: /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. bool isReachableFromEntry(NodeT* A) { - assert (!this->isPostDominator() + assert (!this->isPostDominator() && "This is not implemented for post dominators"); return dominates(&A->getParent()->front(), A); } @@ -384,7 +384,7 @@ public: /// inline bool dominates(const DomTreeNodeBase<NodeT> *A, const DomTreeNodeBase<NodeT> *B) { - if (B == A) + if (B == A) return true; // A node trivially dominates itself. if (A == 0 || B == 0) @@ -412,7 +412,7 @@ public: } inline bool dominates(const NodeT *A, const NodeT *B) { - if (A == B) + if (A == B) return true; // Cast away the const qualifiers here. This is ok since @@ -431,9 +431,9 @@ public: /// for basic block A and B. If there is no such block then return NULL. NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) { - assert (!this->isPostDominator() + assert (!this->isPostDominator() && "This is not implemented for post dominators"); - assert (A->getParent() == B->getParent() + assert (A->getParent() == B->getParent() && "Two blocks are not in same function"); // If either A or B is a entry block then it is nearest common dominator. @@ -478,14 +478,14 @@ public: // the CFG... /// addNewBlock - Add a new node to the dominator tree information. This - /// creates a new node as a child of DomBB dominator node,linking it into + /// creates a new node as a child of DomBB dominator node,linking it into /// the children list of the immediate dominator. DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) { assert(getNode(BB) == 0 && "Block already in dominator tree!"); DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB); assert(IDomNode && "Not immediate dominator specified for block!"); DFSInfoValid = false; - return DomTreeNodes[BB] = + return DomTreeNodes[BB] = IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode)); } @@ -503,7 +503,7 @@ public: changeImmediateDominator(getNode(BB), getNode(NewBB)); } - /// eraseNode - Removes a node from the dominator tree. Block must not + /// eraseNode - Removes a node from the dominator tree. Block must not /// domiante any other blocks. Removes node from its immediate dominator's /// children list. Deletes dominator node associated with basic block BB. void eraseNode(NodeT *BB) { @@ -708,7 +708,7 @@ public: DominatorTreeBase<BasicBlock>& getBase() { return *DT; } - /// getRoots - Return the root blocks of the current CFG. This may include + /// getRoots - Return the root blocks of the current CFG. This may include /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). /// @@ -785,7 +785,7 @@ public: } /// addNewBlock - Add a new node to the dominator tree information. This - /// creates a new node as a child of DomBB dominator node,linking it into + /// creates a new node as a child of DomBB dominator node,linking it into /// the children list of the immediate dominator. inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) { return DT->addNewBlock(BB, DomBB); @@ -802,7 +802,7 @@ public: DT->changeImmediateDominator(N, NewIDom); } - /// eraseNode - Removes a node from the dominator tree. Block must not + /// eraseNode - Removes a node from the dominator tree. Block must not /// domiante any other blocks. Removes node from its immediate dominator's /// children list. Deletes dominator node associated with basic block BB. inline void eraseNode(BasicBlock *BB) { @@ -820,7 +820,7 @@ public: } - virtual void releaseMemory() { + virtual void releaseMemory() { DT->releaseMemory(); } @@ -886,10 +886,10 @@ protected: const bool IsPostDominators; public: - DominanceFrontierBase(void *ID, bool isPostDom) + DominanceFrontierBase(void *ID, bool isPostDom) : FunctionPass(ID), IsPostDominators(isPostDom) {} - /// getRoots - Return the root blocks of the current CFG. This may include + /// getRoots - Return the root blocks of the current CFG. This may include /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). /// @@ -940,7 +940,7 @@ public: bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { std::set<BasicBlock *> tmpSet; for (DomSetType::const_iterator I = DS2.begin(), - E = DS2.end(); I != E; ++I) + E = DS2.end(); I != E; ++I) tmpSet.insert(*I); for (DomSetType::const_iterator I = DS1.begin(), @@ -965,14 +965,14 @@ public: bool compare(DominanceFrontierBase &Other) const { DomSetMapType tmpFrontiers; for (DomSetMapType::const_iterator I = Other.begin(), - E = Other.end(); I != E; ++I) + E = Other.end(); I != E; ++I) tmpFrontiers.insert(std::make_pair(I->first, I->second)); for (DomSetMapType::iterator I = tmpFrontiers.begin(), E = tmpFrontiers.end(); I != E; ) { BasicBlock *Node = I->first; const_iterator DFI = find(Node); - if (DFI == end()) + if (DFI == end()) return true; if (compareDomSet(I->second, DFI->second)) @@ -1001,7 +1001,7 @@ public: class DominanceFrontier : public DominanceFrontierBase { public: static char ID; // Pass ID, replacement for typeid - DominanceFrontier() : + DominanceFrontier() : DominanceFrontierBase(&ID, false) {} BasicBlock *getRoot() const { @@ -1033,7 +1033,7 @@ public: /// to reflect this change. void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB, DominatorTree *DT) { - // NewBB is now dominating BB. Which means BB's dominance + // NewBB is now dominating BB. Which means BB's dominance // frontier is now part of NewBB's dominance frontier. However, BB // itself is not member of NewBB's dominance frontier. DominanceFrontier::iterator NewDFI = find(NewBB); diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index b69bda8..dc616ca 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -16,29 +16,27 @@ #define LLVM_ANALYSIS_IVUSERS_H #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/ADT/SmallVector.h" -#include <map> +#include "llvm/Support/ValueHandle.h" namespace llvm { class DominatorTree; class Instruction; class Value; -struct IVUsersOfOneStride; - -/// IVStrideUse - Keep track of one use of a strided induction variable, where -/// the stride is stored externally. The Offset member keeps track of the -/// offset from the IV, User is the actual user of the operand, and -/// 'OperandValToReplace' is the operand of the User that is the use. +class IVUsers; +class ScalarEvolution; +class SCEV; + +/// IVStrideUse - Keep track of one use of a strided induction variable. +/// The Expr member keeps track of the expression, User is the actual user +/// instruction of the operand, and 'OperandValToReplace' is the operand of +/// the User that is the use. class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { public: - IVStrideUse(IVUsersOfOneStride *parent, - const SCEV *offset, + IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off, Instruction* U, Value *O) - : CallbackVH(U), Parent(parent), Offset(offset), - OperandValToReplace(O), - IsUseOfPostIncrementedValue(false) { + : CallbackVH(U), Parent(P), Stride(S), Offset(Off), + OperandValToReplace(O), IsUseOfPostIncrementedValue(false) { } /// getUser - Return the user instruction for this use. @@ -51,11 +49,19 @@ public: setValPtr(NewUser); } - /// getParent - Return a pointer to the IVUsersOfOneStride that owns + /// getParent - Return a pointer to the IVUsers that owns /// this IVStrideUse. - IVUsersOfOneStride *getParent() const { return Parent; } + IVUsers *getParent() const { return Parent; } + + /// getStride - Return the expression for the stride for the use. + const SCEV *getStride() const { return Stride; } + + /// setStride - Assign a new stride to this use. + void setStride(const SCEV *Val) { + Stride = Val; + } - /// getOffset - Return the offset to add to a theoeretical induction + /// getOffset - Return the offset to add to a theoretical induction /// variable that starts at zero and counts up by the stride to compute /// the value for the use. This always has the same type as the stride. const SCEV *getOffset() const { return Offset; } @@ -92,8 +98,11 @@ public: } private: - /// Parent - a pointer to the IVUsersOfOneStride that owns this IVStrideUse. - IVUsersOfOneStride *Parent; + /// Parent - a pointer to the IVUsers that owns this IVStrideUse. + IVUsers *Parent; + + /// Stride - The stride for this use. + const SCEV *Stride; /// Offset - The offset to add to the base induction expression. const SCEV *Offset; @@ -107,7 +116,7 @@ private: bool IsUseOfPostIncrementedValue; /// Deleted - Implementation of CallbackVH virtual function to - /// recieve notification when the User is deleted. + /// receive notification when the User is deleted. virtual void deleted(); }; @@ -138,42 +147,8 @@ private: mutable ilist_node<IVStrideUse> Sentinel; }; -/// IVUsersOfOneStride - This structure keeps track of all instructions that -/// have an operand that is based on the trip count multiplied by some stride. -struct IVUsersOfOneStride : public ilist_node<IVUsersOfOneStride> { -private: - IVUsersOfOneStride(const IVUsersOfOneStride &I); // do not implement - void operator=(const IVUsersOfOneStride &I); // do not implement - -public: - IVUsersOfOneStride() : Stride(0) {} - - explicit IVUsersOfOneStride(const SCEV *stride) : Stride(stride) {} - - /// Stride - The stride for all the contained IVStrideUses. This is - /// a constant for affine strides. - const SCEV *Stride; - - /// Users - Keep track of all of the users of this stride as well as the - /// initial value and the operand that uses the IV. - ilist<IVStrideUse> Users; - - void addUser(const SCEV *Offset, Instruction *User, Value *Operand) { - Users.push_back(new IVStrideUse(this, Offset, User, Operand)); - } - - void removeUser(IVStrideUse *User) { - Users.erase(User); - } - - void print(raw_ostream &OS) const; - - /// dump - This method is used for debugging. - void dump() const; -}; - class IVUsers : public LoopPass { - friend class IVStrideUserVH; + friend class IVStrideUse; Loop *L; LoopInfo *LI; DominatorTree *DT; @@ -182,19 +157,8 @@ class IVUsers : public LoopPass { /// IVUses - A list of all tracked IV uses of induction variable expressions /// we are interested in. - ilist<IVUsersOfOneStride> IVUses; - -public: - /// IVUsesByStride - A mapping from the strides in StrideOrder to the - /// uses in IVUses. - std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride; + ilist<IVStrideUse> IVUses; - /// StrideOrder - An ordering of the keys in IVUsesByStride that is stable: - /// We use this to iterate over the IVUsesByStride collection without being - /// dependent on random ordering of pointers in the process. - SmallVector<const SCEV *, 16> StrideOrder; - -private: virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnLoop(Loop *L, LPPassManager &LPM); @@ -210,8 +174,8 @@ public: /// return true. Otherwise, return false. bool AddUsersIfInteresting(Instruction *I); - void AddUser(const SCEV *Stride, const SCEV *Offset, - Instruction *User, Value *Operand); + IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset, + Instruction *User, Value *Operand); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. @@ -222,6 +186,14 @@ public: /// isUseOfPostIncrementedValue flag. const SCEV *getCanonicalExpr(const IVStrideUse &U) const; + typedef ilist<IVStrideUse>::iterator iterator; + typedef ilist<IVStrideUse>::const_iterator const_iterator; + iterator begin() { return IVUses.begin(); } + iterator end() { return IVUses.end(); } + const_iterator begin() const { return IVUses.begin(); } + const_iterator end() const { return IVUses.end(); } + bool empty() const { return IVUses.empty(); } + void print(raw_ostream &OS, const Module* = 0) const; /// dump - This method is used for debugging. diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index d5e4d51..f792a7f 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -835,7 +835,7 @@ public: } else if (BlockLoop != Child) { LoopT *SubLoop = BlockLoop; // Reparent all of the blocks which used to belong to BlockLoops - for (unsigned j = 0, e = SubLoop->Blocks.size(); j != e; ++j) + for (unsigned j = 0, f = SubLoop->Blocks.size(); j != f; ++j) ContainingLoops[SubLoop->Blocks[j]] = Child; // There is already a loop which contains this block, that means diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index f83cc4f..f6aab03 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -249,7 +249,7 @@ namespace llvm { SmallPtrSet<Instruction*, 4> > ReverseDepMapType; ReverseDepMapType ReverseLocalDeps; - // A reverse mapping form dependencies to the non-local dependees. + // A reverse mapping from dependencies to the non-local dependees. ReverseDepMapType ReverseNonLocalDeps; /// Current AA implementation, just a cache. @@ -312,6 +312,11 @@ namespace llvm { /// value and replaces the other value with ptr. This can make Ptr available /// in more places that cached info does not necessarily keep. void invalidateCachedPointerInfo(Value *Ptr); + + /// invalidateCachedPredecessors - Clear the PredIteratorCache info. + /// This needs to be done when the CFG changes, e.g., due to splitting + /// critical edges. + void invalidateCachedPredecessors(); private: MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize, diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index b612316..033efba 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -66,9 +66,11 @@ public: bool IsPotentiallyPHITranslatable() const; /// PHITranslateValue - PHI translate the current address up the CFG from - /// CurBB to Pred, updating our state the reflect any needed changes. This - /// returns true on failure and sets Addr to null. - bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); + /// CurBB to Pred, updating our state to reflect any needed changes. If the + /// dominator tree DT is non-null, the translated value must dominate + /// PredBB. This returns true on failure and sets Addr to null. + bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree *DT); /// PHITranslateWithInsertion - PHI translate this value into the specified /// predecessor block, inserting a computation of the value if it is @@ -88,14 +90,8 @@ public: /// returns false. bool Verify() const; private: - Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); - - - /// GetAvailablePHITranslatedSubExpr - Return the value computed by - /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedSubExpr(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const DominatorTree &DT) const; + Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree *DT); /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index 2f39c6a..1a5cbb2 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -81,13 +81,6 @@ namespace llvm { //===--------------------------------------------------------------------===// // - // createAndersensPass - This pass implements Andersen's interprocedural alias - // analysis. - // - ModulePass *createAndersensPass(); - - //===--------------------------------------------------------------------===// - // // createProfileLoaderPass - This pass loads information from a profile dump // file. // diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 3681cc0..5552017 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -69,6 +69,10 @@ struct PostDominatorTree : public FunctionPass { return DT->properlyDominates(A, B); } + inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) { + return DT->findNearestCommonDominator(A, B); + } + virtual void releaseMemory() { DT->releaseMemory(); } diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 383ee88..96d29ba 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // The ScalarEvolution class is an LLVM pass which can be used to analyze and -// catagorize scalar expressions in loops. It specializes in recognizing +// categorize scalar expressions in loops. It specializes in recognizing // general induction variables, representing them with the abstract and opaque // SCEV class. Given this analysis, trip counts of loops and other important // properties can be obtained. @@ -55,7 +55,7 @@ namespace llvm { protected: /// SubclassData - This field is initialized to zero and may be used in - /// subclasses to store miscelaneous information. + /// subclasses to store miscellaneous information. unsigned short SubclassData; private: @@ -177,7 +177,7 @@ namespace llvm { /// LoopInfo *LI; - /// TD - The target data information for the target we are targetting. + /// TD - The target data information for the target we are targeting. /// TargetData *TD; @@ -194,7 +194,7 @@ namespace llvm { std::map<SCEVCallbackVH, const SCEV *> Scalars; /// BackedgeTakenInfo - Information about the backedge-taken count - /// of a loop. This currently inclues an exact count and a maximum 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 @@ -305,7 +305,7 @@ namespace llvm { /// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition /// of 'icmp op load X, cst', try to see if we can compute the /// backedge-taken count. - const SCEV * + BackedgeTakenInfo ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS, const Loop *L, @@ -323,12 +323,12 @@ namespace llvm { /// HowFarToZero - Return the number of times a backedge comparing the /// specified value to zero will execute. If not computable, return /// CouldNotCompute. - const SCEV *HowFarToZero(const SCEV *V, const Loop *L); + BackedgeTakenInfo 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 /// CouldNotCompute. - const SCEV *HowFarToNonZero(const SCEV *V, const Loop *L); + BackedgeTakenInfo 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 @@ -353,14 +353,14 @@ namespace llvm { bool Inverse); /// isImpliedCondOperands - Test whether the condition described by Pred, - /// LHS, and RHS is true whenever the condition desribed by Pred, FoundLHS, + /// LHS, and RHS is true whenever the condition described by Pred, FoundLHS, /// and FoundRHS is true. bool isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const SCEV *FoundLHS, const SCEV *FoundRHS); /// isImpliedCondOperandsHelper - Test whether the condition described by - /// Pred, LHS, and RHS is true whenever the condition desribed by Pred, + /// Pred, LHS, and RHS is true whenever the condition described by Pred, /// FoundLHS, and FoundRHS is true. bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, @@ -586,6 +586,11 @@ namespace llvm { /// compute a trip count, or if the loop is deleted. void forgetLoop(const Loop *L); + /// forgetValue - This method should be called by the client when it has + /// changed a value in a way that may effect its value, or which may + /// disconnect it from a def-use chain linking it to a loop. + void forgetValue(Value *V); + /// GetMinTrailingZeros - Determine the minimum number of zero bits that S /// is guaranteed to end in (at every loop iteration). It is, at the same /// time, the minimum number of times S is divisible by 2. For example, diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 796b168..26dc0c4 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -27,10 +27,7 @@ namespace llvm { /// and destroy it when finished to allow the release of the associated /// memory. class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { - public: ScalarEvolution &SE; - - private: std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > InsertedExpressions; std::set<Value*> InsertedValues; @@ -57,11 +54,11 @@ namespace llvm { /// in a more literal form. bool CanonicalMode; - protected: typedef IRBuilder<true, TargetFolder> BuilderType; BuilderType Builder; friend struct SCEVVisitor<SCEVExpander, Value*>; + public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. explicit SCEVExpander(ScalarEvolution &se) @@ -171,9 +168,9 @@ namespace llvm { return S->getValue(); } - void rememberInstruction(Value *I) { - if (!PostIncLoop) InsertedValues.insert(I); - } + void rememberInstruction(Value *I); + + void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I); Value *expandAddRecExprLiterally(const SCEVAddRecExpr *); PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 3645a5b..0ab3b3f 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -417,6 +417,10 @@ namespace llvm { virtual bool isLoopInvariant(const Loop *QueryLoop) const; + bool dominates(BasicBlock *BB, DominatorTree *DT) const; + + bool properlyDominates(BasicBlock *BB, DominatorTree *DT) const; + /// isAffine - Return true if this is an affine AddRec (i.e., it represents /// an expressions A+B*x where A and B are loop invariant values. bool isAffine() const { diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 7c673c3..0791b7b 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -124,6 +124,10 @@ namespace llvm { /// character is included in the result string. bool GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0, bool StopAtNul = true); + + /// GetStringLength - If we can compute the length of the string pointed to by + /// the specified pointer, return 'len+1'. If we can't, return 0. + uint64_t GetStringLength(Value *V); } // end namespace llvm #endif diff --git a/include/llvm/Assembly/AsmAnnotationWriter.h b/include/llvm/Assembly/AsmAnnotationWriter.h index 6c3ddaf..6d75720 100644 --- a/include/llvm/Assembly/AsmAnnotationWriter.h +++ b/include/llvm/Assembly/AsmAnnotationWriter.h @@ -23,29 +23,34 @@ class Function; class BasicBlock; class Instruction; class raw_ostream; +class formatted_raw_ostream; class AssemblyAnnotationWriter { public: virtual ~AssemblyAnnotationWriter(); - // emitFunctionAnnot - This may be implemented to emit a string right before - // the start of a function. + /// emitFunctionAnnot - This may be implemented to emit a string right before + /// the start of a function. virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {} - // emitBasicBlockStartAnnot - This may be implemented to emit a string right - // after the basic block label, but before the first instruction in the block. + /// emitBasicBlockStartAnnot - This may be implemented to emit a string right + /// after the basic block label, but before the first instruction in the block. virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){ } - // emitBasicBlockEndAnnot - This may be implemented to emit a string right - // after the basic block. + /// emitBasicBlockEndAnnot - This may be implemented to emit a string right + /// after the basic block. virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){ } - // emitInstructionAnnot - This may be implemented to emit a string right - // before an instruction is emitted. + /// emitInstructionAnnot - This may be implemented to emit a string right + /// before an instruction is emitted. virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {} + + /// printInfoComment - This may be implemented to emit a comment to the + /// right of an instruction or global value. + virtual void printInfoComment(const Value &V, formatted_raw_ostream &OS) {} }; } // End llvm namespace diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 068f81f..1296d67 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -60,6 +60,11 @@ const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point const Attributes Naked = 1<<24; ///< Naked function const Attributes InlineHint = 1<<25; ///< source said inlining was ///desirable +const Attributes StackAlignment = 7<<26; ///< Alignment of stack for + ///function (3 bits) stored as log2 + ///of alignment with +1 bias + ///0 means unaligned (different from + ///alignstack(1)) /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -68,7 +73,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// be used on return values or function parameters. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone | NoImplicitFloat | Naked | InlineHint; + NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; @@ -105,6 +110,28 @@ inline unsigned getAlignmentFromAttrs(Attributes A) { return 1U << ((Align >> 16) - 1); } +/// This turns an int stack alignment (which must be a power of 2) into +/// the form used internally in Attributes. +inline Attributes constructStackAlignmentFromInt(unsigned i) { + // Default alignment, allow the target to define how to align it. + if (i == 0) + return 0; + + assert(isPowerOf2_32(i) && "Alignment must be a power of two."); + assert(i <= 0x100 && "Alignment too large."); + return (Log2_32(i)+1) << 26; +} + +/// This returns the stack alignment field of an attribute as a byte alignment +/// value. +inline unsigned getStackAlignmentFromAttrs(Attributes A) { + Attributes StackAlign = A & Attribute::StackAlignment; + if (StackAlign == 0) + return 0; + + return 1U << ((StackAlign >> 26) - 1); +} + /// The set of Attributes set in Attributes is converted to a /// string of equivalent mnemonics. This is, presumably, for writing out diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 9bb50d4..a980df8 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -94,7 +94,8 @@ namespace bitc { TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) - TYPE_CODE_METADATA = 16 // METADATA + TYPE_CODE_METADATA = 16, // METADATA + TYPE_CODE_UNION = 17 // UNION: [eltty x N] }; // The type symbol table only has one code (TST_ENTRY_CODE). diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 3c4dcb5..8ade1bd 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -223,7 +223,7 @@ namespace llvm { void EmitFunctionBody(); /// EmitInstruction - Targets should implement this to emit instructions. - virtual void EmitInstruction(const MachineInstr *MI) { + virtual void EmitInstruction(const MachineInstr *) { assert(0 && "EmitInstruction not implemented"); } @@ -308,7 +308,7 @@ namespace llvm { /// GetGlobalValueSymbol - Return the MCSymbol for the specified global /// value. - MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; + virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const; /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with /// global value name as its base, with the specified suffix, and where the @@ -356,6 +356,11 @@ namespace llvm { /// printOffset - This is just convenient handler for printing offsets. void printOffset(int64_t Offset) const; + /// isBlockOnlyReachableByFallthough - Return true if the basic block has + /// exactly one predecessor and the control transfer mechanism between + /// the predecessor and this block is a fall-through. + virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; + private: /// processDebugLoc - Processes the debug information of each machine diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h deleted file mode 100644 index 4d50879..0000000 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ /dev/null @@ -1,135 +0,0 @@ -//==-llvm/CodeGen/DAGISelHeader.h - Common DAG ISel definitions -*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides definitions of the common, target-independent methods and -// data, which is used by SelectionDAG-based instruction selectors. -// -// *** NOTE: This file is #included into the middle of the target -// instruction selector class. These functions are really methods. -// This is a little awkward, but it allows this code to be shared -// by all the targets while still being able to call into -// target-specific code without using a virtual function call. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_DAGISEL_HEADER_H -#define LLVM_CODEGEN_DAGISEL_HEADER_H - -/// ISelPosition - Node iterator marking the current position of -/// instruction selection as it procedes through the topologically-sorted -/// node list. -SelectionDAG::allnodes_iterator ISelPosition; - -/// IsChainCompatible - Returns true if Chain is Op or Chain does -/// not reach Op. -static bool IsChainCompatible(SDNode *Chain, SDNode *Op) { - if (Chain->getOpcode() == ISD::EntryToken) - return true; - if (Chain->getOpcode() == ISD::TokenFactor) - return false; - if (Chain->getNumOperands() > 0) { - SDValue C0 = Chain->getOperand(0); - if (C0.getValueType() == MVT::Other) - return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op); - } - return true; -} - -/// ISelUpdater - helper class to handle updates of the -/// instruciton selection graph. -class VISIBILITY_HIDDEN ISelUpdater : public SelectionDAG::DAGUpdateListener { - SelectionDAG::allnodes_iterator &ISelPosition; -public: - explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp) - : ISelPosition(isp) {} - - /// NodeDeleted - Handle nodes deleted from the graph. If the - /// node being deleted is the current ISelPosition node, update - /// ISelPosition. - /// - virtual void NodeDeleted(SDNode *N, SDNode *E) { - if (ISelPosition == SelectionDAG::allnodes_iterator(N)) - ++ISelPosition; - } - - /// NodeUpdated - Ignore updates for now. - virtual void NodeUpdated(SDNode *N) {} -}; - -/// ReplaceUses - replace all uses of the old node F with the use -/// of the new node T. -DISABLE_INLINE void ReplaceUses(SDValue F, SDValue T) { - ISelUpdater ISU(ISelPosition); - CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU); -} - -/// ReplaceUses - replace all uses of the old nodes F with the use -/// of the new nodes T. -DISABLE_INLINE void ReplaceUses(const SDValue *F, const SDValue *T, - unsigned Num) { - ISelUpdater ISU(ISelPosition); - CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU); -} - -/// ReplaceUses - replace all uses of the old node F with the use -/// of the new node T. -DISABLE_INLINE void ReplaceUses(SDNode *F, SDNode *T) { - ISelUpdater ISU(ISelPosition); - CurDAG->ReplaceAllUsesWith(F, T, &ISU); -} - -/// SelectRoot - Top level entry to DAG instruction selector. -/// Selects instructions starting at the root of the current DAG. -void SelectRoot(SelectionDAG &DAG) { - SelectRootInit(); - - // Create a dummy node (which is not added to allnodes), that adds - // a reference to the root node, preventing it from being deleted, - // and tracking any changes of the root. - HandleSDNode Dummy(CurDAG->getRoot()); - ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode())); - - // The AllNodes list is now topological-sorted. Visit the - // nodes by starting at the end of the list (the root of the - // graph) and preceding back toward the beginning (the entry - // node). - while (ISelPosition != CurDAG->allnodes_begin()) { - SDNode *Node = --ISelPosition; - // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes, - // but there are currently some corner cases that it misses. Also, this - // makes it theoretically possible to disable the DAGCombiner. - if (Node->use_empty()) - continue; -#if 0 - DAG.setSubgraphColor(Node, "red"); -#endif - SDNode *ResNode = Select(Node); - // If node should not be replaced, continue with the next one. - if (ResNode == Node) - continue; - // Replace node. - if (ResNode) { -#if 0 - DAG.setSubgraphColor(ResNode, "yellow"); - DAG.setSubgraphColor(ResNode, "black"); -#endif - ReplaceUses(Node, ResNode); - } - // If after the replacement this node is not used any more, - // remove this dead node. - if (Node->use_empty()) { // Don't delete EntryToken, etc. - ISelUpdater ISU(ISelPosition); - CurDAG->RemoveDeadNode(Node, &ISU); - } - } - - CurDAG->setRoot(Dummy.getValue()); -} - -#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */ diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index 525ce47..0a1d4f4 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -146,7 +146,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 3d6c9bc..eb5901c 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -320,7 +320,7 @@ namespace llvm { /// advanceTo - Advance the specified iterator to point to the LiveRange /// containing the specified position, or end() if the position is past the /// end of the interval. If no LiveRange contains this position, but the - /// position is in a hole, this method returns an iterator pointing the + /// position is in a hole, this method returns an iterator pointing to the /// LiveRange immediately after the hole. iterator advanceTo(iterator I, SlotIndex Pos) { if (Pos >= endIndex()) @@ -569,6 +569,16 @@ namespace llvm { /// unsigned getSize() const; + /// isSpillable - Can this interval be spilled? + bool isSpillable() const { + return weight != HUGE_VALF; + } + + /// markNotSpillable - Mark interval as not spillable + void markNotSpillable() { + weight = HUGE_VALF; + } + /// ComputeJoinedWeight - Set the weight of a live interval after /// Other has been merged into it. void ComputeJoinedWeight(const LiveInterval &Other); diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index d7ff8da..e8856ac 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -70,8 +70,15 @@ namespace llvm { static char ID; // Pass identification, replacement for typeid LiveIntervals() : MachineFunctionPass(&ID) {} - static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) { - return (isDef + isUse) * powf(10.0F, (float)loopDepth); + // Calculate the spill weight to assign to a single instruction. + static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth); + + // After summing the spill weights of all defs and uses, the final weight + // should be normalized, dividing the weight of the interval by its size. + // This encourages spilling of intervals that are large and have few uses, + // and discourages spilling of small intervals with many uses. + void normalizeSpillWeight(LiveInterval &li) { + li.weight /= getApproximateInstructionCount(li) + 25; } typedef Reg2IntervalMap::iterator iterator; @@ -409,6 +416,9 @@ namespace llvm { DenseMap<unsigned,unsigned> &MBBVRegsMap, std::vector<LiveInterval*> &NewLIs); + // Normalize the spill weight of all the intervals in NewLIs. + void normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs); + static LiveInterval* createInterval(unsigned Reg); void printInstrs(raw_ostream &O) const; diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index a7bf600..fc5ea6f 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -124,6 +124,11 @@ private: /// std::vector<VarInfo> VirtRegInfo; + /// PHIJoins - list of virtual registers that are PHI joins. These registers + /// may have multiple definitions, and they require special handling when + /// building live intervals. + SparseBitVector<> PHIJoins; + /// ReservedRegisters - This vector keeps track of which registers /// are reserved register which are not allocatable by the target machine. /// We can not track liveness for values that are in this set. @@ -295,6 +300,12 @@ public: void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB, MachineBasicBlock *SuccBB); + + /// isPHIJoin - Return true if Reg is a phi join register. + bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); } + + /// setPHIJoin - Mark Reg as a phi join register. + void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); } }; } // End llvm namespace diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index db82ba5..d92650b 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -285,11 +285,6 @@ public: /// it returns end() iterator getFirstTerminator(); - /// isOnlyReachableViaFallthough - Return true if this basic block has - /// exactly one predecessor and the control transfer mechanism between - /// the predecessor and this block is a fall-through. - bool isOnlyReachableByFallthrough() const; - void pop_front() { Insts.pop_front(); } void pop_back() { Insts.pop_back(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 115aecc..48b4082 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -155,7 +155,7 @@ public: } } - /// emitAlignment - Move the CurBufferPtr pointer up the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 968e4ea..043e97f 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -276,6 +276,7 @@ public: assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && "Invalid Object Idx!"); Objects[ObjectIdx+NumFixedObjects].Alignment = Align; + MaxAlignment = std::max(MaxAlignment, Align); } /// getObjectOffset - Return the assigned stack offset of the specified object @@ -328,19 +329,6 @@ public: /// void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } - /// calculateMaxStackAlignment() - If there is a local object which requires - /// greater alignment than the current max alignment, adjust accordingly. - void calculateMaxStackAlignment() { - for (int i = getObjectIndexBegin(), - e = getObjectIndexEnd(); i != e; ++i) { - if (isDeadObjectIndex(i)) - continue; - - unsigned Align = getObjectAlignment(i); - MaxAlignment = std::max(MaxAlignment, Align); - } - } - /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// @@ -402,6 +390,7 @@ public: Objects.push_back(StackObject(Size, Alignment, 0, false, isSS)); int Index = (int)Objects.size()-NumFixedObjects-1; assert(Index >= 0 && "Bad frame index!"); + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } @@ -412,6 +401,7 @@ public: int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { CreateStackObject(Size, Alignment, true); int Index = (int)Objects.size()-NumFixedObjects-1; + MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 6e33fb3..d84f882 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -179,17 +179,16 @@ public: return MemRefsEnd - MemRefs == 1; } + enum MICheckType { + CheckDefs, // Check all operands for equality + IgnoreDefs, // Ignore all definitions + IgnoreVRegDefs // Ignore virtual register definitions + }; + /// isIdenticalTo - Return true if this instruction is identical to (same /// opcode and same operands as) the specified instruction. - bool isIdenticalTo(const MachineInstr *Other) const { - if (Other->getOpcode() != getOpcode() || - Other->getNumOperands() != getNumOperands()) - return false; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (!getOperand(i).isIdenticalTo(Other->getOperand(i))) - return false; - return true; - } + bool isIdenticalTo(const MachineInstr *Other, + MICheckType Check = CheckDefs) const; /// removeFromParent - This method unlinks 'this' from the containing basic /// block, and returns it, but does not delete it. @@ -331,13 +330,13 @@ public: /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. - bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore, - AliasAnalysis *AA) const; + bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, + bool &SawStore) const; /// isSafeToReMat - Return true if it's safe to rematerialize the specified /// instruction which defined the specified register instead of copying it. - bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg, - AliasAnalysis *AA) const; + bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA, + unsigned DstReg) const; /// hasVolatileMemoryRef - Return true if this instruction may have a /// volatile memory reference, or if the information describing the @@ -420,6 +419,30 @@ private: void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo); }; +/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare +/// MachineInstr* by *value* of the instruction rather than by pointer value. +/// The hashing and equality testing functions ignore definitions so this is +/// useful for CSE, etc. +struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> { + static inline MachineInstr *getEmptyKey() { + return 0; + } + + static inline MachineInstr *getTombstoneKey() { + return reinterpret_cast<MachineInstr*>(-1); + } + + static unsigned getHashValue(const MachineInstr* const &MI); + + static bool isEqual(const MachineInstr* const &LHS, + const MachineInstr* const &RHS) { + if (RHS == getEmptyKey() || RHS == getTombstoneKey() || + LHS == getEmptyKey() || LHS == getTombstoneKey()) + return LHS == RHS; + return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs); + } +}; + //===----------------------------------------------------------------------===// // Debugging Support diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index a263a97..47f7cf7 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -127,7 +127,7 @@ public: return *this; } - const MachineInstrBuilder &addMetadata(MDNode *MD) const { + const MachineInstrBuilder &addMetadata(const MDNode *MD) const { MI->addOperand(MachineOperand::CreateMetadata(MD)); return *this; } diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 5dee199..7272aa5 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -46,7 +46,11 @@ public: /// The memory access writes data. MOStore = 2, /// The memory access is volatile. - MOVolatile = 4 + MOVolatile = 4, + /// The memory access is non-temporal. + MONonTemporal = 8, + // This is the number of bits we need to represent flags. + MOMaxBits = 4 }; /// MachineMemOperand - Construct an MachineMemOperand object with the @@ -64,7 +68,7 @@ public: const Value *getValue() const { return V; } /// getFlags - Return the raw flags of the source value, \see MemOperandFlags. - unsigned int getFlags() const { return Flags & 7; } + unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } /// getOffset - For normal values, this is a byte offset added to the base /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex @@ -80,11 +84,12 @@ public: /// getBaseAlignment - Return the minimum known alignment in bytes of the /// base address, without the offset. - uint64_t getBaseAlignment() const { return (1u << (Flags >> 3)) >> 1; } + uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; } bool isLoad() const { return Flags & MOLoad; } bool isStore() const { return Flags & MOStore; } bool isVolatile() const { return Flags & MOVolatile; } + bool isNonTemporal() const { return Flags & MONonTemporal; } /// refineAlignment - Update this MachineMemOperand to reflect the alignment /// of MMO, if it has a greater alignment. This must only be used when the diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 556ba7f..8eeac9f 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -50,6 +50,7 @@ namespace llvm { //===----------------------------------------------------------------------===// // Forward declarations. class Constant; +class MCSymbol; class MDNode; class GlobalVariable; class MachineBasicBlock; @@ -66,6 +67,12 @@ class StructType; class MachineModuleInfoImpl { public: virtual ~MachineModuleInfoImpl(); + + typedef std::vector<std::pair<MCSymbol*, MCSymbol*> > + SymbolListTy; +protected: + static SymbolListTy + GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map); }; diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index 6679990..89b8207 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -19,7 +19,7 @@ namespace llvm { class MCSymbol; - + /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation /// for MachO targets. class MachineModuleInfoMachO : public MachineModuleInfoImpl { @@ -54,10 +54,8 @@ namespace llvm { assert(Sym && "Key cannot be null"); return HiddenGVStubs[Sym]; } - + /// Accessor methods to return the set of stubs in sorted order. - typedef std::vector<std::pair<MCSymbol*, MCSymbol*> > SymbolListTy; - SymbolListTy GetFnStubList() const { return GetSortedStubs(FnStubs); } @@ -67,12 +65,31 @@ namespace llvm { SymbolListTy GetHiddenGVStubList() const { return GetSortedStubs(HiddenGVStubs); } - - private: - static SymbolListTy - GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map); }; - + + /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation + /// for ELF targets. + class MachineModuleInfoELF : public MachineModuleInfoImpl { + /// GVStubs - These stubs are used to materialize global addresses in PIC + /// mode. + DenseMap<MCSymbol*, MCSymbol*> GVStubs; + + virtual void Anchor(); // Out of line virtual method. + public: + MachineModuleInfoELF(const MachineModuleInfo &) {} + + MCSymbol *&getGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return GVStubs[Sym]; + } + + /// Accessor methods to return the set of stubs in sorted order. + + SymbolListTy GetGVStubList() const { + return GetSortedStubs(GVStubs); + } + }; + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 0bb6d7d..0978057 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -19,14 +19,14 @@ namespace llvm { -class ConstantFP; class BlockAddress; -class MachineBasicBlock; +class ConstantFP; class GlobalValue; +class MachineBasicBlock; class MachineInstr; -class TargetMachine; class MachineRegisterInfo; class MDNode; +class TargetMachine; class raw_ostream; /// MachineOperand class - Representation of each machine instruction operand. @@ -100,7 +100,7 @@ private: MachineBasicBlock *MBB; // For MO_MachineBasicBlock. const ConstantFP *CFP; // For MO_FPImmediate. int64_t ImmVal; // For MO_Immediate. - MDNode *MD; // For MO_Metadata. + const MDNode *MD; // For MO_Metadata. struct { // For MO_Register. unsigned RegNo; @@ -220,7 +220,6 @@ public: bool isDebug() const { assert(isReg() && "Wrong MachineOperand accessor"); - assert(!isDef() && "Wrong MachineOperand accessor"); return IsDebug; } @@ -468,7 +467,7 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateMetadata(MDNode *Meta) { + static MachineOperand CreateMetadata(const MDNode *Meta) { MachineOperand Op(MachineOperand::MO_Metadata); Op.Contents.MD = Meta; return Op; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 01dc018..f2e5e10 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -115,6 +115,10 @@ public: /// register. bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); } + /// hasOneUse - Return true if there is exactly one instruction using the + /// specified register. + bool hasOneUse(unsigned RegNo) const; + /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the /// specified register, skipping those marked as Debug. typedef defusechain_iterator<true,false,true> use_nodbg_iterator; @@ -129,6 +133,10 @@ public: return use_nodbg_begin(RegNo) == use_nodbg_end(); } + /// hasOneNonDBGUse - Return true if there is exactly one non-Debug + /// instruction using the specified register. + bool hasOneNonDBGUse(unsigned RegNo) const; + /// replaceRegWith - Replace all instances of FromReg with ToReg in the /// machine function. This is like llvm-level X->replaceAllUsesWith(Y), /// except that it also changes any definitions of the register as well. diff --git a/include/llvm/CodeGen/ObjectCodeEmitter.h b/include/llvm/CodeGen/ObjectCodeEmitter.h index 3caa747..170c0c8 100644 --- a/include/llvm/CodeGen/ObjectCodeEmitter.h +++ b/include/llvm/CodeGen/ObjectCodeEmitter.h @@ -81,7 +81,7 @@ public: /// written to the data stream in big-endian format. void emitDWordBE(uint64_t W); - /// emitAlignment - Move the CurBufferPtr pointer up the specified + /// emitAlignment - Move the CurBufferPtr pointer up to the specified /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment = 0, uint8_t fill = 0); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7e0da3f..911be22 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -162,6 +162,10 @@ namespace llvm { /// FunctionPass *createGCInfoPrinter(raw_ostream &OS); + /// createMachineCSEPass - This pass performs global CSE on machine + /// instructions. + FunctionPass *createMachineCSEPass(); + /// createMachineLICMPass - This pass performs LICM on machine instructions. /// FunctionPass *createMachineLICMPass(); @@ -174,6 +178,10 @@ namespace llvm { /// optimization by increasing uses of extended values. FunctionPass *createOptimizeExtsPass(); + /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs + /// to take advantage of opportunities created during DAG legalization. + FunctionPass *createOptimizePHIsPass(); + /// createStackSlotColoringPass - This pass performs stack slot coloring. FunctionPass *createStackSlotColoringPass(bool); @@ -183,7 +191,7 @@ namespace llvm { /// createMachineVerifierPass - This pass verifies cenerated machine code /// instructions for correctness. /// - /// @param allowPhysDoubleDefs ignore double definitions of + /// @param allowDoubleDefs ignore double definitions of /// registers. Useful before LiveVariables has run. FunctionPass *createMachineVerifierPass(bool allowDoubleDefs); diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 60014f8..ad01e89 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -581,18 +581,18 @@ public: /// determined by their operands, and they produce a value AND a token chain. /// SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, - SDValue Chain, SDValue Ptr, const Value *SV, - int SVOffset, EVT MemVT, bool isVolatile=false, - unsigned Alignment=0); + SDValue Chain, SDValue Ptr, const Value *SV, + int SVOffset, EVT MemVT, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, const Value *SV, int SVOffset, EVT MemVT, - bool isVolatile=false, unsigned Alignment=0); + bool isVolatile, bool isNonTemporal, unsigned Alignment); SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, EVT MemVT, MachineMemOperand *MMO); @@ -600,13 +600,14 @@ public: /// getStore - Helper function to build ISD::STORE nodes. /// SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, bool isVolatile=false, - unsigned Alignment=0); + const Value *SV, int SVOffset, bool isVolatile, + bool isNonTemporal, unsigned Alignment); SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, MachineMemOperand *MMO); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, - const Value *SV, int SVOffset, EVT TVT, - bool isVolatile=false, unsigned Alignment=0); + const Value *SV, int SVOffset, EVT TVT, + bool isNonTemporal, bool isVolatile, + unsigned Alignment); SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr, EVT TVT, MachineMemOperand *MMO); SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base, @@ -667,27 +668,8 @@ public: SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps); - /// MorphNodeTo - These *mutate* the specified node to have the specified + /// MorphNodeTo - This *mutates* the specified node to have the specified /// return type, opcode, and operands. - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, SDValue Op1); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, - SDValue Op1, SDValue Op2); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, - SDValue Op1, SDValue Op2, SDValue Op3); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, - const SDValue *Ops, unsigned NumOps); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, EVT VT2); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, - EVT VT2, const SDValue *Ops, unsigned NumOps); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, - EVT VT2, EVT VT3, const SDValue *Ops, unsigned NumOps); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, - EVT VT2, SDValue Op1); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, - EVT VT2, SDValue Op1, SDValue Op2); - SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, - EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps); @@ -897,6 +879,15 @@ public: /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN. bool isKnownNeverNaN(SDValue Op) const; + /// isKnownNeverZero - Test whether the given SDValue is known to never be + /// positive or negative Zero. + bool isKnownNeverZero(SDValue Op) const; + + /// isEqualTo - Test whether two SDValues are known to compare equal. This + /// is true if they are the same value, or if one is negative zero and the + /// other positive zero. + bool isEqualTo(SDValue A, SDValue B) const; + /// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has /// been verified as a debug information descriptor. bool isVerifiedDebugInfoDesc(SDValue Op) const; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index b33b21d..d9c1374 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -68,12 +68,18 @@ public: unsigned MakeReg(EVT VT); virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {} - virtual void InstructionSelect() = 0; - void SelectRootInit() { - DAGSize = CurDAG->AssignTopologicalOrder(); - } - + /// PreprocessISelDAG - This hook allows targets to hack on the graph before + /// instruction selection starts. + virtual void PreprocessISelDAG() {} + + /// PostprocessISelDAG() - This hook allows the target to hack on the graph + /// right after selection. + virtual void PostprocessISelDAG() {} + + /// Select - Main hook targets implement to select a node. + virtual SDNode *Select(SDNode *N) = 0; + /// SelectInlineAsmMemoryOperand - Select the specified address as a target /// addressing mode, according to the specified constraint code. If this does /// not match or is not implemented, return true. The resultant operands @@ -85,39 +91,197 @@ public: return true; } - /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of - /// U can be folded during instruction selection that starts at Root and - /// folding N is profitable. - virtual - bool IsLegalAndProfitableToFold(SDNode *N, SDNode *U, SDNode *Root) const; + /// IsProfitableToFold - Returns true if it's profitable to fold the specific + /// operand node N of U during instruction selection that starts at Root. + virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const; + + /// IsLegalToFold - Returns true if the specific operand node N of + /// U can be folded during instruction selection that starts at Root. + bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, + bool IgnoreChains = false) const; /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer /// to use for this target when scheduling the DAG. virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer(); + + // Opcodes used by the DAG state machine: + enum BuiltinOpcodes { + OPC_Scope, + OPC_RecordNode, + OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3, + OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7, + OPC_RecordMemRef, + OPC_CaptureFlagInput, + OPC_MoveChild, + OPC_MoveParent, + OPC_CheckSame, + OPC_CheckPatternPredicate, + OPC_CheckPredicate, + OPC_CheckOpcode, + OPC_SwitchOpcode, + OPC_CheckType, + OPC_SwitchType, + OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type, + OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type, + OPC_CheckChild6Type, OPC_CheckChild7Type, + OPC_CheckInteger, + OPC_CheckCondCode, + OPC_CheckValueType, + OPC_CheckComplexPat, + OPC_CheckAndImm, OPC_CheckOrImm, + OPC_CheckFoldableChainNode, + + OPC_EmitInteger, + OPC_EmitRegister, + OPC_EmitConvertToTarget, + OPC_EmitMergeInputChains, + OPC_EmitCopyToReg, + OPC_EmitNodeXForm, + OPC_EmitNode, + OPC_MorphNodeTo, + OPC_MarkFlagResults, + OPC_CompleteMatch + }; + + enum { + OPFL_None = 0, // Node has no chain or flag input and isn't variadic. + OPFL_Chain = 1, // Node has a chain input. + OPFL_FlagInput = 2, // Node has a flag input. + OPFL_FlagOutput = 4, // Node has a flag output. + OPFL_MemRefs = 8, // Node gets accumulated MemRefs. + OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs. + OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs. + OPFL_Variadic2 = 3<<4, // Node is variadic, root has 2 fixed inputs. + OPFL_Variadic3 = 4<<4, // Node is variadic, root has 3 fixed inputs. + OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs. + OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs. + OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs. + + OPFL_VariadicInfo = OPFL_Variadic6 + }; + + /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the + /// number of fixed arity values that should be skipped when copying from the + /// root. + static inline int getNumFixedFromVariadicInfo(unsigned Flags) { + return ((Flags&OPFL_VariadicInfo) >> 4)-1; + } + + protected: /// DAGSize - Size of DAG being instruction selected. /// unsigned DAGSize; + + /// ISelPosition - Node iterator marking the current position of + /// instruction selection as it procedes through the topologically-sorted + /// node list. + SelectionDAG::allnodes_iterator ISelPosition; + + + /// ISelUpdater - helper class to handle updates of the + /// instruction selection graph. + class ISelUpdater : public SelectionDAG::DAGUpdateListener { + SelectionDAG::allnodes_iterator &ISelPosition; + public: + explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp) + : ISelPosition(isp) {} + + /// NodeDeleted - Handle nodes deleted from the graph. If the + /// node being deleted is the current ISelPosition node, update + /// ISelPosition. + /// + virtual void NodeDeleted(SDNode *N, SDNode *E) { + if (ISelPosition == SelectionDAG::allnodes_iterator(N)) + ++ISelPosition; + } + + /// NodeUpdated - Ignore updates for now. + virtual void NodeUpdated(SDNode *N) {} + }; + + /// ReplaceUses - replace all uses of the old node F with the use + /// of the new node T. + void ReplaceUses(SDValue F, SDValue T) { + ISelUpdater ISU(ISelPosition); + CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU); + } + + /// ReplaceUses - replace all uses of the old nodes F with the use + /// of the new nodes T. + void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) { + ISelUpdater ISU(ISelPosition); + CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU); + } + + /// ReplaceUses - replace all uses of the old node F with the use + /// of the new node T. + void ReplaceUses(SDNode *F, SDNode *T) { + ISelUpdater ISU(ISelPosition); + CurDAG->ReplaceAllUsesWith(F, T, &ISU); + } + /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops); + +public: // Calls to these predicates are generated by tblgen. bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; + + /// CheckPatternPredicate - This function is generated by tblgen in the + /// target. It runs the specified pattern predicate and returns true if it + /// succeeds or false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckPatternPredicate(unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + + /// CheckNodePredicate - This function is generated by tblgen in the target. + /// It runs node predicate number PredNo and returns true if it succeeds or + /// false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + + virtual bool CheckComplexPattern(SDNode *Root, SDValue N, unsigned PatternNo, + SmallVectorImpl<SDValue> &Result) { + assert(0 && "Tblgen should generate the implementation of this!"); + return false; + } + + virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { + assert(0 && "Tblgen shoudl generate this!"); + return SDValue(); + } + + SDNode *SelectCodeCommon(SDNode *NodeToMatch, + const unsigned char *MatcherTable, + unsigned TableSize); + +private: + // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDNode *N); SDNode *Select_UNDEF(SDNode *N); SDNode *Select_EH_LABEL(SDNode *N); void CannotYetSelect(SDNode *N); - void CannotYetSelectIntrinsic(SDNode *N); private: + void DoInstructionSelection(); + SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, + const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); + void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, MachineModuleInfo *MMI, DwarfWriter *DW, @@ -143,6 +307,16 @@ private: /// one preferred by the target. /// ScheduleDAGSDNodes *CreateScheduler(); + + /// OpcodeOffset - This is a cache used to dispatch efficiently into isel + /// state machines that start with a OPC_SwitchOpcode node. + std::vector<unsigned> OpcodeOffset; + + void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain, + const SmallVectorImpl<SDNode*> &ChainNodesMatched, + SDValue InputFlag,const SmallVectorImpl<SDNode*> &F, + bool isMorphNodeTo); + }; } diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 45a9d40..21a0b98 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -609,7 +609,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = 1 << 14; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+80; /// Node predicates @@ -821,6 +821,8 @@ public: /// set the SDNode void setNode(SDNode *N) { Node = N; } + inline SDNode *operator->() const { return Node; } + bool operator==(const SDValue &O) const { return Node == O.Node && ResNo == O.ResNo; } @@ -1025,11 +1027,15 @@ private: /// then they will be delete[]'d when the node is destroyed. uint16_t OperandsNeedDelete : 1; + /// HasDebugValue - This tracks whether this node has one or more dbg_value + /// nodes corresponding to it. + uint16_t HasDebugValue : 1; + protected: /// SubclassData - This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. - uint16_t SubclassData : 15; + uint16_t SubclassData : 14; private: /// NodeId - Unique id per SDNode in the DAG. @@ -1092,6 +1098,12 @@ public: return ~NodeType; } + /// getHasDebugValue - get this bit. + bool getHasDebugValue() const { return HasDebugValue; } + + /// setHasDebugValue - set this bit. + void setHasDebugValue(bool b) { HasDebugValue = b; } + /// use_empty - Return true if there are no uses of this node. /// bool use_empty() const { return UseList == NULL; } @@ -1355,8 +1367,8 @@ protected: SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps) - : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), + : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false), + SubclassData(0), NodeId(-1), OperandList(NumOps ? new SDUse[NumOps] : 0), ValueList(VTs.VTs), UseList(NULL), NumOperands(NumOps), NumValues(VTs.NumVTs), @@ -1593,7 +1605,10 @@ public: return SubclassData; } + // We access subclass data here so that we can check consistency + // with MachineMemOperand information. bool isVolatile() const { return (SubclassData >> 5) & 1; } + bool isNonTemporal() const { return (SubclassData >> 6) & 1; } /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return MMO->getValue(); } @@ -1759,7 +1774,12 @@ public: bool isSplat() const { return isSplatMask(Mask, getValueType(0)); } int getSplatIndex() const { assert(isSplat() && "Cannot get splat index for non-splat!"); - return Mask[0]; + EVT VT = getValueType(0); + for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) { + if (Mask[i] != -1) + return Mask[i]; + } + return -1; } static bool isSplatMask(const int *Mask, EVT VT); @@ -1805,6 +1825,12 @@ public: const APFloat& getValueAPF() const { return Value->getValueAPF(); } const ConstantFP *getConstantFPValue() const { return Value; } + /// isZero - Return true if the value is positive or negative zero. + bool isZero() const { return Value->isZero(); } + + /// isNaN - Return true if the value is a NaN. + bool isNaN() const { return Value->isNaN(); } + /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h new file mode 100644 index 0000000..3d99fa7 --- /dev/null +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -0,0 +1,207 @@ +//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object 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 classes used to handle lowerings specific to common +// object file formats. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H +#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Target/TargetLoweringObjectFile.h" + +namespace llvm { + class MachineModuleInfo; + class Mangler; + class MCAsmInfo; + class MCExpr; + class MCSection; + class MCSectionMachO; + class MCSymbol; + class MCContext; + class GlobalValue; + class TargetMachine; + + +class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +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; + +protected: + const MCSection *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind, + bool IsExplicit = false) const; +public: + TargetLoweringObjectFileELF() : UniquingMap(0) {} + ~TargetLoweringObjectFileELF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + 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; + + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference + /// to the specified global variable from exception handling information. + /// + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; +}; + + + +class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { + mutable void *UniquingMap; + + const MCSection *CStringSection; + const MCSection *UStringSection; + const MCSection *TextCoalSection; + const MCSection *ConstTextCoalSection; + const MCSection *ConstDataCoalSection; + 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() : UniquingMap(0) {} + ~TargetLoweringObjectFileMachO(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; + + /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively + /// decide not to emit the UsedDirective for some symbols in llvm.used. + /// FIXME: REMOVE this (rdar://7071300) + virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, + Mangler *) const; + + /// getMachOSection - Return the MCSection for the specified mach-o section. + /// This requires the operands to be valid. + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + SectionKind K) const { + return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); + } + const MCSectionMachO *getMachOSection(StringRef Segment, + StringRef Section, + unsigned TypeAndAttributes, + unsigned Reserved2, + SectionKind K) 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; + } + + /// getSymbolForDwarfGlobalReference - The mach-o version of this method + /// defaults to returning a stub reference. + virtual const MCExpr * + getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding) const; + + virtual unsigned getPersonalityEncoding() const; + virtual unsigned getLSDAEncoding() const; + virtual unsigned getFDEEncoding() const; + virtual unsigned getTTypeEncoding() const; +}; + + + +class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { + mutable void *UniquingMap; +public: + TargetLoweringObjectFileCOFF() : UniquingMap(0) {} + ~TargetLoweringObjectFileCOFF(); + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + /// getCOFFSection - Return the MCSection for the specified COFF section. + /// FIXME: Switch this to a semantic view eventually. + const MCSection *getCOFFSection(StringRef Name, bool isDirective, + SectionKind K) const; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 9c3e861..31a627d 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -20,9 +20,12 @@ class Tool<list<dag> l> { def in_language; def out_language; def output_suffix; -def cmd_line; +def command; +def out_file_option; +def in_file_option; def join; def sink; +def works_on_empty; def actions; // Possible option types. @@ -42,10 +45,12 @@ 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; @@ -81,6 +86,7 @@ def forward_as; def forward_value; def forward_transformed_value; def stop_compilation; +def no_out_file; def unpack_values; def warning; def error; diff --git a/include/llvm/CompilerDriver/Main.inc b/include/llvm/CompilerDriver/Main.inc index fc8b503..71bb8cb 100644 --- a/include/llvm/CompilerDriver/Main.inc +++ b/include/llvm/CompilerDriver/Main.inc @@ -10,7 +10,7 @@ // This tool provides a single point of access to the LLVM // compilation tools. It has many options. To discover the options // supported please refer to the tools' manual page or run the tool -// with the --help option. +// with the -help option. // // This file provides the default entry point for the driver executable. // diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h index a982e2d..85d1690 100644 --- a/include/llvm/CompilerDriver/Tool.h +++ b/include/llvm/CompilerDriver/Tool.h @@ -20,15 +20,19 @@ #include "llvm/ADT/StringSet.h" #include "llvm/System/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 - A class + /// Tool - Represents a single tool. class Tool : public llvm::RefCountedBaseVPTR<Tool> { public: @@ -51,6 +55,7 @@ namespace llvmc { virtual const char* OutputLanguage() const = 0; virtual bool IsJoin() const = 0; + virtual bool WorksOnEmpty() const = 0; protected: /// OutFileName - Generate the output file name. @@ -58,6 +63,8 @@ namespace llvmc { 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. diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index ff1be05..1cebb20 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -33,6 +33,7 @@ namespace llvm { class ArrayType; class IntegerType; class StructType; +class UnionType; class PointerType; class VectorType; @@ -275,6 +276,12 @@ public: return Val.isZero() && Val.isNegative(); } + /// isZero - Return true if the value is positive or negative zero. + bool isZero() const { return Val.isZero(); } + + /// isNaN - Return true if the value is a NaN. + bool isNaN() const { return Val.isNaN(); } + /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of @@ -453,6 +460,50 @@ struct OperandTraits<ConstantStruct> : public VariadicOperandTraits<> { DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant) //===----------------------------------------------------------------------===// +// ConstantUnion - Constant Union Declarations +// +class ConstantUnion : public Constant { + friend struct ConstantCreator<ConstantUnion, UnionType, Constant*>; + ConstantUnion(const ConstantUnion &); // DO NOT IMPLEMENT +protected: + ConstantUnion(const UnionType *T, Constant* Val); +public: + // ConstantUnion accessors + static Constant *get(const UnionType *T, Constant* V); + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + + /// getType() specialization - Reduce amount of casting... + /// + inline const UnionType *getType() const { + return reinterpret_cast<const UnionType*>(Value::getType()); + } + + /// isNullValue - Return true if this is the value that would be returned by + /// getNullValue. This always returns false because zero structs are always + /// created as ConstantAggregateZero objects. + virtual bool isNullValue() const { + return false; + } + + virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ConstantUnion *) { return true; } + static bool classof(const Value *V) { + return V->getValueID() == ConstantUnionVal; + } +}; + +template <> +struct OperandTraits<ConstantUnion> : public FixedNumOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantUnion, Constant) + +//===----------------------------------------------------------------------===// /// ConstantVector - Constant Vector Declarations /// class ConstantVector : public Constant { @@ -647,8 +698,9 @@ public: /// independent way (Note: the return type is an i64). static Constant *getAlignOf(const Type* Ty); - /// getSizeOf constant expr - computes the size of a type in a target - /// independent way (Note: the return type is an i64). + /// 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); diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index c220608..912bb6d 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -27,6 +27,7 @@ template<class ValType, class TypeClass> class TypeMap; class FunctionValType; class ArrayValType; class StructValType; +class UnionValType; class PointerValType; class VectorValType; class IntegerValType; @@ -229,7 +230,8 @@ public: return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || T->getTypeID() == PointerTyID || - T->getTypeID() == VectorTyID; + T->getTypeID() == VectorTyID || + T->getTypeID() == UnionTyID; } }; @@ -301,6 +303,63 @@ public: }; +/// UnionType - Class to represent union types. A union type is similar to +/// a structure, except that all member fields begin at offset 0. +/// +class UnionType : public CompositeType { + friend class TypeMap<UnionValType, UnionType>; + UnionType(const UnionType &); // Do not implement + const UnionType &operator=(const UnionType &); // Do not implement + UnionType(LLVMContext &C, const Type* const* Types, unsigned NumTypes); +public: + /// UnionType::get - This static method is the primary way to create a + /// UnionType. + static UnionType *get(const Type* const* Types, unsigned NumTypes); + + /// UnionType::get - This static method is a convenience method for + /// creating union types by specifying the elements as arguments. + static UnionType *get(const Type *type, ...) END_WITH_NULL; + + /// isValidElementType - Return true if the specified type is valid as a + /// element type. + static bool isValidElementType(const Type *ElemTy); + + /// Given an element type, return the member index of that type, or -1 + /// if there is no such member type. + int getElementTypeIndex(const Type *ElemTy) const; + + // Iterator access to the elements + typedef Type::subtype_iterator element_iterator; + element_iterator element_begin() const { return ContainedTys; } + element_iterator element_end() const { return &ContainedTys[NumContainedTys];} + + // Random access to the elements + unsigned getNumElements() const { return NumContainedTys; } + const Type *getElementType(unsigned N) const { + assert(N < NumContainedTys && "Element number out of range!"); + return ContainedTys[N]; + } + + /// getTypeAtIndex - Given an index value into the type, return the type of + /// the element. For a union type, this must be a constant value... + /// + virtual const Type *getTypeAtIndex(const Value *V) const; + virtual const Type *getTypeAtIndex(unsigned Idx) const; + virtual bool indexValid(const Value *V) const; + virtual bool indexValid(unsigned Idx) const; + + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UnionType *) { return true; } + static inline bool classof(const Type *T) { + return T->getTypeID() == UnionTyID; + } +}; + + /// SequentialType - This is the superclass of the array, pointer and vector /// type classes. All of these represent "arrays" in memory. The array type /// represents a specifically sized array, pointer types are unsized/unknown @@ -496,6 +555,7 @@ public: /// OpaqueType - Class to represent abstract types /// class OpaqueType : public DerivedType { + friend class LLVMContextImpl; OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT OpaqueType(LLVMContext &C); diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index c15b555..658967d 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -110,36 +110,51 @@ public: return ODR ? WeakODRLinkage : WeakAnyLinkage; } - bool hasExternalLinkage() const { return Linkage == ExternalLinkage; } - bool hasAvailableExternallyLinkage() const { + static bool isExternalLinkage(LinkageTypes Linkage) { + return Linkage == ExternalLinkage; + } + static bool isAvailableExternallyLinkage(LinkageTypes Linkage) { return Linkage == AvailableExternallyLinkage; } - bool hasLinkOnceLinkage() const { + static bool isLinkOnceLinkage(LinkageTypes Linkage) { return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; } - bool hasWeakLinkage() const { + static bool isWeakLinkage(LinkageTypes Linkage) { return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage; } - bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; } - bool hasInternalLinkage() const { return Linkage == InternalLinkage; } - bool hasPrivateLinkage() const { return Linkage == PrivateLinkage; } - bool hasLinkerPrivateLinkage() const { return Linkage==LinkerPrivateLinkage; } - bool hasLocalLinkage() const { - return hasInternalLinkage() || hasPrivateLinkage() || - hasLinkerPrivateLinkage(); + static bool isAppendingLinkage(LinkageTypes Linkage) { + return Linkage == AppendingLinkage; + } + static bool isInternalLinkage(LinkageTypes Linkage) { + return Linkage == InternalLinkage; + } + static bool isPrivateLinkage(LinkageTypes Linkage) { + return Linkage == PrivateLinkage; + } + static bool isLinkerPrivateLinkage(LinkageTypes Linkage) { + return Linkage==LinkerPrivateLinkage; + } + static bool isLocalLinkage(LinkageTypes Linkage) { + return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) || + isLinkerPrivateLinkage(Linkage); + } + static bool isDLLImportLinkage(LinkageTypes Linkage) { + return Linkage == DLLImportLinkage; + } + static bool isDLLExportLinkage(LinkageTypes Linkage) { + return Linkage == DLLExportLinkage; + } + static bool isExternalWeakLinkage(LinkageTypes Linkage) { + return Linkage == ExternalWeakLinkage; + } + static bool isCommonLinkage(LinkageTypes Linkage) { + return Linkage == CommonLinkage; } - bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; } - bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; } - bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; } - bool hasCommonLinkage() const { return Linkage == CommonLinkage; } - - void setLinkage(LinkageTypes LT) { Linkage = LT; } - LinkageTypes getLinkage() const { return Linkage; } /// mayBeOverridden - Whether the definition of this global may be replaced /// by something non-equivalent at link time. For example, if a function has /// weak linkage then the code defining it may be replaced by different code. - bool mayBeOverridden() const { + static bool mayBeOverridden(LinkageTypes Linkage) { return (Linkage == WeakAnyLinkage || Linkage == LinkOnceAnyLinkage || Linkage == CommonLinkage || @@ -148,7 +163,7 @@ public: /// isWeakForLinker - Whether the definition of this global may be replaced at /// link time. - bool isWeakForLinker() const { + static bool isWeakForLinker(LinkageTypes Linkage) { return (Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage || @@ -158,6 +173,33 @@ public: Linkage == ExternalWeakLinkage); } + bool hasExternalLinkage() const { return isExternalLinkage(Linkage); } + bool hasAvailableExternallyLinkage() const { + return isAvailableExternallyLinkage(Linkage); + } + bool hasLinkOnceLinkage() const { + return isLinkOnceLinkage(Linkage); + } + bool hasWeakLinkage() const { + return isWeakLinkage(Linkage); + } + bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); } + bool hasInternalLinkage() const { return isInternalLinkage(Linkage); } + bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); } + bool hasLinkerPrivateLinkage() const { return isLinkerPrivateLinkage(Linkage); } + bool hasLocalLinkage() const { return isLocalLinkage(Linkage); } + bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); } + bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); } + bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); } + bool hasCommonLinkage() const { return isCommonLinkage(Linkage); } + + void setLinkage(LinkageTypes LT) { Linkage = LT; } + LinkageTypes getLinkage() const { return Linkage; } + + bool mayBeOverridden() const { return mayBeOverridden(Linkage); } + + bool isWeakForLinker() const { return isWeakForLinker(Linkage); } + /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalValue) from the GlobalValue Src to this one. virtual void copyAttributesFrom(const GlobalValue *Src); diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 5ce1a9d..49cdd6a 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -696,36 +696,36 @@ public: /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the /// predicate values are not overlapping between the classes. enum Predicate { - // Opcode U L G E Intuitive operation - FCMP_FALSE = 0, /// 0 0 0 0 Always false (always folded) - FCMP_OEQ = 1, /// 0 0 0 1 True if ordered and equal - FCMP_OGT = 2, /// 0 0 1 0 True if ordered and greater than - FCMP_OGE = 3, /// 0 0 1 1 True if ordered and greater than or equal - FCMP_OLT = 4, /// 0 1 0 0 True if ordered and less than - FCMP_OLE = 5, /// 0 1 0 1 True if ordered and less than or equal - FCMP_ONE = 6, /// 0 1 1 0 True if ordered and operands are unequal - FCMP_ORD = 7, /// 0 1 1 1 True if ordered (no nans) - FCMP_UNO = 8, /// 1 0 0 0 True if unordered: isnan(X) | isnan(Y) - FCMP_UEQ = 9, /// 1 0 0 1 True if unordered or equal - FCMP_UGT = 10, /// 1 0 1 0 True if unordered or greater than - FCMP_UGE = 11, /// 1 0 1 1 True if unordered, greater than, or equal - FCMP_ULT = 12, /// 1 1 0 0 True if unordered or less than - FCMP_ULE = 13, /// 1 1 0 1 True if unordered, less than, or equal - FCMP_UNE = 14, /// 1 1 1 0 True if unordered or not equal - FCMP_TRUE = 15, /// 1 1 1 1 Always true (always folded) + // Opcode U L G E Intuitive operation + FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded) + FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal + FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than + FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal + FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than + FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal + FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal + FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans) + FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y) + FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal + FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than + FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal + FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than + FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal + FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal + FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded) FIRST_FCMP_PREDICATE = FCMP_FALSE, LAST_FCMP_PREDICATE = FCMP_TRUE, BAD_FCMP_PREDICATE = FCMP_TRUE + 1, - ICMP_EQ = 32, /// equal - ICMP_NE = 33, /// not equal - ICMP_UGT = 34, /// unsigned greater than - ICMP_UGE = 35, /// unsigned greater or equal - ICMP_ULT = 36, /// unsigned less than - ICMP_ULE = 37, /// unsigned less or equal - ICMP_SGT = 38, /// signed greater than - ICMP_SGE = 39, /// signed greater or equal - ICMP_SLT = 40, /// signed less than - ICMP_SLE = 41, /// signed less or equal + ICMP_EQ = 32, ///< equal + ICMP_NE = 33, ///< not equal + ICMP_UGT = 34, ///< unsigned greater than + ICMP_UGE = 35, ///< unsigned greater or equal + ICMP_ULT = 36, ///< unsigned less than + ICMP_ULE = 37, ///< unsigned less or equal + ICMP_SGT = 38, ///< signed greater than + ICMP_SGE = 39, ///< signed greater or equal + ICMP_SLT = 40, ///< signed less than + ICMP_SLE = 41, ///< signed less or equal FIRST_ICMP_PREDICATE = ICMP_EQ, LAST_ICMP_PREDICATE = ICMP_SLE, BAD_ICMP_PREDICATE = ICMP_SLE + 1 diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index c6cdbd5..f07291c 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -590,8 +590,8 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || - isa<PointerType>(getOperand(0)->getType())) && + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || + getOperand(0)->getType()->isPointerTy()) && "Invalid operand types for ICmp instruction"); } @@ -611,8 +611,8 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || - isa<PointerType>(getOperand(0)->getType())) && + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || + getOperand(0)->getType()->isPointerTy()) && "Invalid operand types for ICmp instruction"); } @@ -630,8 +630,8 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type - assert((getOperand(0)->getType()->isIntOrIntVector() || - isa<PointerType>(getOperand(0)->getType())) && + assert((getOperand(0)->getType()->isIntOrIntVectorTy() || + getOperand(0)->getType()->isPointerTy()) && "Invalid operand types for ICmp instruction"); } @@ -740,7 +740,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } @@ -759,7 +759,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } @@ -776,7 +776,7 @@ public: assert(getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to FCmp instruction are not of the same type!"); // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVector() && + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } @@ -1805,7 +1805,7 @@ public: return i/2; } - /// getIncomingBlock - Return incoming basic block #i. + /// getIncomingBlock - Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { return cast<BasicBlock>(getOperand(i*2+1)); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index a7e2e05..ae53851 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -46,7 +46,6 @@ namespace { (void) llvm::createAggressiveDCEPass(); (void) llvm::createAliasAnalysisCounterPass(); (void) llvm::createAliasDebugger(); - (void) llvm::createAndersensPass(); (void) llvm::createArgumentPromotionPass(); (void) llvm::createStructRetPromotionPass(); (void) llvm::createBasicAliasAnalysisPass(); diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 55696b0..882929f 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -14,6 +14,7 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/Casting.h" +#include "llvm/MC/MCFixup.h" #include "llvm/System/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -22,10 +23,34 @@ class raw_ostream; class MCAssembler; class MCContext; class MCExpr; +class MCFragment; class MCSection; class MCSectionData; class MCSymbol; +/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment +/// which needs to be rewritten. This region will either be rewritten by the +/// assembler or cause a relocation entry to be generated. +struct MCAsmFixup { + /// Offset - The offset inside the fragment which needs to be rewritten. + uint64_t Offset; + + /// Value - The expression to eventually write into the fragment. + const MCExpr *Value; + + /// Kind - The fixup kind. + MCFixupKind Kind; + + /// FixedValue - The value to replace the fix up by. + // + // FIXME: This should not be here. + uint64_t FixedValue; + +public: + MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) + : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {} +}; + class MCFragment : public ilist_node<MCFragment> { MCFragment(const MCFragment&); // DO NOT IMPLEMENT void operator=(const MCFragment&); // DO NOT IMPLEMENT @@ -85,7 +110,7 @@ public: uint64_t getAddress() const; - uint64_t getFileSize() const { + uint64_t getFileSize() const { assert(FileSize != ~UINT64_C(0) && "File size not set!"); return FileSize; } @@ -103,11 +128,20 @@ public: /// @} static bool classof(const MCFragment *O) { return true; } + + virtual void dump(); }; class MCDataFragment : public MCFragment { SmallString<32> Contents; + /// Fixups - The list of fixups in this fragment. + std::vector<MCAsmFixup> Fixups; + +public: + typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator; + typedef std::vector<MCAsmFixup>::iterator fixup_iterator; + public: MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} @@ -123,10 +157,28 @@ public: /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Data; + /// @name Fixup Access + /// @{ + + std::vector<MCAsmFixup> &getFixups() { return Fixups; } + const std::vector<MCAsmFixup> &getFixups() const { return Fixups; } + + fixup_iterator fixup_begin() { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + + fixup_iterator fixup_end() {return Fixups.end();} + const_fixup_iterator fixup_end() const {return Fixups.end();} + + size_t fixup_size() const { return Fixups.size(); } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Data; } static bool classof(const MCDataFragment *) { return true; } + + virtual void dump(); }; class MCAlignFragment : public MCFragment { @@ -143,12 +195,16 @@ class MCAlignFragment : public MCFragment { /// cannot be satisfied in this width then this fragment is ignored. unsigned MaxBytesToEmit; + /// EmitNops - true when aligning code and optimal nops to be used for filling + bool EmitNops; + public: MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, - unsigned _MaxBytesToEmit, MCSectionData *SD = 0) + unsigned _MaxBytesToEmit, bool _EmitNops, + MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {} /// @name Accessors /// @{ @@ -158,24 +214,28 @@ public: } unsigned getAlignment() const { return Alignment; } - + int64_t getValue() const { return Value; } unsigned getValueSize() const { return ValueSize; } unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } + unsigned getEmitNops() const { return EmitNops; } + /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Align; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Align; } static bool classof(const MCAlignFragment *) { return true; } + + virtual void dump(); }; class MCFillFragment : public MCFragment { /// Value - Value to use for filling bytes. - const MCExpr *Value; + int64_t Value; /// ValueSize - The size (in bytes) of \arg Value to use when filling. unsigned ValueSize; @@ -184,10 +244,10 @@ class MCFillFragment : public MCFragment { uint64_t Count; public: - MCFillFragment(const MCExpr &_Value, unsigned _ValueSize, uint64_t _Count, - MCSectionData *SD = 0) + MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count, + MCSectionData *SD = 0) : MCFragment(FT_Fill, SD), - Value(&_Value), ValueSize(_ValueSize), Count(_Count) {} + Value(_Value), ValueSize(_ValueSize), Count(_Count) {} /// @name Accessors /// @{ @@ -196,25 +256,27 @@ public: return ValueSize * Count; } - const MCExpr &getValue() const { return *Value; } - + int64_t getValue() const { return Value; } + unsigned getValueSize() const { return ValueSize; } uint64_t getCount() const { return Count; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Fill; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Fill; } static bool classof(const MCFillFragment *) { return true; } + + virtual void dump(); }; class MCOrgFragment : public MCFragment { /// Offset - The offset this fragment should start at. const MCExpr *Offset; - /// Value - Value to use for filling bytes. + /// Value - Value to use for filling bytes. int8_t Value; public: @@ -231,15 +293,17 @@ public: } const MCExpr &getOffset() const { return *Offset; } - + uint8_t getValue() const { return Value; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Org; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Org; } static bool classof(const MCOrgFragment *) { return true; } + + virtual void dump(); }; /// MCZeroFillFragment - Represent data which has a fixed size and alignment, @@ -265,15 +329,17 @@ public: } uint64_t getSize() const { return Size; } - + unsigned getAlignment() const { return Alignment; } /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_ZeroFill; + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_ZeroFill; } static bool classof(const MCZeroFillFragment *) { return true; } + + virtual void dump(); }; // FIXME: Should this be a separate class, or just merged into MCSection? Since @@ -284,41 +350,13 @@ class MCSectionData : public ilist_node<MCSectionData> { void operator=(const MCSectionData&); // DO NOT IMPLEMENT public: - /// Fixup - Represent a fixed size region of bytes inside some fragment which - /// needs to be rewritten. This region will either be rewritten by the - /// assembler or cause a relocation entry to be generated. - struct Fixup { - /// Fragment - The fragment containing the fixup. - MCFragment *Fragment; - - /// Offset - The offset inside the fragment which needs to be rewritten. - uint64_t Offset; - - /// Value - The expression to eventually write into the fragment. - const MCExpr *Value; - - /// Size - The fixup size. - unsigned Size; - - /// FixedValue - The value to replace the fix up by. - // - // FIXME: This should not be here. - uint64_t FixedValue; - - public: - Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value, - unsigned _Size) - : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size), - FixedValue(0) {} - }; - typedef iplist<MCFragment> FragmentListType; typedef FragmentListType::const_iterator const_iterator; typedef FragmentListType::iterator iterator; - typedef std::vector<Fixup>::const_iterator const_fixup_iterator; - typedef std::vector<Fixup>::iterator fixup_iterator; + typedef FragmentListType::const_reverse_iterator const_reverse_iterator; + typedef FragmentListType::reverse_iterator reverse_iterator; private: iplist<MCFragment> Fragments; @@ -343,19 +381,13 @@ private: /// initialized. uint64_t FileSize; - /// LastFixupLookup - Cache for the last looked up fixup. - mutable unsigned LastFixupLookup; - - /// Fixups - The list of fixups in this section. - std::vector<Fixup> Fixups; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; /// @} -public: +public: // Only for use as sentinel. MCSectionData(); MCSectionData(const MCSection &Section, MCAssembler *A = 0); @@ -377,27 +409,15 @@ public: iterator end() { return Fragments.end(); } const_iterator end() const { return Fragments.end(); } - size_t size() const { return Fragments.size(); } - - bool empty() const { return Fragments.empty(); } + reverse_iterator rbegin() { return Fragments.rbegin(); } + const_reverse_iterator rbegin() const { return Fragments.rbegin(); } - /// @} - /// @name Fixup Access - /// @{ - - std::vector<Fixup> &getFixups() { - return Fixups; - } - - fixup_iterator fixup_begin() { - return Fixups.begin(); - } + reverse_iterator rend() { return Fragments.rend(); } + const_reverse_iterator rend() const { return Fragments.rend(); } - fixup_iterator fixup_end() { - return Fixups.end(); - } + size_t size() const { return Fragments.size(); } - size_t fixup_size() const { return Fixups.size(); } + bool empty() const { return Fragments.empty(); } /// @} /// @name Assembler Backend Support @@ -405,38 +425,30 @@ public: // // FIXME: This could all be kept private to the assembler implementation. - /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg - /// Offset. - /// - /// If multiple fixups exist for the same fragment and offset it is undefined - /// which one is returned. - // - // FIXME: This isn't horribly slow in practice, but there are much nicer - // solutions to applying the fixups. - const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const; - - uint64_t getAddress() const { + uint64_t getAddress() const { assert(Address != ~UINT64_C(0) && "Address not set!"); return Address; } void setAddress(uint64_t Value) { Address = Value; } - uint64_t getSize() const { + uint64_t getSize() const { assert(Size != ~UINT64_C(0) && "File size not set!"); return Size; } void setSize(uint64_t Value) { Size = Value; } - uint64_t getFileSize() const { + uint64_t getFileSize() const { assert(FileSize != ~UINT64_C(0) && "File size not set!"); return FileSize; } - void setFileSize(uint64_t Value) { FileSize = Value; } + void setFileSize(uint64_t Value) { FileSize = Value; } bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } /// @} + + void dump(); }; // FIXME: Same concerns as with SectionData. @@ -450,7 +462,7 @@ public: /// Offset - The offset to apply to the fragment address to form this symbol's /// value. uint64_t Offset; - + /// IsExternal - True if this symbol is visible outside this translation /// unit. unsigned IsExternal : 1; @@ -496,10 +508,10 @@ public: /// @} /// @name Symbol Attributes /// @{ - + bool isExternal() const { return IsExternal; } void setExternal(bool Value) { IsExternal = Value; } - + bool isPrivateExtern() const { return IsPrivateExtern; } void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } @@ -532,14 +544,16 @@ public: /// setFlags - Set the (implementation defined) symbol flags. void setFlags(uint32_t Value) { Flags = Value; } - + /// getIndex - Get the (implementation defined) index. uint64_t getIndex() const { return Index; } /// setIndex - Set the (implementation defined) index. void setIndex(uint64_t Value) { Index = Value; } - - /// @} + + /// @} + + void dump(); }; // FIXME: This really doesn't belong here. See comments below. @@ -568,7 +582,7 @@ private: MCContext &Context; raw_ostream &OS; - + iplist<MCSectionData> Sections; iplist<MCSymbolData> Symbols; @@ -612,7 +626,7 @@ public: /// @{ const SectionDataListType &getSectionList() const { return Sections; } - SectionDataListType &getSectionList() { return Sections; } + SectionDataListType &getSectionList() { return Sections; } iterator begin() { return Sections.begin(); } const_iterator begin() const { return Sections.begin(); } @@ -659,6 +673,8 @@ public: size_t indirect_symbol_size() const { return IndirectSymbols.size(); } /// @} + + void dump(); }; } // end namespace llvm diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 5565945..fe1aff4 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -56,7 +56,7 @@ public: virtual unsigned getNumFixupKinds() const = 0; /// getFixupKindInfo - Get information on a fixup kind. - virtual MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const = 0; + virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; /// @} diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 95c6bd4..74415e2 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -46,30 +46,28 @@ namespace llvm { /// @name Symbol Managment /// @{ - /// CreateSymbol - Create a new symbol with the specified @param Name. + /// CreateSymbol - Create a new symbol with the specified @p Name. /// /// @param Name - The symbol name, which must be unique across all symbols. MCSymbol *CreateSymbol(StringRef Name); /// GetOrCreateSymbol - Lookup the symbol inside with the specified - /// @param Name. If it exists, return it. If not, create a forward + /// @p Name. If it exists, return it. If not, create a forward /// reference and return it. /// /// @param Name - The symbol name, which must be unique across all symbols. - /// @param IsTemporary - Whether this symbol is an assembler temporary, - /// which should not survive into the symbol table for the translation unit. MCSymbol *GetOrCreateSymbol(StringRef Name); MCSymbol *GetOrCreateSymbol(const Twine &Name); /// CreateTemporarySymbol - Create a new temporary symbol with the specified - /// @param Name. + /// @p Name. /// /// @param Name - The symbol name, for debugging purposes only, temporary /// symbols do not surive assembly. If non-empty the name must be unique /// across all symbols. MCSymbol *CreateTemporarySymbol(StringRef Name = ""); - /// LookupSymbol - Get the symbol for @param Name, or null. + /// LookupSymbol - Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(StringRef Name) const; /// @} diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 609a9a4..1f7364d 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -17,32 +17,32 @@ namespace llvm { enum MCSymbolAttr { - MCSA_Invalid = 0, /// Not a valid directive. + MCSA_Invalid = 0, ///< Not a valid directive. // Various directives in alphabetical order. - MCSA_ELF_TypeFunction, /// .type _foo, STT_FUNC # aka @function - MCSA_ELF_TypeIndFunction, /// .type _foo, STT_GNU_IFUNC - MCSA_ELF_TypeObject, /// .type _foo, STT_OBJECT # aka @object - MCSA_ELF_TypeTLS, /// .type _foo, STT_TLS # aka @tls_object - MCSA_ELF_TypeCommon, /// .type _foo, STT_COMMON # aka @common - MCSA_ELF_TypeNoType, /// .type _foo, STT_NOTYPE # aka @notype - MCSA_Global, /// .globl - MCSA_Hidden, /// .hidden (ELF) - MCSA_IndirectSymbol, /// .indirect_symbol (MachO) - MCSA_Internal, /// .internal (ELF) - MCSA_LazyReference, /// .lazy_reference (MachO) - MCSA_Local, /// .local (ELF) - MCSA_NoDeadStrip, /// .no_dead_strip (MachO) - MCSA_PrivateExtern, /// .private_extern (MachO) - MCSA_Protected, /// .protected (ELF) - MCSA_Reference, /// .reference (MachO) - MCSA_Weak, /// .weak - MCSA_WeakDefinition, /// .weak_definition (MachO) - MCSA_WeakReference /// .weak_reference (MachO) + MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function + MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC + MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object + MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object + MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common + MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype + MCSA_Global, ///< .globl + MCSA_Hidden, ///< .hidden (ELF) + MCSA_IndirectSymbol, ///< .indirect_symbol (MachO) + MCSA_Internal, ///< .internal (ELF) + MCSA_LazyReference, ///< .lazy_reference (MachO) + MCSA_Local, ///< .local (ELF) + MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) + MCSA_PrivateExtern, ///< .private_extern (MachO) + MCSA_Protected, ///< .protected (ELF) + MCSA_Reference, ///< .reference (MachO) + MCSA_Weak, ///< .weak + MCSA_WeakDefinition, ///< .weak_definition (MachO) + MCSA_WeakReference ///< .weak_reference (MachO) }; enum MCAssemblerFlag { - MCAF_SubsectionsViaSymbols /// .subsections_via_symbols (MachO) + MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO) }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 48a13f6..fce7602 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -340,7 +340,7 @@ class MCTargetExpr : public MCExpr { virtual void Anchor(); protected: MCTargetExpr() : MCExpr(Target) {} - + virtual ~MCTargetExpr() {} public: virtual void PrintImpl(raw_ostream &OS) const = 0; diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index f325d65..cd0dd19 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -89,6 +89,18 @@ public: unsigned getOffset() const { return Offset; } const MCExpr *getValue() const { return Value; } + + /// getKindForSize - Return the generic fixup kind for a value with the given + /// size. It is an error to pass an unsupported size. + static MCFixupKind getKindForSize(unsigned Size) { + switch (Size) { + default: assert(0 && "Invalid generic fixup size!"); + case 1: return FK_Data_1; + case 2: return FK_Data_2; + case 4: return FK_Data_4; + case 8: return FK_Data_8; + } + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 8829518..d2ddc5b 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -14,8 +14,8 @@ namespace llvm { class MCInst; class raw_ostream; class MCAsmInfo; +class StringRef; - /// MCInstPrinter - This is an instance of a target assembly language printer /// that converts an MCInst to valid target assembly syntax. class MCInstPrinter { @@ -40,6 +40,10 @@ public: /// printInst - Print the specified MCInst to the current raw_ostream. /// virtual void printInst(const MCInst *MI) = 0; + + /// getOpcodeName - Return the name of the specified opcode enum (e.g. + /// "MOV32ri") or empty if we can't resolve it. + virtual StringRef getOpcodeName(unsigned Opcode) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 624d9a6..696d024 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -92,12 +92,12 @@ namespace llvm { const MCSection *getCurrentSection() const { return CurSection; } /// SwitchSection - Set the current section where code is being emitted to - /// @param Section. This is required to update CurSection. + /// @p Section. This is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. virtual void SwitchSection(const MCSection *Section) = 0; - /// EmitLabel - Emit a label for @param Symbol into the current section. + /// EmitLabel - Emit a label for @p Symbol into the current section. /// /// This corresponds to an assembler statement such as: /// foo: @@ -107,10 +107,10 @@ namespace llvm { /// used in an assignment. virtual void EmitLabel(MCSymbol *Symbol) = 0; - /// EmitAssemblerFlag - Note in the output the specified @param Flag + /// EmitAssemblerFlag - Note in the output the specified @p Flag virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; - /// EmitAssignment - Emit an assignment of @param Value to @param Symbol. + /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// /// This corresponds to an assembler statement such as: /// symbol = value @@ -123,11 +123,11 @@ namespace llvm { /// @param Value - The value for the symbol. virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0; - /// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol. + /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol. virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) = 0; - /// EmitSymbolDesc - Set the @param DescValue for the @param Symbol. + /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol. /// /// @param Symbol - The symbol to have its n_desc field set. /// @param DescValue - The value to set into the n_desc field. @@ -176,8 +176,8 @@ namespace llvm { /// etc. virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; - /// EmitValue - Emit the expression @param Value into the output as a native - /// integer of the given @param Size bytes. + /// EmitValue - Emit the expression @p Value into the output as a native + /// integer of the given @p Size bytes. /// /// This is used to implement assembler directives such as .word, .quad, /// etc. @@ -192,7 +192,7 @@ namespace llvm { /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace); - /// EmitGPRel32Value - Emit the expression @param Value into the output as a + /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// /// This is used to implement assembler directives such as .gprel32 on @@ -211,11 +211,11 @@ namespace llvm { } - /// EmitValueToAlignment - Emit some number of copies of @param Value until - /// the byte alignment @param ByteAlignment is reached. + /// EmitValueToAlignment - Emit some number of copies of @p Value until + /// the byte alignment @p ByteAlignment is reached. /// /// If the number of bytes need to emit for the alignment is not a multiple - /// of @param ValueSize, then the contents of the emitted fill bytes is + /// of @p ValueSize, then the contents of the emitted fill bytes is /// undefined. /// /// This used to implement the .align assembler directive. @@ -223,8 +223,8 @@ namespace llvm { /// @param ByteAlignment - The alignment to reach. This must be a power of /// two on some targets. /// @param Value - The value to use when filling bytes. - /// @param Size - The size of the integer (in bytes) to emit for @param - /// Value. This must match a native machine width. + /// @param ValueSize - The size of the integer (in bytes) to emit for + /// @p Value. This must match a native machine width. /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If /// the alignment cannot be reached in this many bytes, no bytes are /// emitted. @@ -232,8 +232,22 @@ namespace llvm { unsigned ValueSize = 1, unsigned MaxBytesToEmit = 0) = 0; - /// EmitValueToOffset - Emit some number of copies of @param Value until the - /// byte offset @param Offset is reached. + /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment + /// is reached. + /// + /// This used to align code where the alignment bytes may be executed. This + /// can emit different bytes for different sizes to optimize execution. + /// + /// @param ByteAlignment - The alignment to reach. This must be a power of + /// two on some targets. + /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If + /// the alignment cannot be reached in this many bytes, no bytes are + /// emitted. + virtual void EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit = 0) = 0; + + /// EmitValueToOffset - Emit some number of copies of @p Value until the + /// byte offset @p Offset is reached. /// /// This is used to implement assembler directives such as .org. /// @@ -254,7 +268,7 @@ namespace llvm { /// directive. virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0; - /// EmitInstruction - Emit the given @param Instruction into the current + /// EmitInstruction - Emit the given @p Instruction into the current /// section. virtual void EmitInstruction(const MCInst &Inst) = 0; diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 4e459bf..e536322 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -75,6 +75,7 @@ class MDNode : public Value, public FoldingSetNode { MDNode(const MDNode &); // DO NOT IMPLEMENT void operator=(const MDNode &); // DO NOT IMPLEMENT friend class MDNodeOperand; + friend class LLVMContextImpl; /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the /// end of this MDNode. @@ -103,9 +104,13 @@ class MDNode : public Value, public FoldingSetNode { FL_Yes = 1 }; - // Replace each instance of F from the operand list of this node with T. + /// replaceOperand - Replace each instance of F from the operand list of this + /// node with T. void replaceOperand(MDNodeOperand *Op, Value *NewVal); ~MDNode(); + /// replaceAllOperandsWithNull - This is used while destroying llvm context to + /// gracefully delete all nodes. This method replaces all operands with null. + void replaceAllOperandsWithNull(); protected: explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index ab08afb..8fc3a53 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -56,11 +56,11 @@ typedef const PassInfo* AnalysisID; /// Ordering of pass manager types is important here. enum PassManagerType { PMT_Unknown = 0, - PMT_ModulePassManager = 1, /// MPPassManager - PMT_CallGraphPassManager, /// CGPassManager - PMT_FunctionPassManager, /// FPPassManager - PMT_LoopPassManager, /// LPPassManager - PMT_BasicBlockPassManager, /// BBPassManager + PMT_ModulePassManager = 1, ///< MPPassManager + PMT_CallGraphPassManager, ///< CGPassManager + PMT_FunctionPassManager, ///< FPPassManager + PMT_LoopPassManager, ///< LPPassManager + PMT_BasicBlockPassManager, ///< BBPassManager PMT_Last }; @@ -163,7 +163,7 @@ public: /// an analysis interface through multiple inheritance. If needed, it should /// override this to adjust the this pointer as needed for the specified pass /// info. - virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + virtual void *getAdjustedAnalysisPointer(const PassInfo *) { return this; } virtual ImmutablePass *getAsImmutablePass() { return 0; } diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 3ee2313..61c3256 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -93,9 +93,9 @@ enum ValueExpected { // Is a value required for the option? }; enum OptionHidden { // Control whether -help shows this option - NotHidden = 0x20, // Option included in --help & --help-hidden - Hidden = 0x40, // -help doesn't, but --help-hidden does - ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg + NotHidden = 0x20, // Option included in -help & -help-hidden + Hidden = 0x40, // -help doesn't, but -help-hidden does + ReallyHidden = 0x60, // Neither -help nor -help-hidden show this arg HiddenMask = 0x60 }; @@ -159,7 +159,7 @@ class Option { Option *NextRegistered; // Singly linked list of registered options. public: const char *ArgStr; // The argument string itself (ex: "help", "o") - const char *HelpStr; // The descriptive text message for --help + const char *HelpStr; // The descriptive text message for -help const char *ValueStr; // String describing what the value of this option is inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { @@ -251,14 +251,14 @@ public: // command line option parsers... // -// desc - Modifier to set the description shown in the --help output... +// desc - Modifier to set the description shown in the -help output... struct desc { const char *Desc; desc(const char *Str) : Desc(Str) {} void apply(Option &O) const { O.setDescription(Desc); } }; -// value_desc - Modifier to set the value description shown in the --help +// value_desc - Modifier to set the value description shown in the -help // output... struct value_desc { const char *Desc; @@ -437,7 +437,7 @@ protected: // Default parser implementation - This implementation depends on having a // mapping of recognized options to values of some sort. In addition to this, // each entry in the mapping also tracks a help message that is printed with the -// command line option for --help. Because this is a simple mapping parser, the +// command line option for -help. Because this is a simple mapping parser, the // data type can be any unsupported type. // template <class DataType> @@ -1373,7 +1373,7 @@ struct extrahelp { void PrintVersionMessage(); // This function just prints the help message, exactly the same way as if the -// --help option had been given on the command line. +// -help option had been given on the command line. // NOTE: THIS FUNCTION TERMINATES THE PROGRAM! void PrintHelpMessage(); diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 1376e46..881a0fe 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -78,7 +78,9 @@ // ALWAYS_INLINE - On compilers where we have a directive to do so, mark a // method "always inline" because it is performance sensitive. -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +// GCC 3.4 supported this but is buggy in various cases and produces +// unimplemented errors, just use it in GCC 4.0 and later. +#if __GNUC__ > 3 #define ALWAYS_INLINE __attribute__((always_inline)) #else // TODO: No idea how to do this with MSVC. diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index bfccc52..5f591d4 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -580,7 +580,6 @@ const char *MacinfoString(unsigned Encoding); /// CallFrameString - Return the string for the specified call frame instruction /// encodings. const char *CallFrameString(unsigned Encoding); - } // End of namespace dwarf } // End of namespace llvm diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index af546f0..58a1885 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/FormattedStream.h - Formatted streams ------*- C++ -*-===// +//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -119,7 +119,7 @@ namespace llvm /// space. /// /// \param NewCol - The column to move to. - void PadToColumn(unsigned NewCol); + formatted_raw_ostream &PadToColumn(unsigned NewCol); private: void releaseStream() { diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 0139793..1f4e598 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -94,7 +94,7 @@ public: //===--------------------------------------------------------------------===// /// CreateGlobalString - Make a new global variable with an initializer that - /// has array of i8 type filled in the nul terminated string value + /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable /// created. Value *CreateGlobalString(const char *Str = "", const Twine &Name = ""); @@ -143,6 +143,10 @@ public: return Type::getVoidTy(Context); } + const Type *getInt8PtrTy() { + return Type::getInt8PtrTy(Context); + } + /// getCurrentFunctionReturnType - Get the return type of the current function /// that we're emitting into. const Type *getCurrentFunctionReturnType() const; diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index c954c0d..591af00 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -56,6 +56,19 @@ namespace llvm { /// /// This returns true on a successful match. bool match(const StringRef &String, SmallVectorImpl<StringRef> *Matches=0); + + /// sub - Return the result of replacing the first match of the regex in + /// \arg String with the \arg Repl string. Backreferences like "\0" in the + /// replacement string are replaced with the appropriate match substring. + /// + /// Note that the replacement string has backslash escaping performed on + /// it. Invalid backreferences are ignored (replaced by empty strings). + /// + /// \param Error If non-null, any errors in the substitution (invalid + /// backreferences, trailing backslashes) will be recorded as a non-empty + /// string. + std::string sub(StringRef Repl, StringRef String, std::string *Error = 0); + private: struct llvm_regex *preg; int error; diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index bed2f13..fd56b16 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -132,7 +132,7 @@ class SMDiagnostic { unsigned ShowLine : 1; public: - SMDiagnostic() : LineNo(0), ColumnNo(0) {} + SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {} SMDiagnostic(const std::string &FN, int Line, int Col, const std::string &Msg, const std::string &LineStr, bool showline = true) diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 384c493..d34f35f 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -185,7 +185,9 @@ public: return C; // avoid calling Fold return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); } - + Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + return ConstantExpr::getPointerCast(C, DestTy); + } Constant *CreateBitCast(Constant *C, const Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } diff --git a/include/llvm/System/DataTypes.h b/include/llvm/System/DataTypes.h new file mode 100644 index 0000000..d325c66 --- /dev/null +++ b/include/llvm/System/DataTypes.h @@ -0,0 +1,111 @@ +/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file contains definitions to figure out the size of _HOST_ data types.*| +|* This file is important because different host OS's define different macros,*| +|* which makes portability tough. This file exports the following *| +|* definitions: *| +|* *| +|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*| +|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *| +|* *| +|* No library is required when using these functinons. *| +|* *| +|*===----------------------------------------------------------------------===*/ + +/* Please leave this file C-compatible. */ + +#ifndef SUPPORT_DATATYPES_H +#define SUPPORT_DATATYPES_H + +#define HAVE_SYS_TYPES_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UINT64_T 1 +/* #undef HAVE_U_INT64_T */ + +#ifdef __cplusplus +#include <cmath> +#else +#include <math.h> +#endif + +/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS + being defined. We would define it here, but in order to prevent Bad Things + happening when system headers or C++ STL headers include stdint.h before we + define it here, we define it on the g++ command line (in Makefile.rules). */ +#if !defined(__STDC_LIMIT_MACROS) +# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h" +#endif + +#if !defined(__STDC_CONSTANT_MACROS) +# error "Must #define __STDC_CONSTANT_MACROS before " \ + "#including System/DataTypes.h" +#endif + +/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */ +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#ifdef _AIX +#include "llvm/System/AIXDataTypesFix.h" +#endif + +/* Handle incorrect definition of uint64_t as u_int64_t */ +#ifndef HAVE_UINT64_T +#ifdef HAVE_U_INT64_T +typedef u_int64_t uint64_t; +#else +# error "Don't have a definition for uint64_t on this platform" +#endif +#endif + +#ifdef _OpenBSD_ +#define INT8_MAX 127 +#define INT8_MIN -128 +#define UINT8_MAX 255 +#define INT16_MAX 32767 +#define INT16_MIN -32768 +#define UINT16_MAX 65535 +#define INT32_MAX 2147483647 +#define INT32_MIN -2147483648 +#define UINT32_MAX 4294967295U +#endif + +/* Set defaults for constants which we cannot find. */ +#if !defined(INT64_MAX) +# define INT64_MAX 9223372036854775807LL +#endif +#if !defined(INT64_MIN) +# define INT64_MIN ((-INT64_MAX)-1) +#endif +#if !defined(UINT64_MAX) +# define UINT64_MAX 0xffffffffffffffffULL +#endif + +#if __GNUC__ > 3 +#define END_WITH_NULL __attribute__((sentinel)) +#else +#define END_WITH_NULL +#endif + +#ifndef HUGE_VALF +#define HUGE_VALF (float)HUGE_VAL +#endif + +#endif /* SUPPORT_DATATYPES_H */ diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h index 1be27b2..d4af478 100644 --- a/include/llvm/System/Path.h +++ b/include/llvm/System/Path.h @@ -203,7 +203,7 @@ namespace sys { } /// Makes a copy of \p that to \p this. - /// @param \p that A StringRef denoting the path + /// @param that A StringRef denoting the path /// @returns \p this /// @brief Assignment Operator Path &operator=(StringRef that); diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h index 04de4e9..45cbf9d 100644 --- a/include/llvm/Target/Mangler.h +++ b/include/llvm/Target/Mangler.h @@ -1,4 +1,4 @@ -//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===// +//===-- llvm/Target/Mangler.h - Self-contained name mangler ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 9a117df..0cffffb 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -211,16 +211,9 @@ class Instruction { // hasSideEffects - The instruction has side effects that are not // captured by any operands of the instruction or other flags. // - // mayHaveSideEffects - Some instances of the instruction can have side - // effects. The virtual method "isReallySideEffectFree" is called to - // determine this. Load instructions are an example of where this is - // useful. In general, loads always have side effects. However, loads from - // constant pools don't. Individual back ends make this determination. - // // neverHasSideEffects - Set on an instruction with no pattern if it has no // side effects. bit hasSideEffects = 0; - bit mayHaveSideEffects = 0; bit neverHasSideEffects = 0; // Is this instruction a "real" instruction (with a distinct machine diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h new file mode 100644 index 0000000..dfdabdb --- /dev/null +++ b/include/llvm/Target/TargetAsmBackend.h @@ -0,0 +1,35 @@ +//===-- llvm/Target/TargetAsmBackend.h - Target Asm Backend -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETASMBACKEND_H +#define LLVM_TARGET_TARGETASMBACKEND_H + +namespace llvm { +class Target; + +/// TargetAsmBackend - Generic interface to target specific assembler backends. +class TargetAsmBackend { + TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT + void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT +protected: // Can only create subclasses. + TargetAsmBackend(const Target &); + + /// TheTarget - The Target that this machine was created for. + const Target &TheTarget; + +public: + virtual ~TargetAsmBackend(); + + const Target &getTarget() const { return TheTarget; } + +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index da9ba2b..85315c1 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -42,8 +42,8 @@ public: /// line should be parsed up to and including the end-of-statement token. On /// failure, the parser is not required to read to the end of the line. // - /// \param AP - The current parser object. /// \param Name - The instruction name. + /// \param NameLoc - The source location of the name. /// \param Operands [out] - The list of parsed operands, this returns /// ownership of them to the caller. /// \return True on failure. @@ -59,7 +59,7 @@ public: /// the target, the entire line is parsed up to and including the /// end-of-statement token and false is returned. /// - /// \param ID - the identifier token of the directive. + /// \param DirectiveID - the identifier token of the directive. virtual bool ParseDirective(AsmToken DirectiveID) = 0; /// MatchInstruction - Recognize a series of operands of a parsed instruction diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index d95e4e8..4b26beb 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -19,14 +19,14 @@ namespace llvm { -class MCAsmInfo; -class TargetRegisterClass; -class TargetRegisterInfo; -class LiveVariables; class CalleeSavedInfo; +class LiveVariables; +class MCAsmInfo; +class MachineMemOperand; class SDNode; class SelectionDAG; -class MachineMemOperand; +class TargetRegisterClass; +class TargetRegisterInfo; template<class T> class SmallVectorImpl; @@ -243,13 +243,11 @@ public: virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const = 0; - /// isIdentical - Return true if two instructions are identical. This differs - /// from MachineInstr::isIdenticalTo() in that it does not require the - /// virtual destination registers to be the same. This is used by MachineLICM - /// and other MI passes to perform CSE. - virtual bool isIdentical(const MachineInstr *MI, - const MachineInstr *Other, - const MachineRegisterInfo *MRI) const = 0; + /// produceSameValue - Return true if two machine instructions would produce + /// identical values. By default, this is only true when the two instructions + /// are deemed identical except for defs. + virtual bool produceSameValue(const MachineInstr *MI0, + const MachineInstr *MI1) const = 0; /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't @@ -560,10 +558,8 @@ public: const TargetRegisterInfo *TRI) const; virtual MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; - virtual bool isIdentical(const MachineInstr *MI, - const MachineInstr *Other, - const MachineRegisterInfo *MRI) const; - + virtual bool produceSameValue(const MachineInstr *MI0, + const MachineInstr *MI1) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; }; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index e172edf..5bc1c0e 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -346,6 +346,11 @@ public: return true; } + /// canOpTrap - Returns true if the operation can trap for the value type. + /// VT must be a legal type. By default, we optimistically assume most + /// operations don't trap except for divide and remainder. + virtual bool canOpTrap(unsigned Op, EVT VT) const; + /// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is /// used by Targets can use this to indicate if there is a suitable /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant @@ -659,12 +664,12 @@ public: /// getOptimalMemOpType - Returns the target specific optimal type for load /// and store operations as a result of memset, memcpy, and memmove lowering. - /// It returns EVT::iAny if SelectionDAG should be responsible for + /// It returns EVT::Other if SelectionDAG should be responsible for /// determining it. virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align, bool isSrcConst, bool isSrcStr, SelectionDAG &DAG) const { - return MVT::iAny; + return MVT::Other; } /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp @@ -1159,7 +1164,7 @@ public: bool isVarArg, bool isInreg, unsigned NumFixedArgs, CallingConv::ID CallConv, bool isTailCall, bool isReturnValueUsed, SDValue Callee, ArgListTy &Args, - SelectionDAG &DAG, DebugLoc dl, unsigned Order); + SelectionDAG &DAG, DebugLoc dl); /// LowerCall - This hook must be implemented to lower calls into the /// the specified DAG. The outgoing arguments to the call are described diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index d3e5cf2..42d88a0 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -25,6 +25,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSectionMachO; + class MCSymbol; class MCContext; class GlobalValue; class TargetMachine; @@ -175,187 +176,26 @@ public: return 0; } - /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a - /// pc-relative reference to the specified global variable from exception - /// handling information. In addition to the symbol, this returns - /// by-reference: - /// - /// IsIndirect - True if the returned symbol is actually a stub that contains - /// the address of the symbol, false if the symbol is the global itself. - /// - /// IsPCRel - True if the symbol reference is already pc-relative, false if - /// the caller needs to subtract off the address of the reference from the - /// symbol. + /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a reference + /// to the specified global variable from exception handling information. /// virtual const MCExpr * getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, - bool &IsIndirect, bool &IsPCRel) const; - -protected: - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; -}; - - - + MachineModuleInfo *MMI, unsigned Encoding) const; -class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { - mutable void *UniquingMap; -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; - -protected: - const MCSection *getELFSection(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind, - bool IsExplicit = false) const; -public: - TargetLoweringObjectFileELF() : UniquingMap(0) {} - ~TargetLoweringObjectFileELF(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - /// getSectionForConstant - Given a constant with the SectionKind, return a - /// section that it should be placed in. - virtual const MCSection *getSectionForConstant(SectionKind Kind) const; - - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; -}; - - - -class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { - mutable void *UniquingMap; - - const MCSection *CStringSection; - const MCSection *UStringSection; - const MCSection *TextCoalSection; - const MCSection *ConstTextCoalSection; - const MCSection *ConstDataCoalSection; - 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() : UniquingMap(0) {} - ~TargetLoweringObjectFileMachO(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection * - SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - virtual const MCSection *getSectionForConstant(SectionKind Kind) const; - - /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively - /// decide not to emit the UsedDirective for some symbols in llvm.used. - /// FIXME: REMOVE this (rdar://7071300) - virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, - Mangler *) const; - - /// getMachOSection - Return the MCSection for the specified mach-o section. - /// This requires the operands to be valid. - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - SectionKind K) const { - return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); - } - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, - unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind K) 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; - } - - /// getSymbolForDwarfGlobalReference - The mach-o version of this method - /// defaults to returning a stub reference. virtual const MCExpr * - getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, - bool &IsIndirect, bool &IsPCRel) const; -}; + getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI, + unsigned Encoding) const; + virtual unsigned getPersonalityEncoding() const; + virtual unsigned getLSDAEncoding() const; + virtual unsigned getFDEEncoding() const; + virtual unsigned getTTypeEncoding() const; - -class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { - mutable void *UniquingMap; -public: - TargetLoweringObjectFileCOFF() : UniquingMap(0) {} - ~TargetLoweringObjectFileCOFF(); - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - +protected: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; - - /// getCOFFSection - Return the MCSection for the specified COFF section. - /// FIXME: Switch this to a semantic view eventually. - const MCSection *getCOFFSection(StringRef Name, bool isDirective, - SectionKind K) const; }; } // end namespace llvm diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 63e28ac..a7062ac 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -68,15 +68,6 @@ namespace CodeGenOpt { }; } -// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes. -namespace DwarfLSDAEncoding { - enum Encoding { - Default, - FourByte, - EightByte - }; -} - //===----------------------------------------------------------------------===// /// /// TargetMachine - Primary interface to the complete machine description for @@ -179,20 +170,6 @@ public: /// is false. static void setAsmVerbosityDefault(bool); - /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are - /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that - /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded - /// as a 4-byte pointer by default. However, some systems may require a - /// different size due to bugs or other conditions. We will default to a - /// 4-byte encoding unless the system tells us otherwise. - /// - /// FIXME: This call-back isn't good! We should be using the correct encoding - /// regardless of the system. However, there are some systems which have bugs - /// that prevent this from occuring. - virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const { - return DwarfLSDAEncoding::Default; - } - /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit, and returned by /// it to indicate what type of file could actually be made. @@ -212,8 +189,9 @@ public: /// is not supported, or false on success. virtual bool addPassesToEmitFile(PassManagerBase &, formatted_raw_ostream &, - CodeGenFileType Filetype, - CodeGenOpt::Level) { + CodeGenFileType, + CodeGenOpt::Level, + bool DisableVerify = true) { return true; } @@ -225,7 +203,8 @@ public: /// virtual bool addPassesToEmitMachineCode(PassManagerBase &, JITCodeEmitter &, - CodeGenOpt::Level) { + CodeGenOpt::Level, + bool DisableVerify = true) { return true; } @@ -235,7 +214,8 @@ public: virtual bool WantsWholeFile() const { return false; } virtual bool addPassesToEmitWholeFile(PassManager &, formatted_raw_ostream &, CodeGenFileType, - CodeGenOpt::Level) { + CodeGenOpt::Level, + bool DisableVerify = true) { return true; } }; @@ -250,7 +230,8 @@ protected: // Can only create subclasses. /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for /// both emitting to assembly files or machine code output. /// - bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level); + bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level, + bool DisableVerify); private: virtual void setCodeModelForJIT(); @@ -265,7 +246,8 @@ public: virtual bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, - CodeGenOpt::Level); + CodeGenOpt::Level, + bool DisableVerify = true); /// addPassesToEmitMachineCode - Add passes to the specified pass manager to /// get machine code emitted. This uses a JITCodeEmitter object to handle @@ -275,7 +257,8 @@ public: /// virtual bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE, - CodeGenOpt::Level); + CodeGenOpt::Level, + bool DisableVerify = true); /// Target-Independent Code Generator Pass Configuration Options. diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 10cb45f..48665b7 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -16,7 +16,7 @@ namespace llvm { -// Invariant opcodes: All instruction sets have these as their low opcodes. +/// Invariant opcodes: All instruction sets have these as their low opcodes. namespace TargetOpcode { enum { PHI = 0, @@ -63,7 +63,7 @@ namespace TargetOpcode { /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. COPY_TO_REGCLASS = 10, - // DBG_VALUE - a mapping of the llvm.dbg.value intrinsic + /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic DBG_VALUE = 11 }; } // end namespace TargetOpcode diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 65b60f7..212cc93 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -587,6 +587,17 @@ public: return !hasFP(MF); } + /// canSimplifyCallFramePseudos - When possible, it's best to simplify the + /// call frame pseudo ops before doing frame index elimination. This is + /// possible only when frame index references between the pseudos won't + /// need adjusted for the call frame adjustments. Normally, that's true + /// if the function has a reserved call frame or a frame pointer. Some + /// targets (Thumb2, for example) may have more complicated criteria, + /// however, and can override this behavior. + virtual bool canSimplifyCallFramePseudos(MachineFunction &MF) const { + return hasReservedCallFrame(MF) || hasFP(MF); + } + /// hasReservedSpillSlot - Return true if target has reserved a spill slot in /// the stack frame of the given function for the specified register. e.g. On /// x86, if the frame register is required, the first fixed stack object is diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index 1738997..a409b62 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -26,6 +26,7 @@ namespace llvm { class AsmPrinter; class Module; + class MCAssembler; class MCAsmInfo; class MCAsmParser; class MCCodeEmitter; @@ -33,6 +34,7 @@ namespace llvm { class MCDisassembler; class MCInstPrinter; class MCStreamer; + class TargetAsmBackend; class TargetAsmLexer; class TargetAsmParser; class TargetMachine; @@ -63,6 +65,8 @@ namespace llvm { MCContext &Ctx, MCStreamer &Streamer, const MCAsmInfo *MAI); + typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T, + MCAssembler &A); typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P); @@ -72,7 +76,8 @@ namespace llvm { const MCAsmInfo &MAI, raw_ostream &O); typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, - TargetMachine &TM); + TargetMachine &TM, + MCContext &Ctx); private: /// Next - The next registered target in the linked list, maintained by the @@ -93,32 +98,35 @@ namespace llvm { bool HasJIT; AsmInfoCtorFnTy AsmInfoCtorFn; - + /// TargetMachineCtorFn - Construction function for this target's /// TargetMachine, if registered. TargetMachineCtorTy TargetMachineCtorFn; - /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, - /// if registered. - AsmPrinterCtorTy AsmPrinterCtorFn; + /// AsmBackendCtorFn - Construction function for this target's + /// TargetAsmBackend, if registered. + AsmBackendCtorTy AsmBackendCtorFn; /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer, /// if registered. AsmLexerCtorTy AsmLexerCtorFn; - + /// AsmParserCtorFn - Construction function for this target's /// TargetAsmParser, if registered. AsmParserCtorTy AsmParserCtorFn; - + + /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, + /// if registered. + AsmPrinterCtorTy AsmPrinterCtorFn; + /// MCDisassemblerCtorFn - Construction function for this target's /// MCDisassembler, if registered. MCDisassemblerCtorTy MCDisassemblerCtorFn; - - /// MCInstPrinterCtorFn - Construction function for this target's + /// MCInstPrinterCtorFn - Construction function for this target's /// MCInstPrinter, if registered. MCInstPrinterCtorTy MCInstPrinterCtorFn; - + /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter, /// if registered. CodeEmitterCtorTy CodeEmitterCtorFn; @@ -146,12 +154,18 @@ namespace llvm { /// hasTargetMachine - Check if this target supports code generation. bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } - /// hasAsmPrinter - Check if this target supports .s printing. - bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } + /// hasAsmBackend - Check if this target supports .o generation. + bool hasAsmBackend() const { return AsmBackendCtorFn != 0; } + + /// hasAsmLexer - Check if this target supports .s lexing. + bool hasAsmLexer() const { return AsmLexerCtorFn != 0; } /// hasAsmParser - Check if this target supports .s parsing. bool hasAsmParser() const { return AsmParserCtorFn != 0; } - + + /// hasAsmPrinter - Check if this target supports .s printing. + bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } + /// hasMCDisassembler - Check if this target has a disassembler. bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; } @@ -164,7 +178,7 @@ namespace llvm { /// @} /// @name Feature Constructors /// @{ - + /// createAsmInfo - Create a MCAsmInfo implementation for the specified /// target triple. /// @@ -177,7 +191,7 @@ namespace llvm { return 0; return AsmInfoCtorFn(*this, Triple); } - + /// createTargetMachine - Create a target specific machine implementation /// for the specified \arg Triple. /// @@ -192,14 +206,13 @@ namespace llvm { return TargetMachineCtorFn(*this, Triple, Features); } - /// createAsmPrinter - Create a target specific assembly printer pass. This - /// takes ownership of the MCContext and MCStreamer objects but not the MAI. - AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM, - MCContext &Ctx, MCStreamer &Streamer, - const MCAsmInfo *MAI) const { - if (!AsmPrinterCtorFn) + /// createAsmBackend - Create a target specific assembly parser. + /// + /// \arg Backend - The target independent assembler object. + TargetAsmBackend *createAsmBackend(MCAssembler &Backend) const { + if (!AsmBackendCtorFn) return 0; - return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI); + return AsmBackendCtorFn(*this, Backend); } /// createAsmLexer - Create a target specific assembly lexer. @@ -209,7 +222,7 @@ namespace llvm { return 0; return AsmLexerCtorFn(*this, MAI); } - + /// createAsmParser - Create a target specific assembly parser. /// /// \arg Parser - The target independent parser implementation to use for @@ -219,7 +232,17 @@ namespace llvm { return 0; return AsmParserCtorFn(*this, Parser); } - + + /// createAsmPrinter - Create a target specific assembly printer pass. This + /// takes ownership of the MCContext and MCStreamer objects but not the MAI. + AsmPrinter *createAsmPrinter(formatted_raw_ostream &OS, TargetMachine &TM, + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *MAI) const { + if (!AsmPrinterCtorFn) + return 0; + return AsmPrinterCtorFn(OS, TM, Ctx, Streamer, MAI); + } + const MCDisassembler *createMCDisassembler() const { if (!MCDisassemblerCtorFn) return 0; @@ -233,13 +256,13 @@ namespace llvm { return 0; return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, O); } - - + + /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const { + MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const { if (!CodeEmitterCtorFn) return 0; - return CodeEmitterCtorFn(*this, TM); + return CodeEmitterCtorFn(*this, TM, Ctx); } /// @} @@ -269,8 +292,8 @@ namespace llvm { return *this; } iterator operator++(int) { // Postincrement - iterator tmp = *this; - ++*this; + iterator tmp = *this; + ++*this; return tmp; } @@ -312,7 +335,7 @@ namespace llvm { /// RegisterTarget - Register the given target. Attempts to register a /// target which has already been registered will be ignored. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. @@ -320,7 +343,7 @@ namespace llvm { /// @param T - The target being registered. /// @param Name - The target name. This should be a static string. /// @param ShortDesc - A short target description. This should be a static - /// string. + /// string. /// @param TQualityFn - The triple match quality computation function for /// this target. /// @param HasJIT - Whether the target supports JIT code @@ -333,11 +356,11 @@ namespace llvm { /// RegisterAsmInfo - Register a MCAsmInfo implementation for the /// given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. - /// + /// /// @param T - The target being registered. /// @param Fn - A function to construct a MCAsmInfo for the target. static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) { @@ -345,76 +368,90 @@ namespace llvm { if (!T.AsmInfoCtorFn) T.AsmInfoCtorFn = Fn; } - + /// RegisterTargetMachine - Register a TargetMachine implementation for the /// given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. - /// + /// /// @param T - The target being registered. /// @param Fn - A function to construct a TargetMachine for the target. - static void RegisterTargetMachine(Target &T, + static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) { // Ignore duplicate registration. if (!T.TargetMachineCtorFn) T.TargetMachineCtorFn = Fn; } - /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given - /// target. - /// + /// RegisterAsmBackend - Register a TargetAsmBackend implementation for the + /// given target. + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmPrinter for the target. - static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { - // Ignore duplicate registration. - if (!T.AsmPrinterCtorFn) - T.AsmPrinterCtorFn = Fn; + /// @param Fn - A function to construct an AsmBackend for the target. + static void RegisterAsmBackend(Target &T, Target::AsmBackendCtorTy Fn) { + if (!T.AsmBackendCtorFn) + T.AsmBackendCtorFn = Fn; } /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the /// given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmPrinter for the target. + /// @param Fn - A function to construct an AsmLexer for the target. static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) { if (!T.AsmLexerCtorFn) T.AsmLexerCtorFn = Fn; } - + /// RegisterAsmParser - Register a TargetAsmParser implementation for the /// given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmPrinter for the target. + /// @param Fn - A function to construct an AsmParser for the target. static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) { if (!T.AsmParserCtorFn) T.AsmParserCtorFn = Fn; } - + + /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given + /// target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an AsmPrinter for the target. + static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { + // Ignore duplicate registration. + if (!T.AsmPrinterCtorFn) + T.AsmPrinterCtorFn = Fn; + } + /// RegisterMCDisassembler - Register a MCDisassembler implementation for /// the given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. /// @param Fn - A function to construct an MCDisassembler for the target. - static void RegisterMCDisassembler(Target &T, + static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn) { if (!T.MCDisassemblerCtorFn) T.MCDisassemblerCtorFn = Fn; @@ -422,7 +459,7 @@ namespace llvm { /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the /// given target. - /// + /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. @@ -434,7 +471,7 @@ namespace llvm { if (!T.MCInstPrinterCtorFn) T.MCInstPrinterCtorFn = Fn; } - + /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the /// given target. /// @@ -443,7 +480,7 @@ namespace llvm { /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmPrinter for the target. + /// @param Fn - A function to construct an MCCodeEmitter for the target. static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) { if (!T.CodeEmitterCtorFn) T.CodeEmitterCtorFn = Fn; @@ -497,7 +534,7 @@ namespace llvm { static const MCAsmInfo *Allocator(const Target &T, StringRef TT) { return new MCAsmInfoImpl(T, TT); } - + }; /// RegisterAsmInfoFn - Helper template for registering a target assembly info @@ -536,25 +573,22 @@ namespace llvm { } }; - /// RegisterAsmPrinter - Helper template for registering a target specific - /// assembly printer, for use in the target machine initialization - /// function. Usage: + /// RegisterAsmBackend - Helper template for registering a target specific + /// assembler backend. Usage: /// - /// extern "C" void LLVMInitializeFooAsmPrinter() { + /// extern "C" void LLVMInitializeFooAsmBackend() { /// extern Target TheFooTarget; - /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); + /// RegisterAsmBackend<FooAsmLexer> X(TheFooTarget); /// } - template<class AsmPrinterImpl> - struct RegisterAsmPrinter { - RegisterAsmPrinter(Target &T) { - TargetRegistry::RegisterAsmPrinter(T, &Allocator); + template<class AsmBackendImpl> + struct RegisterAsmBackend { + RegisterAsmBackend(Target &T) { + TargetRegistry::RegisterAsmBackend(T, &Allocator); } private: - static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM, - MCContext &Ctx, MCStreamer &Streamer, - const MCAsmInfo *MAI) { - return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI); + static TargetAsmBackend *Allocator(const Target &T, MCAssembler &Backend) { + return new AsmBackendImpl(T, Backend); } }; @@ -571,7 +605,7 @@ namespace llvm { RegisterAsmLexer(Target &T) { TargetRegistry::RegisterAsmLexer(T, &Allocator); } - + private: static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) { return new AsmLexerImpl(T, MAI); @@ -598,6 +632,28 @@ namespace llvm { } }; + /// RegisterAsmPrinter - Helper template for registering a target specific + /// assembly printer, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooAsmPrinter() { + /// extern Target TheFooTarget; + /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); + /// } + template<class AsmPrinterImpl> + struct RegisterAsmPrinter { + RegisterAsmPrinter(Target &T) { + TargetRegistry::RegisterAsmPrinter(T, &Allocator); + } + + private: + static AsmPrinter *Allocator(formatted_raw_ostream &OS, TargetMachine &TM, + MCContext &Ctx, MCStreamer &Streamer, + const MCAsmInfo *MAI) { + return new AsmPrinterImpl(OS, TM, Ctx, Streamer, MAI); + } + }; + /// RegisterCodeEmitter - Helper template for registering a target specific /// machine code emitter, for use in the target initialization /// function. Usage: @@ -613,8 +669,9 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM) { - return new CodeEmitterImpl(T, TM); + static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM, + MCContext &Ctx) { + return new CodeEmitterImpl(T, TM, Ctx); } }; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 4b72f81..4365d33 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -479,7 +479,6 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; -def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; def immAllOnesV: PatLeaf<(build_vector), [{ return ISD::isBuildVectorAllOnes(N); }]>; @@ -496,7 +495,7 @@ def immAllZerosV_bc: PatLeaf<(bitconvert), [{ // Other helper fragments. -def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; +def not : PatFrag<(ops node:$in), (xor node:$in, -1)>; def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>; def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 7159f86..6893bad 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -263,7 +263,7 @@ extern const PassInfo *const LCSSAID; // GVN - This pass performs global value numbering and redundant load // elimination cotemporaneously. // -FunctionPass *createGVNPass(bool NoPRE = false, bool NoLoads = false); +FunctionPass *createGVNPass(bool NoLoads = false); //===----------------------------------------------------------------------===// // diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 3f4571e..5279e96 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -102,6 +102,12 @@ void FindFunctionBackedges(const Function &F, // void RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum); +/// GetSuccessorNumber - Search for the specified successor of basic block BB +/// and return its position in the terminator instruction's list of +/// successors. It is an error to call this with a block that is not a +/// successor. +unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ); + /// isCriticalEdge - Return true if the specified edge is a critical edge. /// Critical edges are edges from a block with multiple successors to a block /// with multiple predecessors. diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h new file mode 100644 index 0000000..03716a8 --- /dev/null +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -0,0 +1,96 @@ +//===- BuildLibCalls.h - Utility builder for libcalls -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file exposes an interface to build some C language libcalls for +// optimization passes that need to call the various functions. +// +//===----------------------------------------------------------------------===// + +#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H +#define TRANSFORMS_UTILS_BUILDLIBCALLS_H + +#include "llvm/Support/IRBuilder.h" + +namespace llvm { + class Value; + class TargetData; + + /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. + Value *CastToCStr(Value *V, IRBuilder<> &B); + + /// EmitStrLen - Emit a call to the strlen function to the builder, for the + /// specified pointer. Ptr is required to be some pointer type, and the + /// return value has 'intptr_t' type. + Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD); + + /// EmitStrChr - Emit a call to the strchr function to the builder, for the + /// specified pointer and character. Ptr is required to be some pointer type, + /// and the return value has 'i8*' type. + Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD); + + /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the + /// specified pointer arguments. + Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, + const TargetData *TD); + + /// EmitMemCpy - Emit a call to the memcpy function to the builder. This + /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. + Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, + unsigned Align, IRBuilder<> &B, const TargetData *TD); + + /// EmitMemMove - Emit a call to the memmove function to the builder. This + /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. + Value *EmitMemMove(Value *Dst, Value *Src, Value *Len, + unsigned Align, IRBuilder<> &B, const TargetData *TD); + + /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is + /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. + Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, + const TargetData *TD); + + /// EmitMemCmp - Emit a call to the memcmp function. + Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, + const TargetData *TD); + + /// EmitMemSet - Emit a call to the memset function + Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, IRBuilder<> &B, + const TargetData *TD); + + /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' + /// (e.g. 'floor'). This function is known to take a single of type matching + /// 'Op' and returns one value with the same type. If 'Op' is a long double, + /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' + /// suffix. + Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B, + const AttrListPtr &Attrs); + + /// EmitPutChar - Emit a call to the putchar function. This assumes that Char + /// is an integer. + Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD); + + /// EmitPutS - Emit a call to the puts function. This assumes that Str is + /// some pointer. + void EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD); + + /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is + /// an i32, and File is a pointer to FILE. + void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, + const TargetData *TD); + + /// EmitFPutS - Emit a call to the puts function. Str is required to be a + /// pointer and File is a pointer to FILE. + void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD); + + /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is + /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. + void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, + const TargetData *TD); +} + +#endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index bc319c6..d09913a 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -82,13 +82,14 @@ public: IntegerTyID, ///< 8: Arbitrary bit width integers FunctionTyID, ///< 9: Functions StructTyID, ///< 10: Structures - ArrayTyID, ///< 11: Arrays - PointerTyID, ///< 12: Pointers - OpaqueTyID, ///< 13: Opaque: type with unknown structure - VectorTyID, ///< 14: SIMD 'packed' format, or other vector type + UnionTyID, ///< 11: Unions + ArrayTyID, ///< 12: Arrays + PointerTyID, ///< 13: Pointers + OpaqueTyID, ///< 14: Opaque: type with unknown structure + VectorTyID, ///< 15: SIMD 'packed' format, or other vector type NumTypeIDs, // Must remain as last defined ID - LastPrimitiveTyID = LabelTyID, + LastPrimitiveTyID = MetadataTyID, FirstDerivedTyID = IntegerTyID }; @@ -181,6 +182,9 @@ public: // are defined in private classes defined in Type.cpp for primitive types. // + /// getDescription - Return the string representation of the type. + std::string getDescription() const; + /// getTypeID - Return the type id for the type. This will return one /// of the TypeID enum elements defined above. /// @@ -204,55 +208,60 @@ public: /// isPPC_FP128Ty - Return true if this is powerpc long double. bool isPPC_FP128Ty() const { return ID == PPC_FP128TyID; } + /// isFloatingPointTy - Return true if this is one of the five floating point + /// types + bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID || + ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; } + + /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP. + /// + bool isFPOrFPVectorTy() const; + /// isLabelTy - Return true if this is 'label'. bool isLabelTy() const { return ID == LabelTyID; } /// isMetadataTy - Return true if this is 'metadata'. bool isMetadataTy() const { return ID == MetadataTyID; } - /// getDescription - Return the string representation of the type. - std::string getDescription() const; - - /// isInteger - True if this is an instance of IntegerType. + /// isIntegerTy - True if this is an instance of IntegerType. /// - bool isInteger() const { return ID == IntegerTyID; } + bool isIntegerTy() const { return ID == IntegerTyID; } - /// isInteger - Return true if this is an IntegerType of the specified width. - bool isInteger(unsigned Bitwidth) const; + /// isIntegerTy - Return true if this is an IntegerType of the given width. + bool isIntegerTy(unsigned Bitwidth) const; - /// isIntOrIntVector - Return true if this is an integer type or a vector of + /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of /// integer types. /// - bool isIntOrIntVector() const; + bool isIntOrIntVectorTy() const; - /// isFloatingPoint - Return true if this is one of the five floating point - /// types - bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID || - ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; } + /// isFunctionTy - True if this is an instance of FunctionType. + /// + bool isFunctionTy() const { return ID == FunctionTyID; } - /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types. + /// isStructTy - True if this is an instance of StructType. /// - bool isFPOrFPVector() const; - - /// isFunction - True if this is an instance of FunctionType. + bool isStructTy() const { return ID == StructTyID; } + + /// isUnionTy - True if this is an instance of UnionType. /// - bool isFunction() const { return ID == FunctionTyID; } + bool isUnionTy() const { return ID == UnionTyID; } - /// isStruct - True if this is an instance of StructType. + /// isArrayTy - True if this is an instance of ArrayType. /// - bool isStruct() const { return ID == StructTyID; } + bool isArrayTy() const { return ID == ArrayTyID; } - /// isArray - True if this is an instance of ArrayType. + /// isPointerTy - True if this is an instance of PointerType. /// - bool isArray() const { return ID == ArrayTyID; } + bool isPointerTy() const { return ID == PointerTyID; } - /// isPointer - True if this is an instance of PointerType. + /// isOpaqueTy - True if this is an instance of OpaqueType. /// - bool isPointer() const { return ID == PointerTyID; } + bool isOpaqueTy() const { return ID == OpaqueTyID; } - /// isVector - True if this is an instance of VectorType. + /// isVectorTy - True if this is an instance of VectorType. /// - bool isVector() const { return ID == VectorTyID; } + bool isVectorTy() const { return ID == VectorTyID; } /// isAbstract - True if the type is either an Opaque type, or is a derived /// type that includes an opaque type somewhere in it. @@ -297,7 +306,7 @@ public: /// does not include vector types. /// inline bool isAggregateType() const { - return ID == StructTyID || ID == ArrayTyID; + return ID == StructTyID || ID == ArrayTyID || ID == UnionTyID; } /// isSized - Return true if it makes sense to take the size of this type. To @@ -306,11 +315,12 @@ public: /// bool isSized() const { // If it's a primitive, it is always sized. - if (ID == IntegerTyID || isFloatingPoint() || ID == PointerTyID) + if (ID == IntegerTyID || isFloatingPointTy() || ID == PointerTyID) return true; // If it is not something that can have a size (e.g. a function or label), // it doesn't have a size. - if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID) + if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID && + ID != UnionTyID) return false; // If it is something that can have a size and it's concrete, it definitely // has a size, otherwise we have to try harder to decide. diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 9045906..d06cbc0 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -215,6 +215,7 @@ public: ConstantFPVal, // This is an instance of ConstantFP ConstantArrayVal, // This is an instance of ConstantArray ConstantStructVal, // This is an instance of ConstantStruct + ConstantUnionVal, // This is an instance of ConstantUnion ConstantVectorVal, // This is an instance of ConstantVector ConstantPointerNullVal, // This is an instance of ConstantPointerNull MDNodeVal, // This is an instance of MDNode |