diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 9e4b41b2983b..43fbd65eccb8 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -1,3886 +1,3890 @@ /*===-- llvm-c/Core.h - Core Library C Interface ------------------*- C -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| |* This file is distributed under the University of Illinois Open Source *| |* License. See LICENSE.TXT for details. *| |* *| |*===----------------------------------------------------------------------===*| |* *| |* This header declares the C interface to libLLVMCore.a, which implements *| |* the LLVM intermediate representation. *| |* *| \*===----------------------------------------------------------------------===*/ #ifndef LLVM_C_CORE_H #define LLVM_C_CORE_H #include "llvm-c/ErrorHandling.h" #include "llvm-c/Types.h" #ifdef __cplusplus extern "C" { #endif /** * @defgroup LLVMC LLVM-C: C interface to LLVM * * This module exposes parts of the LLVM library as a C API. * * @{ */ /** * @defgroup LLVMCTransforms Transforms */ /** * @defgroup LLVMCCore Core * * This modules provide an interface to libLLVMCore, which implements * the LLVM intermediate representation as well as other related types * and utilities. * * Many exotic languages can interoperate with C code but have a harder time * with C++ due to name mangling. So in addition to C, this interface enables * tools written in such languages. * * @{ */ /** * @defgroup LLVMCCoreTypes Types and Enumerations * * @{ */ /// External users depend on the following values being stable. It is not safe /// to reorder them. typedef enum { /* Terminator Instructions */ LLVMRet = 1, LLVMBr = 2, LLVMSwitch = 3, LLVMIndirectBr = 4, LLVMInvoke = 5, /* removed 6 due to API changes */ LLVMUnreachable = 7, /* Standard Unary Operators */ LLVMFNeg = 66, /* 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, LLVMAddrSpaceCast = 60, /* Other Operators */ LLVMICmp = 42, LLVMFCmp = 43, LLVMPHI = 44, LLVMCall = 45, LLVMSelect = 46, LLVMUserOp1 = 47, LLVMUserOp2 = 48, LLVMVAArg = 49, LLVMExtractElement = 50, LLVMInsertElement = 51, LLVMShuffleVector = 52, LLVMExtractValue = 53, LLVMInsertValue = 54, /* Atomic operators */ LLVMFence = 55, LLVMAtomicCmpXchg = 56, LLVMAtomicRMW = 57, /* Exception Handling Operators */ LLVMResume = 58, LLVMLandingPad = 59, LLVMCleanupRet = 61, LLVMCatchRet = 62, LLVMCatchPad = 63, LLVMCleanupPad = 64, LLVMCatchSwitch = 65 } LLVMOpcode; typedef enum { LLVMVoidTypeKind, /**< type with no size */ LLVMHalfTypeKind, /**< 16 bit floating point type */ LLVMFloatTypeKind, /**< 32 bit floating point type */ LLVMDoubleTypeKind, /**< 64 bit floating point type */ LLVMX86_FP80TypeKind, /**< 80 bit floating point type (X87) */ LLVMFP128TypeKind, /**< 128 bit floating point type (112-bit mantissa)*/ LLVMPPC_FP128TypeKind, /**< 128 bit floating point type (two 64-bits) */ LLVMLabelTypeKind, /**< Labels */ LLVMIntegerTypeKind, /**< Arbitrary bit width integers */ LLVMFunctionTypeKind, /**< Functions */ LLVMStructTypeKind, /**< Structures */ LLVMArrayTypeKind, /**< Arrays */ LLVMPointerTypeKind, /**< Pointers */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ LLVMMetadataTypeKind, /**< Metadata */ LLVMX86_MMXTypeKind, /**< X86 MMX */ LLVMTokenTypeKind /**< Tokens */ } LLVMTypeKind; typedef enum { LLVMExternalLinkage, /**< Externally visible function */ LLVMAvailableExternallyLinkage, LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/ LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something equivalent. */ LLVMLinkOnceODRAutoHideLinkage, /**< Obsolete */ LLVMWeakAnyLinkage, /**< Keep one copy of function when linking (weak) */ LLVMWeakODRLinkage, /**< Same, but only replaced by something equivalent. */ LLVMAppendingLinkage, /**< Special purpose, only applies to global arrays */ LLVMInternalLinkage, /**< Rename collisions when linking (static functions) */ LLVMPrivateLinkage, /**< Like Internal, but omit from symbol table */ LLVMDLLImportLinkage, /**< Obsolete */ LLVMDLLExportLinkage, /**< Obsolete */ LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */ LLVMGhostLinkage, /**< Obsolete */ LLVMCommonLinkage, /**< Tentative definitions */ LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */ LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */ } LLVMLinkage; typedef enum { LLVMDefaultVisibility, /**< The GV is visible */ LLVMHiddenVisibility, /**< The GV is hidden */ LLVMProtectedVisibility /**< The GV is protected */ } LLVMVisibility; typedef enum { LLVMNoUnnamedAddr, /**< Address of the GV is significant. */ LLVMLocalUnnamedAddr, /**< Address of the GV is locally insignificant. */ LLVMGlobalUnnamedAddr /**< Address of the GV is globally insignificant. */ } LLVMUnnamedAddr; typedef enum { LLVMDefaultStorageClass = 0, LLVMDLLImportStorageClass = 1, /**< Function to be imported from DLL. */ LLVMDLLExportStorageClass = 2 /**< Function to be accessible from DLL. */ } LLVMDLLStorageClass; typedef enum { LLVMCCallConv = 0, LLVMFastCallConv = 8, LLVMColdCallConv = 9, LLVMGHCCallConv = 10, LLVMHiPECallConv = 11, LLVMWebKitJSCallConv = 12, LLVMAnyRegCallConv = 13, LLVMPreserveMostCallConv = 14, LLVMPreserveAllCallConv = 15, LLVMSwiftCallConv = 16, LLVMCXXFASTTLSCallConv = 17, LLVMX86StdcallCallConv = 64, LLVMX86FastcallCallConv = 65, LLVMARMAPCSCallConv = 66, LLVMARMAAPCSCallConv = 67, LLVMARMAAPCSVFPCallConv = 68, LLVMMSP430INTRCallConv = 69, LLVMX86ThisCallCallConv = 70, LLVMPTXKernelCallConv = 71, LLVMPTXDeviceCallConv = 72, LLVMSPIRFUNCCallConv = 75, LLVMSPIRKERNELCallConv = 76, LLVMIntelOCLBICallConv = 77, LLVMX8664SysVCallConv = 78, LLVMWin64CallConv = 79, LLVMX86VectorCallCallConv = 80, LLVMHHVMCallConv = 81, LLVMHHVMCCallConv = 82, LLVMX86INTRCallConv = 83, LLVMAVRINTRCallConv = 84, LLVMAVRSIGNALCallConv = 85, LLVMAVRBUILTINCallConv = 86, LLVMAMDGPUVSCallConv = 87, LLVMAMDGPUGSCallConv = 88, LLVMAMDGPUPSCallConv = 89, LLVMAMDGPUCSCallConv = 90, LLVMAMDGPUKERNELCallConv = 91, LLVMX86RegCallCallConv = 92, LLVMAMDGPUHSCallConv = 93, LLVMMSP430BUILTINCallConv = 94, LLVMAMDGPULSCallConv = 95, LLVMAMDGPUESCallConv = 96 } LLVMCallConv; typedef enum { LLVMArgumentValueKind, LLVMBasicBlockValueKind, LLVMMemoryUseValueKind, LLVMMemoryDefValueKind, LLVMMemoryPhiValueKind, LLVMFunctionValueKind, LLVMGlobalAliasValueKind, LLVMGlobalIFuncValueKind, LLVMGlobalVariableValueKind, LLVMBlockAddressValueKind, LLVMConstantExprValueKind, LLVMConstantArrayValueKind, LLVMConstantStructValueKind, LLVMConstantVectorValueKind, LLVMUndefValueValueKind, LLVMConstantAggregateZeroValueKind, LLVMConstantDataArrayValueKind, LLVMConstantDataVectorValueKind, LLVMConstantIntValueKind, LLVMConstantFPValueKind, LLVMConstantPointerNullValueKind, LLVMConstantTokenNoneValueKind, LLVMMetadataAsValueValueKind, LLVMInlineAsmValueKind, LLVMInstructionValueKind, } LLVMValueKind; typedef enum { LLVMIntEQ = 32, /**< equal */ LLVMIntNE, /**< not equal */ LLVMIntUGT, /**< unsigned greater than */ LLVMIntUGE, /**< unsigned greater or equal */ LLVMIntULT, /**< unsigned less than */ LLVMIntULE, /**< unsigned less or equal */ LLVMIntSGT, /**< signed greater than */ LLVMIntSGE, /**< signed greater or equal */ LLVMIntSLT, /**< signed less than */ LLVMIntSLE /**< signed less or equal */ } LLVMIntPredicate; typedef enum { LLVMRealPredicateFalse, /**< Always false (always folded) */ LLVMRealOEQ, /**< True if ordered and equal */ LLVMRealOGT, /**< True if ordered and greater than */ LLVMRealOGE, /**< True if ordered and greater than or equal */ LLVMRealOLT, /**< True if ordered and less than */ LLVMRealOLE, /**< True if ordered and less than or equal */ LLVMRealONE, /**< True if ordered and operands are unequal */ LLVMRealORD, /**< True if ordered (no nans) */ LLVMRealUNO, /**< True if unordered: isnan(X) | isnan(Y) */ LLVMRealUEQ, /**< True if unordered or equal */ LLVMRealUGT, /**< True if unordered or greater than */ LLVMRealUGE, /**< True if unordered, greater than, or equal */ LLVMRealULT, /**< True if unordered or less than */ LLVMRealULE, /**< True if unordered, less than, or equal */ LLVMRealUNE, /**< True if unordered or not equal */ LLVMRealPredicateTrue /**< Always true (always folded) */ } LLVMRealPredicate; typedef enum { LLVMLandingPadCatch, /**< A catch clause */ LLVMLandingPadFilter /**< A filter clause */ } LLVMLandingPadClauseTy; typedef enum { LLVMNotThreadLocal = 0, LLVMGeneralDynamicTLSModel, LLVMLocalDynamicTLSModel, LLVMInitialExecTLSModel, LLVMLocalExecTLSModel } LLVMThreadLocalMode; typedef enum { LLVMAtomicOrderingNotAtomic = 0, /**< A load or store which is not atomic */ LLVMAtomicOrderingUnordered = 1, /**< Lowest level of atomicity, guarantees somewhat sane results, lock free. */ LLVMAtomicOrderingMonotonic = 2, /**< guarantees that if you take all the operations affecting a specific address, a consistent ordering exists */ LLVMAtomicOrderingAcquire = 4, /**< Acquire provides a barrier of the sort necessary to acquire a lock to access other memory with normal loads and stores. */ LLVMAtomicOrderingRelease = 5, /**< Release is similar to Acquire, but with a barrier of the sort necessary to release a lock. */ LLVMAtomicOrderingAcquireRelease = 6, /**< provides both an Acquire and a Release barrier (for fences and operations which both read and write memory). */ LLVMAtomicOrderingSequentiallyConsistent = 7 /**< provides Acquire semantics for loads and Release semantics for stores. Additionally, it guarantees that a total ordering exists between all SequentiallyConsistent operations. */ } LLVMAtomicOrdering; typedef enum { LLVMAtomicRMWBinOpXchg, /**< Set the new value and return the one old */ LLVMAtomicRMWBinOpAdd, /**< Add a value and return the old one */ LLVMAtomicRMWBinOpSub, /**< Subtract a value and return the old one */ LLVMAtomicRMWBinOpAnd, /**< And a value and return the old one */ LLVMAtomicRMWBinOpNand, /**< Not-And a value and return the old one */ LLVMAtomicRMWBinOpOr, /**< OR a value and return the old one */ LLVMAtomicRMWBinOpXor, /**< Xor a value and return the old one */ LLVMAtomicRMWBinOpMax, /**< Sets the value if it's greater than the original using a signed comparison and return the old one */ LLVMAtomicRMWBinOpMin, /**< Sets the value if it's Smaller than the original using a signed comparison and return the old one */ LLVMAtomicRMWBinOpUMax, /**< Sets the value if it's greater than the original using an unsigned comparison and return the old one */ LLVMAtomicRMWBinOpUMin /**< Sets the value if it's greater than the original using an unsigned comparison and return the old one */ } LLVMAtomicRMWBinOp; typedef enum { LLVMDSError, LLVMDSWarning, LLVMDSRemark, LLVMDSNote } LLVMDiagnosticSeverity; typedef enum { LLVMInlineAsmDialectATT, LLVMInlineAsmDialectIntel } LLVMInlineAsmDialect; typedef enum { /** * Emits an error if two values disagree, otherwise the resulting value is * that of the operands. * * @see Module::ModFlagBehavior::Error */ LLVMModuleFlagBehaviorError, /** * Emits a warning if two values disagree. The result value will be the * operand for the flag from the first module being linked. * * @see Module::ModFlagBehavior::Warning */ LLVMModuleFlagBehaviorWarning, /** * Adds a requirement that another module flag be present and have a * specified value after linking is performed. The value must be a metadata * pair, where the first element of the pair is the ID of the module flag * to be restricted, and the second element of the pair is the value the * module flag should be restricted to. This behavior can be used to * restrict the allowable results (via triggering of an error) of linking * IDs with the **Override** behavior. * * @see Module::ModFlagBehavior::Require */ LLVMModuleFlagBehaviorRequire, /** * Uses the specified value, regardless of the behavior or value of the * other module. If both modules specify **Override**, but the values * differ, an error will be emitted. * * @see Module::ModFlagBehavior::Override */ LLVMModuleFlagBehaviorOverride, /** * Appends the two values, which are required to be metadata nodes. * * @see Module::ModFlagBehavior::Append */ LLVMModuleFlagBehaviorAppend, /** * Appends the two values, which are required to be metadata * nodes. However, duplicate entries in the second list are dropped * during the append operation. * * @see Module::ModFlagBehavior::AppendUnique */ LLVMModuleFlagBehaviorAppendUnique, } LLVMModuleFlagBehavior; /** * Attribute index are either LLVMAttributeReturnIndex, * LLVMAttributeFunctionIndex or a parameter number from 1 to N. */ enum { LLVMAttributeReturnIndex = 0U, // ISO C restricts enumerator values to range of 'int' // (4294967295 is too large) // LLVMAttributeFunctionIndex = ~0U, LLVMAttributeFunctionIndex = -1, }; typedef unsigned LLVMAttributeIndex; /** * @} */ void LLVMInitializeCore(LLVMPassRegistryRef R); /** Deallocate and destroy all ManagedStatic variables. @see llvm::llvm_shutdown @see ManagedStatic */ void LLVMShutdown(void); /*===-- Error handling ----------------------------------------------------===*/ char *LLVMCreateMessage(const char *Message); void LLVMDisposeMessage(char *Message); /** * @defgroup LLVMCCoreContext Contexts * * Contexts are execution states for the core LLVM IR system. * * Most types are tied to a context instance. Multiple contexts can * exist simultaneously. A single context is not thread safe. However, * different contexts can execute on different threads simultaneously. * * @{ */ typedef void (*LLVMDiagnosticHandler)(LLVMDiagnosticInfoRef, void *); typedef void (*LLVMYieldCallback)(LLVMContextRef, void *); /** * Create a new context. * * Every call to this function should be paired with a call to * LLVMContextDispose() or the context will leak memory. */ LLVMContextRef LLVMContextCreate(void); /** * Obtain the global context instance. */ LLVMContextRef LLVMGetGlobalContext(void); /** * Set the diagnostic handler for this context. */ void LLVMContextSetDiagnosticHandler(LLVMContextRef C, LLVMDiagnosticHandler Handler, void *DiagnosticContext); /** * Get the diagnostic handler of this context. */ LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C); /** * Get the diagnostic context of this context. */ void *LLVMContextGetDiagnosticContext(LLVMContextRef C); /** * Set the yield callback function for this context. * * @see LLVMContext::setYieldCallback() */ void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback, void *OpaqueHandle); /** * Retrieve whether the given context is set to discard all value names. * * @see LLVMContext::shouldDiscardValueNames() */ LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C); /** * Set whether the given context discards all value names. * * If true, only the names of GlobalValue objects will be available in the IR. * This can be used to save memory and runtime, especially in release mode. * * @see LLVMContext::setDiscardValueNames() */ void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard); /** * Destroy a context instance. * * This should be called for every call to LLVMContextCreate() or memory * will be leaked. */ void LLVMContextDispose(LLVMContextRef C); /** * Return a string representation of the DiagnosticInfo. Use * LLVMDisposeMessage to free the string. * * @see DiagnosticInfo::print() */ char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI); /** * Return an enum LLVMDiagnosticSeverity. * * @see DiagnosticInfo::getSeverity() */ LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI); unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name, unsigned SLen); unsigned LLVMGetMDKindID(const char *Name, unsigned SLen); /** * Return an unique id given the name of a enum attribute, * or 0 if no attribute by that name exists. * * See http://llvm.org/docs/LangRef.html#parameter-attributes * and http://llvm.org/docs/LangRef.html#function-attributes * for the list of available attributes. * * NB: Attribute names and/or id are subject to change without * going through the C API deprecation cycle. */ unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen); unsigned LLVMGetLastEnumAttributeKind(void); /** * Create an enum attribute. */ LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID, uint64_t Val); /** * Get the unique id corresponding to the enum attribute * passed as argument. */ unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A); /** * Get the enum attribute's value. 0 is returned if none exists. */ uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A); /** * Create a string attribute. */ LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C, const char *K, unsigned KLength, const char *V, unsigned VLength); /** * Get the string attribute's kind. */ const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, unsigned *Length); /** * Get the string attribute's value. */ const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length); /** * Check for the different types of attributes. */ LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A); LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A); /** * @} */ /** * @defgroup LLVMCCoreModule Modules * * Modules represent the top-level structure in an LLVM program. An LLVM * module is effectively a translation unit or a collection of * translation units merged together. * * @{ */ /** * Create a new, empty module in the global context. * * This is equivalent to calling LLVMModuleCreateWithNameInContext with * LLVMGetGlobalContext() as the context parameter. * * Every invocation should be paired with LLVMDisposeModule() or memory * will be leaked. */ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID); /** * Create a new, empty module in a specific context. * * Every invocation should be paired with LLVMDisposeModule() or memory * will be leaked. */ LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, LLVMContextRef C); /** * Return an exact copy of the specified module. */ LLVMModuleRef LLVMCloneModule(LLVMModuleRef M); /** * Destroy a module instance. * * This must be called for every created module or memory will be * leaked. */ void LLVMDisposeModule(LLVMModuleRef M); /** * Obtain the identifier of a module. * * @param M Module to obtain identifier of * @param Len Out parameter which holds the length of the returned string. * @return The identifier of M. * @see Module::getModuleIdentifier() */ const char *LLVMGetModuleIdentifier(LLVMModuleRef M, size_t *Len); /** * Set the identifier of a module to a string Ident with length Len. * * @param M The module to set identifier * @param Ident The string to set M's identifier to * @param Len Length of Ident * @see Module::setModuleIdentifier() */ void LLVMSetModuleIdentifier(LLVMModuleRef M, const char *Ident, size_t Len); /** * Obtain the module's original source file name. * * @param M Module to obtain the name of * @param Len Out parameter which holds the length of the returned string * @return The original source file name of M * @see Module::getSourceFileName() */ const char *LLVMGetSourceFileName(LLVMModuleRef M, size_t *Len); /** * Set the original source file name of a module to a string Name with length * Len. * * @param M The module to set the source file name of * @param Name The string to set M's source file name to * @param Len Length of Name * @see Module::setSourceFileName() */ void LLVMSetSourceFileName(LLVMModuleRef M, const char *Name, size_t Len); /** * Obtain the data layout for a module. * * @see Module::getDataLayoutStr() * * LLVMGetDataLayout is DEPRECATED, as the name is not only incorrect, * but match the name of another method on the module. Prefer the use * of LLVMGetDataLayoutStr, which is not ambiguous. */ const char *LLVMGetDataLayoutStr(LLVMModuleRef M); const char *LLVMGetDataLayout(LLVMModuleRef M); /** * Set the data layout for a module. * * @see Module::setDataLayout() */ void LLVMSetDataLayout(LLVMModuleRef M, const char *DataLayoutStr); /** * Obtain the target triple for a module. * * @see Module::getTargetTriple() */ const char *LLVMGetTarget(LLVMModuleRef M); /** * Set the target triple for a module. * * @see Module::setTargetTriple() */ void LLVMSetTarget(LLVMModuleRef M, const char *Triple); /** * Returns the module flags as an array of flag-key-value triples. The caller * is responsible for freeing this array by calling * \c LLVMDisposeModuleFlagsMetadata. * * @see Module::getModuleFlagsMetadata() */ LLVMModuleFlagEntry *LLVMCopyModuleFlagsMetadata(LLVMModuleRef M, size_t *Len); /** * Destroys module flags metadata entries. */ void LLVMDisposeModuleFlagsMetadata(LLVMModuleFlagEntry *Entries); /** * Returns the flag behavior for a module flag entry at a specific index. * * @see Module::ModuleFlagEntry::Behavior */ LLVMModuleFlagBehavior LLVMModuleFlagEntriesGetFlagBehavior(LLVMModuleFlagEntry *Entries, unsigned Index); /** * Returns the key for a module flag entry at a specific index. * * @see Module::ModuleFlagEntry::Key */ const char *LLVMModuleFlagEntriesGetKey(LLVMModuleFlagEntry *Entries, unsigned Index, size_t *Len); /** * Returns the metadata for a module flag entry at a specific index. * * @see Module::ModuleFlagEntry::Val */ LLVMMetadataRef LLVMModuleFlagEntriesGetMetadata(LLVMModuleFlagEntry *Entries, unsigned Index); /** * Add a module-level flag to the module-level flags metadata if it doesn't * already exist. * * @see Module::getModuleFlag() */ LLVMMetadataRef LLVMGetModuleFlag(LLVMModuleRef M, const char *Key, size_t KeyLen); /** * Add a module-level flag to the module-level flags metadata if it doesn't * already exist. * * @see Module::addModuleFlag() */ void LLVMAddModuleFlag(LLVMModuleRef M, LLVMModuleFlagBehavior Behavior, const char *Key, size_t KeyLen, LLVMMetadataRef Val); /** * Dump a representation of a module to stderr. * * @see Module::dump() */ void LLVMDumpModule(LLVMModuleRef M); /** * Print a representation of a module to a file. The ErrorMessage needs to be * disposed with LLVMDisposeMessage. Returns 0 on success, 1 otherwise. * * @see Module::print() */ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, char **ErrorMessage); /** * Return a string representation of the module. Use * LLVMDisposeMessage to free the string. * * @see Module::print() */ char *LLVMPrintModuleToString(LLVMModuleRef M); /** * Get inline assembly for a module. * * @see Module::getModuleInlineAsm() */ const char *LLVMGetModuleInlineAsm(LLVMModuleRef M, size_t *Len); /** * Set inline assembly for a module. * * @see Module::setModuleInlineAsm() */ void LLVMSetModuleInlineAsm2(LLVMModuleRef M, const char *Asm, size_t Len); /** * Append inline assembly to a module. * * @see Module::appendModuleInlineAsm() */ void LLVMAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm, size_t Len); /** * Create the specified uniqued inline asm string. * * @see InlineAsm::get() */ LLVMValueRef LLVMGetInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringSize, char *Constraints, size_t ConstraintsSize, LLVMBool HasSideEffects, LLVMBool IsAlignStack, LLVMInlineAsmDialect Dialect); /** * Obtain the context to which this module is associated. * * @see Module::getContext() */ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M); /** * Obtain a Type from a module by its registered name. */ LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name); /** * Obtain an iterator to the first NamedMDNode in a Module. * * @see llvm::Module::named_metadata_begin() */ LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M); /** * Obtain an iterator to the last NamedMDNode in a Module. * * @see llvm::Module::named_metadata_end() */ LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M); /** * Advance a NamedMDNode iterator to the next NamedMDNode. * * Returns NULL if the iterator was already at the end and there are no more * named metadata nodes. */ LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NamedMDNode); /** * Decrement a NamedMDNode iterator to the previous NamedMDNode. * * Returns NULL if the iterator was already at the beginning and there are * no previous named metadata nodes. */ LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NamedMDNode); /** * Retrieve a NamedMDNode with the given name, returning NULL if no such * node exists. * * @see llvm::Module::getNamedMetadata() */ LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M, const char *Name, size_t NameLen); /** * Retrieve a NamedMDNode with the given name, creating a new node if no such * node exists. * * @see llvm::Module::getOrInsertNamedMetadata() */ LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M, const char *Name, size_t NameLen); /** * Retrieve the name of a NamedMDNode. * * @see llvm::NamedMDNode::getName() */ const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NamedMD, size_t *NameLen); /** * Obtain the number of operands for named metadata in a module. * * @see llvm::Module::getNamedMetadata() */ unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name); /** * Obtain the named metadata operands for a module. * * The passed LLVMValueRef pointer should refer to an array of * LLVMValueRef at least LLVMGetNamedMetadataNumOperands long. This * array will be populated with the LLVMValueRef instances. Each * instance corresponds to a llvm::MDNode. * * @see llvm::Module::getNamedMetadata() * @see llvm::MDNode::getOperand() */ void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char *Name, LLVMValueRef *Dest); /** * Add an operand to named metadata. * * @see llvm::Module::getNamedMetadata() * @see llvm::MDNode::addOperand() */ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char *Name, LLVMValueRef Val); /** * Return the directory of the debug location for this value, which must be * an llvm::Instruction, llvm::GlobalVariable, or llvm::Function. * * @see llvm::Instruction::getDebugLoc() * @see llvm::GlobalVariable::getDebugInfo() * @see llvm::Function::getSubprogram() */ const char *LLVMGetDebugLocDirectory(LLVMValueRef Val, unsigned *Length); /** * Return the filename of the debug location for this value, which must be * an llvm::Instruction, llvm::GlobalVariable, or llvm::Function. * * @see llvm::Instruction::getDebugLoc() * @see llvm::GlobalVariable::getDebugInfo() * @see llvm::Function::getSubprogram() */ const char *LLVMGetDebugLocFilename(LLVMValueRef Val, unsigned *Length); /** * Return the line number of the debug location for this value, which must be * an llvm::Instruction, llvm::GlobalVariable, or llvm::Function. * * @see llvm::Instruction::getDebugLoc() * @see llvm::GlobalVariable::getDebugInfo() * @see llvm::Function::getSubprogram() */ unsigned LLVMGetDebugLocLine(LLVMValueRef Val); /** * Return the column number of the debug location for this value, which must be * an llvm::Instruction. * * @see llvm::Instruction::getDebugLoc() */ unsigned LLVMGetDebugLocColumn(LLVMValueRef Val); /** * Add a function to a module under a specified name. * * @see llvm::Function::Create() */ LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy); /** * Obtain a Function value from a Module by its name. * * The returned value corresponds to a llvm::Function value. * * @see llvm::Module::getFunction() */ LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name); /** * Obtain an iterator to the first Function in a Module. * * @see llvm::Module::begin() */ LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M); /** * Obtain an iterator to the last Function in a Module. * * @see llvm::Module::end() */ LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M); /** * Advance a Function iterator to the next Function. * * Returns NULL if the iterator was already at the end and there are no more * functions. */ LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn); /** * Decrement a Function iterator to the previous Function. * * Returns NULL if the iterator was already at the beginning and there are * no previous functions. */ LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn); /** Deprecated: Use LLVMSetModuleInlineAsm2 instead. */ void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm); /** * @} */ /** * @defgroup LLVMCCoreType Types * * Types represent the type of a value. * * Types are associated with a context instance. The context internally * deduplicates types so there is only 1 instance of a specific type * alive at a time. In other words, a unique type is shared among all * consumers within a context. * * A Type in the C API corresponds to llvm::Type. * * Types have the following hierarchy: * * types: * integer type * real type * function type * sequence types: * array type * pointer type * vector type * void type * label type * opaque type * * @{ */ /** * Obtain the enumerated type of a Type instance. * * @see llvm::Type:getTypeID() */ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty); /** * Whether the type has a known size. * * Things that don't have a size are abstract types, labels, and void.a * * @see llvm::Type::isSized() */ LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty); /** * Obtain the context to which this type instance is associated. * * @see llvm::Type::getContext() */ LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty); /** * Dump a representation of a type to stderr. * * @see llvm::Type::dump() */ void LLVMDumpType(LLVMTypeRef Val); /** * Return a string representation of the type. Use * LLVMDisposeMessage to free the string. * * @see llvm::Type::print() */ char *LLVMPrintTypeToString(LLVMTypeRef Val); /** * @defgroup LLVMCCoreTypeInt Integer Types * * Functions in this section operate on integer types. * * @{ */ /** * Obtain an integer type from a context with specified bit width. */ LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt128TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits); /** * Obtain an integer type from the global context with a specified bit * width. */ LLVMTypeRef LLVMInt1Type(void); LLVMTypeRef LLVMInt8Type(void); LLVMTypeRef LLVMInt16Type(void); LLVMTypeRef LLVMInt32Type(void); LLVMTypeRef LLVMInt64Type(void); LLVMTypeRef LLVMInt128Type(void); LLVMTypeRef LLVMIntType(unsigned NumBits); unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy); /** * @} */ /** * @defgroup LLVMCCoreTypeFloat Floating Point Types * * @{ */ /** * Obtain a 16-bit floating point type from a context. */ LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C); /** * Obtain a 32-bit floating point type from a context. */ LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C); /** * Obtain a 64-bit floating point type from a context. */ LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C); /** * Obtain a 80-bit floating point type (X87) from a context. */ LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C); /** * Obtain a 128-bit floating point type (112-bit mantissa) from a * context. */ LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C); /** * Obtain a 128-bit floating point type (two 64-bits) from a context. */ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C); /** * Obtain a floating point type from the global context. * * These map to the functions in this group of the same name. */ LLVMTypeRef LLVMHalfType(void); LLVMTypeRef LLVMFloatType(void); LLVMTypeRef LLVMDoubleType(void); LLVMTypeRef LLVMX86FP80Type(void); LLVMTypeRef LLVMFP128Type(void); LLVMTypeRef LLVMPPCFP128Type(void); /** * @} */ /** * @defgroup LLVMCCoreTypeFunction Function Types * * @{ */ /** * Obtain a function type consisting of a specified signature. * * The function is defined as a tuple of a return Type, a list of * parameter types, and whether the function is variadic. */ LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType, LLVMTypeRef *ParamTypes, unsigned ParamCount, LLVMBool IsVarArg); /** * Returns whether a function type is variadic. */ LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy); /** * Obtain the Type this function Type returns. */ LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy); /** * Obtain the number of parameters this function accepts. */ unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy); /** * Obtain the types of a function's parameters. * * The Dest parameter should point to a pre-allocated array of * LLVMTypeRef at least LLVMCountParamTypes() large. On return, the * first LLVMCountParamTypes() entries in the array will be populated * with LLVMTypeRef instances. * * @param FunctionTy The function type to operate on. * @param Dest Memory address of an array to be filled with result. */ void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest); /** * @} */ /** * @defgroup LLVMCCoreTypeStruct Structure Types * * These functions relate to LLVMTypeRef instances. * * @see llvm::StructType * * @{ */ /** * Create a new structure type in a context. * * A structure is specified by a list of inner elements/types and * whether these can be packed together. * * @see llvm::StructType::create() */ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); /** * Create a new structure type in the global context. * * @see llvm::StructType::create() */ LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); /** * Create an empty structure in a context having a specified name. * * @see llvm::StructType::create() */ LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name); /** * Obtain the name of a structure. * * @see llvm::StructType::getName() */ const char *LLVMGetStructName(LLVMTypeRef Ty); /** * Set the contents of a structure type. * * @see llvm::StructType::setBody() */ void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); /** * Get the number of elements defined inside the structure. * * @see llvm::StructType::getNumElements() */ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); /** * Get the elements within a structure. * * The function is passed the address of a pre-allocated array of * LLVMTypeRef at least LLVMCountStructElementTypes() long. After * invocation, this array will be populated with the structure's * elements. The objects in the destination array will have a lifetime * of the structure type itself, which is the lifetime of the context it * is contained in. */ void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); /** * Get the type of the element at a given index in the structure. * * @see llvm::StructType::getTypeAtIndex() */ LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i); /** * Determine whether a structure is packed. * * @see llvm::StructType::isPacked() */ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); /** * Determine whether a structure is opaque. * * @see llvm::StructType::isOpaque() */ LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy); /** * Determine whether a structure is literal. * * @see llvm::StructType::isLiteral() */ LLVMBool LLVMIsLiteralStruct(LLVMTypeRef StructTy); /** * @} */ /** * @defgroup LLVMCCoreTypeSequential Sequential Types * * Sequential types represents "arrays" of types. This is a super class * for array, vector, and pointer types. * * @{ */ /** * Obtain the type of elements within a sequential type. * * This works on array, vector, and pointer types. * * @see llvm::SequentialType::getElementType() */ LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty); /** * Returns type's subtypes * * @see llvm::Type::subtypes() */ void LLVMGetSubtypes(LLVMTypeRef Tp, LLVMTypeRef *Arr); /** * Return the number of types in the derived type. * * @see llvm::Type::getNumContainedTypes() */ unsigned LLVMGetNumContainedTypes(LLVMTypeRef Tp); /** * Create a fixed size array type that refers to a specific type. * * The created type will exist in the context that its element type * exists in. * * @see llvm::ArrayType::get() */ LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); /** * Obtain the length of an array type. * * This only works on types that represent arrays. * * @see llvm::ArrayType::getNumElements() */ unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy); /** * Create a pointer type that points to a defined type. * * The created type will exist in the context that its pointee type * exists in. * * @see llvm::PointerType::get() */ LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); /** * Obtain the address space of a pointer type. * * This only works on types that represent pointers. * * @see llvm::PointerType::getAddressSpace() */ unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy); /** * Create a vector type that contains a defined type and has a specific * number of elements. * * The created type will exist in the context thats its element type * exists in. * * @see llvm::VectorType::get() */ LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount); /** * Obtain the number of elements in a vector type. * * This only works on types that represent vectors. * * @see llvm::VectorType::getNumElements() */ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy); /** * @} */ /** * @defgroup LLVMCCoreTypeOther Other Types * * @{ */ /** * Create a void type in a context. */ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C); /** * Create a label type in a context. */ LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C); /** * Create a X86 MMX type in a context. */ LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C); /** * Create a token type in a context. */ LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C); /** * Create a metadata type in a context. */ LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C); /** * These are similar to the above functions except they operate on the * global context. */ LLVMTypeRef LLVMVoidType(void); LLVMTypeRef LLVMLabelType(void); LLVMTypeRef LLVMX86MMXType(void); /** * @} */ /** * @} */ /** * @defgroup LLVMCCoreValues Values * * The bulk of LLVM's object model consists of values, which comprise a very * rich type hierarchy. * * LLVMValueRef essentially represents llvm::Value. There is a rich * hierarchy of classes within this type. Depending on the instance * obtained, not all APIs are available. * * Callers can determine the type of an LLVMValueRef by calling the * LLVMIsA* family of functions (e.g. LLVMIsAArgument()). These * functions are defined by a macro, so it isn't obvious which are * available by looking at the Doxygen source code. Instead, look at the * source definition of LLVM_FOR_EACH_VALUE_SUBCLASS and note the list * of value names given. These value names also correspond to classes in * the llvm::Value hierarchy. * * @{ */ #define LLVM_FOR_EACH_VALUE_SUBCLASS(macro) \ macro(Argument) \ macro(BasicBlock) \ macro(InlineAsm) \ macro(User) \ macro(Constant) \ macro(BlockAddress) \ macro(ConstantAggregateZero) \ macro(ConstantArray) \ macro(ConstantDataSequential) \ macro(ConstantDataArray) \ macro(ConstantDataVector) \ macro(ConstantExpr) \ macro(ConstantFP) \ macro(ConstantInt) \ macro(ConstantPointerNull) \ macro(ConstantStruct) \ macro(ConstantTokenNone) \ macro(ConstantVector) \ macro(GlobalValue) \ macro(GlobalAlias) \ macro(GlobalIFunc) \ macro(GlobalObject) \ macro(Function) \ macro(GlobalVariable) \ macro(UndefValue) \ macro(Instruction) \ macro(BinaryOperator) \ macro(CallInst) \ macro(IntrinsicInst) \ macro(DbgInfoIntrinsic) \ macro(DbgVariableIntrinsic) \ macro(DbgDeclareInst) \ macro(DbgLabelInst) \ macro(MemIntrinsic) \ macro(MemCpyInst) \ macro(MemMoveInst) \ macro(MemSetInst) \ macro(CmpInst) \ macro(FCmpInst) \ macro(ICmpInst) \ macro(ExtractElementInst) \ macro(GetElementPtrInst) \ macro(InsertElementInst) \ macro(InsertValueInst) \ macro(LandingPadInst) \ macro(PHINode) \ macro(SelectInst) \ macro(ShuffleVectorInst) \ macro(StoreInst) \ macro(BranchInst) \ macro(IndirectBrInst) \ macro(InvokeInst) \ macro(ReturnInst) \ macro(SwitchInst) \ macro(UnreachableInst) \ macro(ResumeInst) \ macro(CleanupReturnInst) \ macro(CatchReturnInst) \ macro(FuncletPadInst) \ macro(CatchPadInst) \ macro(CleanupPadInst) \ macro(UnaryInstruction) \ macro(AllocaInst) \ macro(CastInst) \ macro(AddrSpaceCastInst) \ macro(BitCastInst) \ macro(FPExtInst) \ macro(FPToSIInst) \ macro(FPToUIInst) \ macro(FPTruncInst) \ macro(IntToPtrInst) \ macro(PtrToIntInst) \ macro(SExtInst) \ macro(SIToFPInst) \ macro(TruncInst) \ macro(UIToFPInst) \ macro(ZExtInst) \ macro(ExtractValueInst) \ macro(LoadInst) \ macro(VAArgInst) /** * @defgroup LLVMCCoreValueGeneral General APIs * * Functions in this section work on all LLVMValueRef instances, * regardless of their sub-type. They correspond to functions available * on llvm::Value. * * @{ */ /** * Obtain the type of a value. * * @see llvm::Value::getType() */ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val); /** * Obtain the enumerated type of a Value instance. * * @see llvm::Value::getValueID() */ LLVMValueKind LLVMGetValueKind(LLVMValueRef Val); /** * Obtain the string name of a value. * * @see llvm::Value::getName() */ const char *LLVMGetValueName2(LLVMValueRef Val, size_t *Length); /** * Set the string name of a value. * * @see llvm::Value::setName() */ void LLVMSetValueName2(LLVMValueRef Val, const char *Name, size_t NameLen); /** * Dump a representation of a value to stderr. * * @see llvm::Value::dump() */ void LLVMDumpValue(LLVMValueRef Val); /** * Return a string representation of the value. Use * LLVMDisposeMessage to free the string. * * @see llvm::Value::print() */ char *LLVMPrintValueToString(LLVMValueRef Val); /** * Replace all uses of a value with another one. * * @see llvm::Value::replaceAllUsesWith() */ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal); /** * Determine whether the specified value instance is constant. */ LLVMBool LLVMIsConstant(LLVMValueRef Val); /** * Determine whether a value instance is undefined. */ LLVMBool LLVMIsUndef(LLVMValueRef Val); /** * Convert value instances between types. * * Internally, an LLVMValueRef is "pinned" to a specific type. This * series of functions allows you to cast an instance to a specific * type. * * If the cast is not valid for the specified type, NULL is returned. * * @see llvm::dyn_cast_or_null<> */ #define LLVM_DECLARE_VALUE_CAST(name) \ LLVMValueRef LLVMIsA##name(LLVMValueRef Val); LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST) LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val); LLVMValueRef LLVMIsAMDString(LLVMValueRef Val); /** Deprecated: Use LLVMGetValueName2 instead. */ const char *LLVMGetValueName(LLVMValueRef Val); /** Deprecated: Use LLVMSetValueName2 instead. */ void LLVMSetValueName(LLVMValueRef Val, const char *Name); /** * @} */ /** * @defgroup LLVMCCoreValueUses Usage * * This module defines functions that allow you to inspect the uses of a * LLVMValueRef. * * It is possible to obtain an LLVMUseRef for any LLVMValueRef instance. * Each LLVMUseRef (which corresponds to a llvm::Use instance) holds a * llvm::User and llvm::Value. * * @{ */ /** * Obtain the first use of a value. * * Uses are obtained in an iterator fashion. First, call this function * to obtain a reference to the first use. Then, call LLVMGetNextUse() * on that instance and all subsequently obtained instances until * LLVMGetNextUse() returns NULL. * * @see llvm::Value::use_begin() */ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val); /** * Obtain the next use of a value. * * This effectively advances the iterator. It returns NULL if you are on * the final use and no more are available. */ LLVMUseRef LLVMGetNextUse(LLVMUseRef U); /** * Obtain the user value for a user. * * The returned value corresponds to a llvm::User type. * * @see llvm::Use::getUser() */ LLVMValueRef LLVMGetUser(LLVMUseRef U); /** * Obtain the value this use corresponds to. * * @see llvm::Use::get(). */ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U); /** * @} */ /** * @defgroup LLVMCCoreValueUser User value * * Function in this group pertain to LLVMValueRef instances that descent * from llvm::User. This includes constants, instructions, and * operators. * * @{ */ /** * Obtain an operand at a specific index in a llvm::User value. * * @see llvm::User::getOperand() */ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index); /** * Obtain the use of an operand at a specific index in a llvm::User value. * * @see llvm::User::getOperandUse() */ LLVMUseRef LLVMGetOperandUse(LLVMValueRef Val, unsigned Index); /** * Set an operand at a specific index in a llvm::User value. * * @see llvm::User::setOperand() */ void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val); /** * Obtain the number of operands in a llvm::User value. * * @see llvm::User::getNumOperands() */ int LLVMGetNumOperands(LLVMValueRef Val); /** * @} */ /** * @defgroup LLVMCCoreValueConstant Constants * * This section contains APIs for interacting with LLVMValueRef that * correspond to llvm::Constant instances. * * These functions will work for any LLVMValueRef in the llvm::Constant * class hierarchy. * * @{ */ /** * Obtain a constant value referring to the null instance of a type. * * @see llvm::Constant::getNullValue() */ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */ /** * Obtain a constant value referring to the instance of a type * consisting of all ones. * * This is only valid for integer types. * * @see llvm::Constant::getAllOnesValue() */ LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty); /** * Obtain a constant value referring to an undefined value of a type. * * @see llvm::UndefValue::get() */ LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty); /** * Determine whether a value instance is null. * * @see llvm::Constant::isNullValue() */ LLVMBool LLVMIsNull(LLVMValueRef Val); /** * Obtain a constant that is a constant pointer pointing to NULL for a * specified type. */ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); /** * @defgroup LLVMCCoreValueConstantScalar Scalar constants * * Functions in this group model LLVMValueRef instances that correspond * to constants referring to scalar types. * * For integer types, the LLVMTypeRef parameter should correspond to a * llvm::IntegerType instance and the returned LLVMValueRef will * correspond to a llvm::ConstantInt. * * For floating point types, the LLVMTypeRef returned corresponds to a * llvm::ConstantFP. * * @{ */ /** * Obtain a constant value for an integer type. * * The returned value corresponds to a llvm::ConstantInt. * * @see llvm::ConstantInt::get() * * @param IntTy Integer type to obtain value of. * @param N The value the returned instance should refer to. * @param SignExtend Whether to sign extend the produced value. */ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, LLVMBool SignExtend); /** * Obtain a constant value for an integer of arbitrary precision. * * @see llvm::ConstantInt::get() */ LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, unsigned NumWords, const uint64_t Words[]); /** * Obtain a constant value for an integer parsed from a string. * * A similar API, LLVMConstIntOfStringAndSize is also available. If the * string's length is available, it is preferred to call that function * instead. * * @see llvm::ConstantInt::get() */ LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char *Text, uint8_t Radix); /** * Obtain a constant value for an integer parsed from a string with * specified length. * * @see llvm::ConstantInt::get() */ LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char *Text, unsigned SLen, uint8_t Radix); /** * Obtain a constant value referring to a double floating point value. */ LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N); /** * Obtain a constant for a floating point value parsed from a string. * * A similar API, LLVMConstRealOfStringAndSize is also available. It * should be used if the input string's length is known. */ LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text); /** * Obtain a constant for a floating point value parsed from a string. */ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char *Text, unsigned SLen); /** * Obtain the zero extended value for an integer constant value. * * @see llvm::ConstantInt::getZExtValue() */ unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal); /** * Obtain the sign extended value for an integer constant value. * * @see llvm::ConstantInt::getSExtValue() */ long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal); /** * Obtain the double value for an floating point constant value. * losesInfo indicates if some precision was lost in the conversion. * * @see llvm::ConstantFP::getDoubleValue */ double LLVMConstRealGetDouble(LLVMValueRef ConstantVal, LLVMBool *losesInfo); /** * @} */ /** * @defgroup LLVMCCoreValueConstantComposite Composite Constants * * Functions in this group operate on composite constants. * * @{ */ /** * Create a ConstantDataSequential and initialize it with a string. * * @see llvm::ConstantDataArray::getString() */ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, unsigned Length, LLVMBool DontNullTerminate); /** * Create a ConstantDataSequential with string content in the global context. * * This is the same as LLVMConstStringInContext except it operates on the * global context. * * @see LLVMConstStringInContext() * @see llvm::ConstantDataArray::getString() */ LLVMValueRef LLVMConstString(const char *Str, unsigned Length, LLVMBool DontNullTerminate); /** * Returns true if the specified constant is an array of i8. * * @see ConstantDataSequential::getAsString() */ LLVMBool LLVMIsConstantString(LLVMValueRef c); /** * Get the given constant data sequential as a string. * * @see ConstantDataSequential::getAsString() */ const char *LLVMGetAsString(LLVMValueRef c, size_t *Length); /** * Create an anonymous ConstantStruct with the specified values. * * @see llvm::ConstantStruct::getAnon() */ LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed); /** * Create a ConstantStruct in the global Context. * * This is the same as LLVMConstStructInContext except it operates on the * global Context. * * @see LLVMConstStructInContext() */ LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed); /** * Create a ConstantArray from values. * * @see llvm::ConstantArray::get() */ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length); /** * Create a non-anonymous ConstantStruct from values. * * @see llvm::ConstantStruct::get() */ LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, LLVMValueRef *ConstantVals, unsigned Count); /** * Get an element at specified index as a constant. * * @see ConstantDataSequential::getElementAsConstant() */ LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx); /** * Create a ConstantVector from values. * * @see llvm::ConstantVector::get() */ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size); /** * @} */ /** * @defgroup LLVMCCoreValueConstantExpressions Constant Expressions * * Functions in this group correspond to APIs on llvm::ConstantExpr. * * @see llvm::ConstantExpr. * * @{ */ 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 LLVMConstExactUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate, LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate, LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices); LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices); LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType, LLVMBool isSigned); LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType); LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition, LLVMValueRef ConstantIfTrue, LLVMValueRef ConstantIfFalse); LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant, LLVMValueRef IndexConstant); LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef ElementValueConstant, LLVMValueRef IndexConstant); LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant); LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx); LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx); LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB); /** Deprecated: Use LLVMGetInlineAsm instead. */ LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, const char *Constraints, LLVMBool HasSideEffects, LLVMBool IsAlignStack); /** * @} */ /** * @defgroup LLVMCCoreValueConstantGlobals Global Values * * This group contains functions that operate on global values. Functions in * this group relate to functions in the llvm::GlobalValue class tree. * * @see llvm::GlobalValue * * @{ */ LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global); LLVMBool LLVMIsDeclaration(LLVMValueRef Global); LLVMLinkage LLVMGetLinkage(LLVMValueRef Global); void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage); const char *LLVMGetSection(LLVMValueRef Global); void LLVMSetSection(LLVMValueRef Global, const char *Section); LLVMVisibility LLVMGetVisibility(LLVMValueRef Global); void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz); LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global); void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class); LLVMUnnamedAddr LLVMGetUnnamedAddress(LLVMValueRef Global); void LLVMSetUnnamedAddress(LLVMValueRef Global, LLVMUnnamedAddr UnnamedAddr); /** * Returns the "value type" of a global value. This differs from the formal * type of a global value which is always a pointer type. * * @see llvm::GlobalValue::getValueType() */ LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef Global); /** Deprecated: Use LLVMGetUnnamedAddress instead. */ LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global); /** Deprecated: Use LLVMSetUnnamedAddress instead. */ void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr); /** * @defgroup LLVMCCoreValueWithAlignment Values with alignment * * Functions in this group only apply to values with alignment, i.e. * global variables, load and store instructions. */ /** * Obtain the preferred alignment of the value. * @see llvm::AllocaInst::getAlignment() * @see llvm::LoadInst::getAlignment() * @see llvm::StoreInst::getAlignment() * @see llvm::GlobalValue::getAlignment() */ unsigned LLVMGetAlignment(LLVMValueRef V); /** * Set the preferred alignment of the value. * @see llvm::AllocaInst::setAlignment() * @see llvm::LoadInst::setAlignment() * @see llvm::StoreInst::setAlignment() * @see llvm::GlobalValue::setAlignment() */ void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes); /** * Sets a metadata attachment, erasing the existing metadata attachment if * it already exists for the given kind. * * @see llvm::GlobalObject::setMetadata() */ void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind, LLVMMetadataRef MD); /** * Erases a metadata attachment of the given kind if it exists. * * @see llvm::GlobalObject::eraseMetadata() */ void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind); /** * Removes all metadata attachments from this value. * * @see llvm::GlobalObject::clearMetadata() */ void LLVMGlobalClearMetadata(LLVMValueRef Global); /** * Retrieves an array of metadata entries representing the metadata attached to * this value. The caller is responsible for freeing this array by calling * \c LLVMDisposeValueMetadataEntries. * * @see llvm::GlobalObject::getAllMetadata() */ LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value, size_t *NumEntries); /** * Destroys value metadata entries. */ void LLVMDisposeValueMetadataEntries(LLVMValueMetadataEntry *Entries); /** * Returns the kind of a value metadata entry at a specific index. */ unsigned LLVMValueMetadataEntriesGetKind(LLVMValueMetadataEntry *Entries, unsigned Index); /** * Returns the underlying metadata node of a value metadata entry at a * specific index. */ LLVMMetadataRef LLVMValueMetadataEntriesGetMetadata(LLVMValueMetadataEntry *Entries, unsigned Index); /** * @} */ /** * @defgroup LLVMCoreValueConstantGlobalVariable Global Variables * * This group contains functions that operate on global variable values. * * @see llvm::GlobalVariable * * @{ */ 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); LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar); LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar); void LLVMDeleteGlobal(LLVMValueRef GlobalVar); LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar); void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar); void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal); LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar); void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant); LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar); void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode); LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar); void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit); /** * @} */ /** * @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases * * This group contains function that operate on global alias values. * * @see llvm::GlobalAlias * * @{ */ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name); /** * Obtain a GlobalAlias value from a Module by its name. * * The returned value corresponds to a llvm::GlobalAlias value. * * @see llvm::Module::getNamedAlias() */ LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M, const char *Name, size_t NameLen); /** * Obtain an iterator to the first GlobalAlias in a Module. * * @see llvm::Module::alias_begin() */ LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M); /** * Obtain an iterator to the last GlobalAlias in a Module. * * @see llvm::Module::alias_end() */ LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M); /** * Advance a GlobalAlias iterator to the next GlobalAlias. * * Returns NULL if the iterator was already at the end and there are no more * global aliases. */ LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA); /** * Decrement a GlobalAlias iterator to the previous GlobalAlias. * * Returns NULL if the iterator was already at the beginning and there are * no previous global aliases. */ LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA); /** * Retrieve the target value of an alias. */ LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias); /** * Set the target value of an alias. */ void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee); /** * @} */ /** * @defgroup LLVMCCoreValueFunction Function values * * Functions in this group operate on LLVMValueRef instances that * correspond to llvm::Function instances. * * @see llvm::Function * * @{ */ /** * Remove a function from its containing module and deletes it. * * @see llvm::Function::eraseFromParent() */ void LLVMDeleteFunction(LLVMValueRef Fn); /** * Check whether the given function has a personality function. * * @see llvm::Function::hasPersonalityFn() */ LLVMBool LLVMHasPersonalityFn(LLVMValueRef Fn); /** * Obtain the personality function attached to the function. * * @see llvm::Function::getPersonalityFn() */ LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn); /** * Set the personality function attached to the function. * * @see llvm::Function::setPersonalityFn() */ void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn); /** * Obtain the ID number from a function instance. * * @see llvm::Function::getIntrinsicID() */ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn); /** * Create or insert the declaration of an intrinsic. For overloaded intrinsics, * parameter types must be provided to uniquely identify an overload. * * @see llvm::Intrinsic::getDeclaration() */ LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount); /** * Retrieves the type of an intrinsic. For overloaded intrinsics, parameter * types must be provided to uniquely identify an overload. * * @see llvm::Intrinsic::getType() */ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount); /** * Retrieves the name of an intrinsic. * * @see llvm::Intrinsic::getName() */ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength); /** * Copies the name of an overloaded intrinsic identified by a given list of * parameter types. * * Unlike LLVMIntrinsicGetName, the caller is responsible for freeing the * returned string. * * @see llvm::Intrinsic::getName() */ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount, size_t *NameLength); /** * Obtain if the intrinsic identified by the given ID is overloaded. * * @see llvm::Intrinsic::isOverloaded() */ LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID); /** * Obtain the calling function of a function. * * The returned value corresponds to the LLVMCallConv enumeration. * * @see llvm::Function::getCallingConv() */ unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn); /** * Set the calling convention of a function. * * @see llvm::Function::setCallingConv() * * @param Fn Function to operate on * @param CC LLVMCallConv to set calling convention to */ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); /** * Obtain the name of the garbage collector to use during code * generation. * * @see llvm::Function::getGC() */ const char *LLVMGetGC(LLVMValueRef Fn); /** * Define the garbage collector to use during code generation. * * @see llvm::Function::setGC() */ void LLVMSetGC(LLVMValueRef Fn, const char *Name); /** * Add an attribute to a function. * * @see llvm::Function::addAttribute() */ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A); unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx); void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs); LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID); LLVMAttributeRef LLVMGetStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen); void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID); void LLVMRemoveStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen); /** * Add a target-dependent attribute to a function * @see llvm::AttrBuilder::addAttribute() */ void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, const char *V); /** * @defgroup LLVMCCoreValueFunctionParameters Function Parameters * * Functions in this group relate to arguments/parameters on functions. * * Functions in this group expect LLVMValueRef instances that correspond * to llvm::Function instances. * * @{ */ /** * Obtain the number of parameters in a function. * * @see llvm::Function::arg_size() */ unsigned LLVMCountParams(LLVMValueRef Fn); /** * Obtain the parameters in a function. * * The takes a pointer to a pre-allocated array of LLVMValueRef that is * at least LLVMCountParams() long. This array will be filled with * LLVMValueRef instances which correspond to the parameters the * function receives. Each LLVMValueRef corresponds to a llvm::Argument * instance. * * @see llvm::Function::arg_begin() */ void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params); /** * Obtain the parameter at the specified index. * * Parameters are indexed from 0. * * @see llvm::Function::arg_begin() */ LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index); /** * Obtain the function to which this argument belongs. * * Unlike other functions in this group, this one takes an LLVMValueRef * that corresponds to a llvm::Attribute. * * The returned LLVMValueRef is the llvm::Function to which this * argument belongs. */ LLVMValueRef LLVMGetParamParent(LLVMValueRef Inst); /** * Obtain the first parameter to a function. * * @see llvm::Function::arg_begin() */ LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn); /** * Obtain the last parameter to a function. * * @see llvm::Function::arg_end() */ LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn); /** * Obtain the next parameter to a function. * * This takes an LLVMValueRef obtained from LLVMGetFirstParam() (which is * actually a wrapped iterator) and obtains the next parameter from the * underlying iterator. */ LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg); /** * Obtain the previous parameter to a function. * * This is the opposite of LLVMGetNextParam(). */ LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg); /** * Set the alignment for a function parameter. * * @see llvm::Argument::addAttr() * @see llvm::AttrBuilder::addAlignmentAttr() */ void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned Align); /** * @} */ /** * @} */ /** * @} */ /** * @} */ /** * @defgroup LLVMCCoreValueMetadata Metadata * * @{ */ /** * Obtain a MDString value from a context. * * The returned instance corresponds to the llvm::MDString class. * * The instance is specified by string data of a specified length. The * string content is copied, so the backing memory can be freed after * this function returns. */ LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, unsigned SLen); /** * Obtain a MDString value from the global context. */ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen); /** * Obtain a MDNode value from a context. * * The returned value corresponds to the llvm::MDNode class. */ LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, unsigned Count); /** * Obtain a MDNode value from the global context. */ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); /** * Obtain a Metadata as a Value. */ LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD); /** * Obtain a Value as a Metadata. */ LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val); /** * Obtain the underlying string from a MDString value. * * @param V Instance to obtain string from. * @param Length Memory address which will hold length of returned string. * @return String data in MDString. */ const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length); /** * Obtain the number of operands from an MDNode value. * * @param V MDNode to get number of operands from. * @return Number of operands of the MDNode. */ unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V); /** * Obtain the given MDNode's operands. * * The passed LLVMValueRef pointer should point to enough memory to hold all of * the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as * LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the * MDNode's operands. * * @param V MDNode to get the operands from. * @param Dest Destination array for operands. */ void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest); /** * @} */ /** * @defgroup LLVMCCoreValueBasicBlock Basic Block * * A basic block represents a single entry single exit section of code. * Basic blocks contain a list of instructions which form the body of * the block. * * Basic blocks belong to functions. They have the type of label. * * Basic blocks are themselves values. However, the C API models them as * LLVMBasicBlockRef. * * @see llvm::BasicBlock * * @{ */ /** * Convert a basic block instance to a value type. */ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB); /** * Determine whether an LLVMValueRef is itself a basic block. */ LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val); /** * Convert an LLVMValueRef to an LLVMBasicBlockRef instance. */ LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val); /** * Obtain the string name of a basic block. */ const char *LLVMGetBasicBlockName(LLVMBasicBlockRef BB); /** * Obtain the function to which a basic block belongs. * * @see llvm::BasicBlock::getParent() */ LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB); /** * Obtain the terminator instruction for a basic block. * * If the basic block does not have a terminator (it is not well-formed * if it doesn't), then NULL is returned. * * The returned LLVMValueRef corresponds to an llvm::Instruction. * * @see llvm::BasicBlock::getTerminator() */ LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB); /** * Obtain the number of basic blocks in a function. * * @param Fn Function value to operate on. */ unsigned LLVMCountBasicBlocks(LLVMValueRef Fn); /** * Obtain all of the basic blocks in a function. * * This operates on a function value. The BasicBlocks parameter is a * pointer to a pre-allocated array of LLVMBasicBlockRef of at least * LLVMCountBasicBlocks() in length. This array is populated with * LLVMBasicBlockRef instances. */ void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks); /** * Obtain the first basic block in a function. * * The returned basic block can be used as an iterator. You will likely * eventually call into LLVMGetNextBasicBlock() with it. * * @see llvm::Function::begin() */ LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn); /** * Obtain the last basic block in a function. * * @see llvm::Function::end() */ LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn); /** * Advance a basic block iterator. */ LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB); /** * Go backwards in a basic block iterator. */ LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB); /** * Obtain the basic block that corresponds to the entry point of a * function. * * @see llvm::Function::getEntryBlock() */ LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn); /** * Create a new basic block without inserting it into a function. * * @see llvm::BasicBlock::Create() */ LLVMBasicBlockRef LLVMCreateBasicBlockInContext(LLVMContextRef C, const char *Name); /** * Append a basic block to the end of a function. * * @see llvm::BasicBlock::Create() */ LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C, LLVMValueRef Fn, const char *Name); /** * Append a basic block to the end of a function using the global * context. * * @see llvm::BasicBlock::Create() */ LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name); /** * Insert a basic block in a function before another basic block. * * The function to add to is determined by the function of the * passed basic block. * * @see llvm::BasicBlock::Create() */ LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C, LLVMBasicBlockRef BB, const char *Name); /** * Insert a basic block in a function using the global context. * * @see llvm::BasicBlock::Create() */ LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB, const char *Name); /** * Remove a basic block from a function and delete it. * * This deletes the basic block from its containing function and deletes * the basic block itself. * * @see llvm::BasicBlock::eraseFromParent() */ void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); /** * Remove a basic block from a function. * * This deletes the basic block from its containing function but keep * the basic block alive. * * @see llvm::BasicBlock::removeFromParent() */ void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB); /** * Move a basic block to before another one. * * @see llvm::BasicBlock::moveBefore() */ void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); /** * Move a basic block to after another one. * * @see llvm::BasicBlock::moveAfter() */ void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); /** * Obtain the first instruction in a basic block. * * The returned LLVMValueRef corresponds to a llvm::Instruction * instance. */ LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB); /** * Obtain the last instruction in a basic block. * * The returned LLVMValueRef corresponds to an LLVM:Instruction. */ LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB); /** * @} */ /** * @defgroup LLVMCCoreValueInstruction Instructions * * Functions in this group relate to the inspection and manipulation of * individual instructions. * * In the C++ API, an instruction is modeled by llvm::Instruction. This * class has a large number of descendents. llvm::Instruction is a * llvm::Value and in the C API, instructions are modeled by * LLVMValueRef. * * This group also contains sub-groups which operate on specific * llvm::Instruction types, e.g. llvm::CallInst. * * @{ */ /** * Determine whether an instruction has any metadata attached. */ int LLVMHasMetadata(LLVMValueRef Val); /** * Return metadata associated with an instruction value. */ LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID); /** * Set metadata associated with an instruction value. */ void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); /** * Returns the metadata associated with an instruction value, but filters out * all the debug locations. * * @see llvm::Instruction::getAllMetadataOtherThanDebugLoc() */ LLVMValueMetadataEntry * LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Instr, size_t *NumEntries); /** * Obtain the basic block to which an instruction belongs. * * @see llvm::Instruction::getParent() */ LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst); /** * Obtain the instruction that occurs after the one specified. * * The next instruction will be from the same basic block. * * If this is the last instruction in a basic block, NULL will be * returned. */ LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst); /** * Obtain the instruction that occurred before this one. * * If the instruction is the first instruction in a basic block, NULL * will be returned. */ LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst); /** * Remove and delete an instruction. * * The instruction specified is removed from its containing building * block but is kept alive. * * @see llvm::Instruction::removeFromParent() */ void LLVMInstructionRemoveFromParent(LLVMValueRef Inst); /** * Remove and delete an instruction. * * The instruction specified is removed from its containing building * block and then deleted. * * @see llvm::Instruction::eraseFromParent() */ void LLVMInstructionEraseFromParent(LLVMValueRef Inst); /** * Obtain the code opcode for an individual instruction. * * @see llvm::Instruction::getOpCode() */ LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst); /** * Obtain the predicate of an instruction. * * This is only valid for instructions that correspond to llvm::ICmpInst * or llvm::ConstantExpr whose opcode is llvm::Instruction::ICmp. * * @see llvm::ICmpInst::getPredicate() */ LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst); /** * Obtain the float predicate of an instruction. * * This is only valid for instructions that correspond to llvm::FCmpInst * or llvm::ConstantExpr whose opcode is llvm::Instruction::FCmp. * * @see llvm::FCmpInst::getPredicate() */ LLVMRealPredicate LLVMGetFCmpPredicate(LLVMValueRef Inst); /** * Create a copy of 'this' instruction that is identical in all ways * except the following: * * The instruction has no parent * * The instruction has no name * * @see llvm::Instruction::clone() */ LLVMValueRef LLVMInstructionClone(LLVMValueRef Inst); /** * Determine whether an instruction is a terminator. This routine is named to * be compatible with historical functions that did this by querying the * underlying C++ type. * * @see llvm::Instruction::isTerminator() */ LLVMValueRef LLVMIsATerminatorInst(LLVMValueRef Inst); /** * @defgroup LLVMCCoreValueInstructionCall Call Sites and Invocations * * Functions in this group apply to instructions that refer to call * sites and invocations. These correspond to C++ types in the * llvm::CallInst class tree. * * @{ */ /** * Obtain the argument count for a call instruction. * * This expects an LLVMValueRef that corresponds to a llvm::CallInst, * llvm::InvokeInst, or llvm:FuncletPadInst. * * @see llvm::CallInst::getNumArgOperands() * @see llvm::InvokeInst::getNumArgOperands() * @see llvm::FuncletPadInst::getNumArgOperands() */ unsigned LLVMGetNumArgOperands(LLVMValueRef Instr); /** * Set the calling convention for a call instruction. * * This expects an LLVMValueRef that corresponds to a llvm::CallInst or * llvm::InvokeInst. * * @see llvm::CallInst::setCallingConv() * @see llvm::InvokeInst::setCallingConv() */ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC); /** * Obtain the calling convention for a call instruction. * * This is the opposite of LLVMSetInstructionCallConv(). Reads its * usage. * * @see LLVMSetInstructionCallConv() */ unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr); void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned Align); void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef A); unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx); void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs); LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID); LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen); void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID); void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen); /** * Obtain the function type called by this instruction. * * @see llvm::CallBase::getFunctionType() */ LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef C); /** * Obtain the pointer to the function invoked by this instruction. * * This expects an LLVMValueRef that corresponds to a llvm::CallInst or * llvm::InvokeInst. * * @see llvm::CallInst::getCalledValue() * @see llvm::InvokeInst::getCalledValue() */ LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr); /** * Obtain whether a call instruction is a tail call. * * This only works on llvm::CallInst instructions. * * @see llvm::CallInst::isTailCall() */ LLVMBool LLVMIsTailCall(LLVMValueRef CallInst); /** * Set whether a call instruction is a tail call. * * This only works on llvm::CallInst instructions. * * @see llvm::CallInst::setTailCall() */ void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall); /** * Return the normal destination basic block. * * This only works on llvm::InvokeInst instructions. * * @see llvm::InvokeInst::getNormalDest() */ LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef InvokeInst); /** * Return the unwind destination basic block. * * Works on llvm::InvokeInst, llvm::CleanupReturnInst, and * llvm::CatchSwitchInst instructions. * * @see llvm::InvokeInst::getUnwindDest() * @see llvm::CleanupReturnInst::getUnwindDest() * @see llvm::CatchSwitchInst::getUnwindDest() */ LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef InvokeInst); /** * Set the normal destination basic block. * * This only works on llvm::InvokeInst instructions. * * @see llvm::InvokeInst::setNormalDest() */ void LLVMSetNormalDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B); /** * Set the unwind destination basic block. * * Works on llvm::InvokeInst, llvm::CleanupReturnInst, and * llvm::CatchSwitchInst instructions. * * @see llvm::InvokeInst::setUnwindDest() * @see llvm::CleanupReturnInst::setUnwindDest() * @see llvm::CatchSwitchInst::setUnwindDest() */ void LLVMSetUnwindDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B); /** * @} */ /** * @defgroup LLVMCCoreValueInstructionTerminator Terminators * * Functions in this group only apply to instructions for which * LLVMIsATerminatorInst returns true. * * @{ */ /** * Return the number of successors that this terminator has. * * @see llvm::Instruction::getNumSuccessors */ unsigned LLVMGetNumSuccessors(LLVMValueRef Term); /** * Return the specified successor. * * @see llvm::Instruction::getSuccessor */ LLVMBasicBlockRef LLVMGetSuccessor(LLVMValueRef Term, unsigned i); /** * Update the specified successor to point at the provided block. * * @see llvm::Instruction::setSuccessor */ void LLVMSetSuccessor(LLVMValueRef Term, unsigned i, LLVMBasicBlockRef block); /** * Return if a branch is conditional. * * This only works on llvm::BranchInst instructions. * * @see llvm::BranchInst::isConditional */ LLVMBool LLVMIsConditional(LLVMValueRef Branch); /** * Return the condition of a branch instruction. * * This only works on llvm::BranchInst instructions. * * @see llvm::BranchInst::getCondition */ LLVMValueRef LLVMGetCondition(LLVMValueRef Branch); /** * Set the condition of a branch instruction. * * This only works on llvm::BranchInst instructions. * * @see llvm::BranchInst::setCondition */ void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond); /** * Obtain the default destination basic block of a switch instruction. * * This only works on llvm::SwitchInst instructions. * * @see llvm::SwitchInst::getDefaultDest() */ LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr); /** * @} */ /** * @defgroup LLVMCCoreValueInstructionAlloca Allocas * * Functions in this group only apply to instructions that map to * llvm::AllocaInst instances. * * @{ */ /** * Obtain the type that is being allocated by the alloca instruction. */ LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca); /** * @} */ /** * @defgroup LLVMCCoreValueInstructionGetElementPointer GEPs * * Functions in this group only apply to instructions that map to * llvm::GetElementPtrInst instances. * * @{ */ /** * Check whether the given GEP instruction is inbounds. */ LLVMBool LLVMIsInBounds(LLVMValueRef GEP); /** * Set the given GEP instruction to be inbounds or not. */ void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds); /** * @} */ /** * @defgroup LLVMCCoreValueInstructionPHINode PHI Nodes * * Functions in this group only apply to instructions that map to * llvm::PHINode instances. * * @{ */ /** * Add an incoming value to the end of a PHI list. */ void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, LLVMBasicBlockRef *IncomingBlocks, unsigned Count); /** * Obtain the number of incoming basic blocks to a PHI node. */ unsigned LLVMCountIncoming(LLVMValueRef PhiNode); /** * Obtain an incoming value to a PHI node as an LLVMValueRef. */ LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index); /** * Obtain an incoming value to a PHI node as an LLVMBasicBlockRef. */ LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index); /** * @} */ /** * @defgroup LLVMCCoreValueInstructionExtractValue ExtractValue * @defgroup LLVMCCoreValueInstructionInsertValue InsertValue * * Functions in this group only apply to instructions that map to * llvm::ExtractValue and llvm::InsertValue instances. * * @{ */ /** * Obtain the number of indices. * NB: This also works on GEP. */ unsigned LLVMGetNumIndices(LLVMValueRef Inst); /** * Obtain the indices as an array. */ const unsigned *LLVMGetIndices(LLVMValueRef Inst); /** * @} */ /** * @} */ /** * @} */ /** * @defgroup LLVMCCoreInstructionBuilder Instruction Builders * * An instruction builder represents a point within a basic block and is * the exclusive means of building instructions using the C interface. * * @{ */ LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C); LLVMBuilderRef LLVMCreateBuilder(void); void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr); void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr); void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block); LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder); void LLVMClearInsertionPosition(LLVMBuilderRef Builder); void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr); 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); LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef, LLVMValueRef *RetVals, unsigned N); LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest); 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); // LLVMBuildInvoke is deprecated in favor of LLVMBuildInvoke2, in preparation // for opaque pointer types. LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name); LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name); LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); /* Exception Handling */ LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn); LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef PersFn, unsigned NumClauses, const char *Name); LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CatchPad, LLVMBasicBlockRef BB); LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad, LLVMBasicBlockRef BB); LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMValueRef *Args, unsigned NumArgs, const char *Name); LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMValueRef *Args, unsigned NumArgs, const char *Name); LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMBasicBlockRef UnwindBB, unsigned NumHandlers, const char *Name); /* Add a case to the switch instruction */ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest); /* Add a destination to the indirectbr instruction */ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest); /* Get the number of clauses on the landingpad instruction */ unsigned LLVMGetNumClauses(LLVMValueRef LandingPad); /* Get the value of the clause at idnex Idx on the landingpad instruction */ LLVMValueRef LLVMGetClause(LLVMValueRef LandingPad, unsigned Idx); /* Add a catch or filter clause to the landingpad instruction */ void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal); /* Get the 'cleanup' flag in the landingpad instruction */ LLVMBool LLVMIsCleanup(LLVMValueRef LandingPad); /* Set the 'cleanup' flag in the landingpad instruction */ void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val); /* Add a destination to the catchswitch instruction */ void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef Dest); /* Get the number of handlers on the catchswitch instruction */ unsigned LLVMGetNumHandlers(LLVMValueRef CatchSwitch); /** * Obtain the basic blocks acting as handlers for a catchswitch instruction. * * The Handlers parameter should point to a pre-allocated array of * LLVMBasicBlockRefs at least LLVMGetNumHandlers() large. On return, the * first LLVMGetNumHandlers() entries in the array will be populated * with LLVMBasicBlockRef instances. * * @param CatchSwitch The catchswitch instruction to operate on. * @param Handlers Memory address of an array to be filled with basic blocks. */ void LLVMGetHandlers(LLVMValueRef CatchSwitch, LLVMBasicBlockRef *Handlers); /* Funclets */ /* Get the number of funcletpad arguments. */ LLVMValueRef LLVMGetArgOperand(LLVMValueRef Funclet, unsigned i); /* Set a funcletpad argument at the given index. */ void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value); /** * Get the parent catchswitch instruction of a catchpad instruction. * * This only works on llvm::CatchPadInst instructions. * * @see llvm::CatchPadInst::getCatchSwitch() */ LLVMValueRef LLVMGetParentCatchSwitch(LLVMValueRef CatchPad); /** * Set the parent catchswitch instruction of a catchpad instruction. * * This only works on llvm::CatchPadInst instructions. * * @see llvm::CatchPadInst::setCatchSwitch() */ void LLVMSetParentCatchSwitch(LLVMValueRef CatchPad, LLVMValueRef CatchSwitch); /* 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, const char *Name); LLVMValueRef LLVMBuildExactUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); 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); /* Memory */ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name); /** * Creates and inserts a memset to the specified pointer and the * specified value. * * @see llvm::IRRBuilder::CreateMemSet() */ LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Len, unsigned Align); /** * Creates and inserts a memcpy between the specified pointers. * * @see llvm::IRRBuilder::CreateMemCpy() */ LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size); /** * Creates and inserts a memmove between the specified pointers. * * @see llvm::IRRBuilder::CreateMemMove() */ LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size); LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name); LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal); +// LLVMBuildLoad is deprecated in favor of LLVMBuildLoad2, in preparation for +// opaque pointer types. LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal, const char *Name); +LLVMValueRef LLVMBuildLoad2(LLVMBuilderRef, LLVMTypeRef Ty, + LLVMValueRef PointerVal, const char *Name); LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr); LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef *Indices, unsigned NumIndices, const char *Name); LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef *Indices, unsigned NumIndices, const char *Name); LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer, unsigned Idx, const char *Name); LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str, const char *Name); LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str, const char *Name); LLVMBool LLVMGetVolatile(LLVMValueRef MemoryAccessInst); void LLVMSetVolatile(LLVMValueRef MemoryAccessInst, LLVMBool IsVolatile); LLVMAtomicOrdering LLVMGetOrdering(LLVMValueRef MemoryAccessInst); void LLVMSetOrdering(LLVMValueRef MemoryAccessInst, LLVMAtomicOrdering Ordering); /* Casts */ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); 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 LLVMBuildIntCast2(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, LLVMBool IsSigned, const char *Name); LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name); /** Deprecated: This cast is always signed. Use LLVMBuildIntCast2 instead. */ LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/ LLVMTypeRef DestTy, const char *Name); /* Comparisons */ LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); /* Miscellaneous instructions */ LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name); // LLVMBuildCall is deprecated in favor of LLVMBuildCall2, in preparation for // opaque pointer types. LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name); LLVMValueRef LLVMBuildCall2(LLVMBuilderRef, LLVMTypeRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name); LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, const char *Name); LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty, const char *Name); LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal, LLVMValueRef Index, const char *Name); LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, const char *Name); LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, const char *Name); LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef, LLVMValueRef AggVal, unsigned Index, const char *Name); LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, const char *Name); LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val, const char *Name); LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val, const char *Name); LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering ordering, LLVMBool singleThread, const char *Name); LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op, LLVMValueRef PTR, LLVMValueRef Val, LLVMAtomicOrdering ordering, LLVMBool singleThread); LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Cmp, LLVMValueRef New, LLVMAtomicOrdering SuccessOrdering, LLVMAtomicOrdering FailureOrdering, LLVMBool SingleThread); LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst); void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread); LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst); void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst, LLVMAtomicOrdering Ordering); LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst); void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst, LLVMAtomicOrdering Ordering); /** * @} */ /** * @defgroup LLVMCCoreModuleProvider Module Providers * * @{ */ /** * Changes the type of M so it can be passed to FunctionPassManagers and the * JIT. They take ModuleProviders for historical reasons. */ LLVMModuleProviderRef LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M); /** * Destroys the module M. */ void LLVMDisposeModuleProvider(LLVMModuleProviderRef M); /** * @} */ /** * @defgroup LLVMCCoreMemoryBuffers Memory Buffers * * @{ */ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path, LLVMMemoryBufferRef *OutMemBuf, char **OutMessage); LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage); LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData, size_t InputDataLength, const char *BufferName, LLVMBool RequiresNullTerminator); LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData, size_t InputDataLength, const char *BufferName); const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf); size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf); void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf); /** * @} */ /** * @defgroup LLVMCCorePassRegistry Pass Registry * * @{ */ /** Return the global pass registry, for use with initialization functions. @see llvm::PassRegistry::getPassRegistry */ LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void); /** * @} */ /** * @defgroup LLVMCCorePassManagers Pass Managers * * @{ */ /** Constructs a new whole-module pass pipeline. This type of pipeline is suitable for link-time optimization and whole-module transformations. @see llvm::PassManager::PassManager */ LLVMPassManagerRef LLVMCreatePassManager(void); /** Constructs a new function-by-function pass pipeline over the module 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 passes scheduled in the pass manager. Returns 1 if any of the passes modified the module, 0 otherwise. @see llvm::PassManager::run(Module&) */ LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M); /** Initializes all of the function passes scheduled in the function pass manager. Returns 1 if any of the passes modified the module, 0 otherwise. @see llvm::FunctionPassManager::doInitialization */ LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM); /** Executes all of the function passes scheduled in the function pass manager on the provided function. Returns 1 if any of the passes modified the function, false otherwise. @see llvm::FunctionPassManager::run(Function&) */ LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F); /** Finalizes all of the function passes scheduled in the function pass manager. Returns 1 if any of the passes modified the module, 0 otherwise. @see llvm::FunctionPassManager::doFinalization */ LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM); /** Frees the memory of a pass pipeline. For function pipelines, does not free the module provider. @see llvm::PassManagerBase::~PassManagerBase. */ void LLVMDisposePassManager(LLVMPassManagerRef PM); /** * @} */ /** * @defgroup LLVMCCoreThreading Threading * * Handle the structures needed to make LLVM safe for multithreading. * * @{ */ /** Deprecated: Multi-threading can only be enabled/disabled with the compile time define LLVM_ENABLE_THREADS. This function always returns LLVMIsMultithreaded(). */ LLVMBool LLVMStartMultithreaded(void); /** Deprecated: Multi-threading can only be enabled/disabled with the compile time define LLVM_ENABLE_THREADS. */ void LLVMStopMultithreaded(void); /** Check whether LLVM is executing in thread-safe mode or not. @see llvm::llvm_is_multithreaded */ LLVMBool LLVMIsMultithreaded(void); /** * @} */ /** * @} */ /** * @} */ #ifdef __cplusplus } #endif #endif /* LLVM_C_CORE_H */ diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index ed86b503b8df..27e300268a13 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1,2282 +1,2314 @@ //===- llvm/IRBuilder.h - Builder for LLVM Instructions ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the IRBuilder class, which is used as a convenient way // to create LLVM instructions with a consistent and simplified interface. // //===----------------------------------------------------------------------===// #ifndef LLVM_IR_IRBUILDER_H #define LLVM_IR_IRBUILDER_H #include "llvm-c/Types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/ConstantFolder.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Casting.h" #include #include #include #include #include namespace llvm { class APInt; class MDNode; class Use; /// This provides the default implementation of the IRBuilder /// 'InsertHelper' method that is called whenever an instruction is created by /// IRBuilder and needs to be inserted. /// /// By default, this inserts the instruction at the insertion point. class IRBuilderDefaultInserter { protected: void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB, BasicBlock::iterator InsertPt) const { if (BB) BB->getInstList().insert(InsertPt, I); I->setName(Name); } }; /// Provides an 'InsertHelper' that calls a user-provided callback after /// performing the default insertion. class IRBuilderCallbackInserter : IRBuilderDefaultInserter { std::function Callback; public: IRBuilderCallbackInserter(std::function Callback) : Callback(std::move(Callback)) {} protected: void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB, BasicBlock::iterator InsertPt) const { IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt); Callback(I); } }; /// Common base class shared among various IRBuilders. class IRBuilderBase { DebugLoc CurDbgLocation; protected: BasicBlock *BB; BasicBlock::iterator InsertPt; LLVMContext &Context; MDNode *DefaultFPMathTag; FastMathFlags FMF; ArrayRef DefaultOperandBundles; public: IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : Context(context), DefaultFPMathTag(FPMathTag), DefaultOperandBundles(OpBundles) { ClearInsertionPoint(); } //===--------------------------------------------------------------------===// // Builder configuration methods //===--------------------------------------------------------------------===// /// Clear the insertion point: created instructions will not be /// inserted into a block. void ClearInsertionPoint() { BB = nullptr; InsertPt = BasicBlock::iterator(); } BasicBlock *GetInsertBlock() const { return BB; } BasicBlock::iterator GetInsertPoint() const { return InsertPt; } LLVMContext &getContext() const { return Context; } /// This specifies that created instructions should be appended to the /// end of the specified block. void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } /// This specifies that created instructions should be inserted before /// the specified instruction. void SetInsertPoint(Instruction *I) { BB = I->getParent(); InsertPt = I->getIterator(); assert(InsertPt != BB->end() && "Can't read debug loc from end()"); SetCurrentDebugLocation(I->getDebugLoc()); } /// This specifies that created instructions should be inserted at the /// specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; if (IP != TheBB->end()) SetCurrentDebugLocation(IP->getDebugLoc()); } /// Set location information used by debugging information. void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } /// Get location information used by debugging information. const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } /// If this builder has a current debug location, set it on the /// specified instruction. void SetInstDebugLocation(Instruction *I) const { if (CurDbgLocation) I->setDebugLoc(CurDbgLocation); } /// Get the return type of the current function that we're emitting /// into. Type *getCurrentFunctionReturnType() const; /// InsertPoint - A saved insertion point. class InsertPoint { BasicBlock *Block = nullptr; BasicBlock::iterator Point; public: /// Creates a new insertion point which doesn't point to anything. InsertPoint() = default; /// Creates a new insertion point at the given location. InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) : Block(InsertBlock), Point(InsertPoint) {} /// Returns true if this insert point is set. bool isSet() const { return (Block != nullptr); } BasicBlock *getBlock() const { return Block; } BasicBlock::iterator getPoint() const { return Point; } }; /// Returns the current insert point. InsertPoint saveIP() const { return InsertPoint(GetInsertBlock(), GetInsertPoint()); } /// Returns the current insert point, clearing it in the process. InsertPoint saveAndClearIP() { InsertPoint IP(GetInsertBlock(), GetInsertPoint()); ClearInsertionPoint(); return IP; } /// Sets the current insert point to a previously-saved location. void restoreIP(InsertPoint IP) { if (IP.isSet()) SetInsertPoint(IP.getBlock(), IP.getPoint()); else ClearInsertionPoint(); } /// Get the floating point math metadata being used. MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } /// Get the flags to be applied to created floating point ops FastMathFlags getFastMathFlags() const { return FMF; } /// Clear the fast-math flags. void clearFastMathFlags() { FMF.clear(); } /// Set the floating point math metadata to be used. void setDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } /// Set the fast-math flags to be used with generated fp-math operators void setFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } //===--------------------------------------------------------------------===// // RAII helpers. //===--------------------------------------------------------------------===// // RAII object that stores the current insertion point and restores it // when the object is destroyed. This includes the debug location. class InsertPointGuard { IRBuilderBase &Builder; AssertingVH Block; BasicBlock::iterator Point; DebugLoc DbgLoc; public: InsertPointGuard(IRBuilderBase &B) : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()), DbgLoc(B.getCurrentDebugLocation()) {} InsertPointGuard(const InsertPointGuard &) = delete; InsertPointGuard &operator=(const InsertPointGuard &) = delete; ~InsertPointGuard() { Builder.restoreIP(InsertPoint(Block, Point)); Builder.SetCurrentDebugLocation(DbgLoc); } }; // RAII object that stores the current fast math settings and restores // them when the object is destroyed. class FastMathFlagGuard { IRBuilderBase &Builder; FastMathFlags FMF; MDNode *FPMathTag; public: FastMathFlagGuard(IRBuilderBase &B) : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {} FastMathFlagGuard(const FastMathFlagGuard &) = delete; FastMathFlagGuard &operator=(const FastMathFlagGuard &) = delete; ~FastMathFlagGuard() { Builder.FMF = FMF; Builder.DefaultFPMathTag = FPMathTag; } }; //===--------------------------------------------------------------------===// // Miscellaneous creation methods. //===--------------------------------------------------------------------===// /// Make a new global variable with initializer type i8* /// /// Make a new global variable with an initializer that has array of i8 type /// filled in with the null terminated string value specified. The new global /// variable will be marked mergable with any others of the same contents. If /// Name is specified, it is the name of the global variable created. GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "", unsigned AddressSpace = 0); /// Get a constant value representing either true or false. ConstantInt *getInt1(bool V) { return ConstantInt::get(getInt1Ty(), V); } /// Get the constant value for i1 true. ConstantInt *getTrue() { return ConstantInt::getTrue(Context); } /// Get the constant value for i1 false. ConstantInt *getFalse() { return ConstantInt::getFalse(Context); } /// Get a constant 8-bit value. ConstantInt *getInt8(uint8_t C) { return ConstantInt::get(getInt8Ty(), C); } /// Get a constant 16-bit value. ConstantInt *getInt16(uint16_t C) { return ConstantInt::get(getInt16Ty(), C); } /// Get a constant 32-bit value. ConstantInt *getInt32(uint32_t C) { return ConstantInt::get(getInt32Ty(), C); } /// Get a constant 64-bit value. ConstantInt *getInt64(uint64_t C) { return ConstantInt::get(getInt64Ty(), C); } /// Get a constant N-bit value, zero extended or truncated from /// a 64-bit value. ConstantInt *getIntN(unsigned N, uint64_t C) { return ConstantInt::get(getIntNTy(N), C); } /// Get a constant integer value. ConstantInt *getInt(const APInt &AI) { return ConstantInt::get(Context, AI); } //===--------------------------------------------------------------------===// // Type creation methods //===--------------------------------------------------------------------===// /// Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); } /// Fetch the type representing an 8-bit integer. IntegerType *getInt8Ty() { return Type::getInt8Ty(Context); } /// Fetch the type representing a 16-bit integer. IntegerType *getInt16Ty() { return Type::getInt16Ty(Context); } /// Fetch the type representing a 32-bit integer. IntegerType *getInt32Ty() { return Type::getInt32Ty(Context); } /// Fetch the type representing a 64-bit integer. IntegerType *getInt64Ty() { return Type::getInt64Ty(Context); } /// Fetch the type representing a 128-bit integer. IntegerType *getInt128Ty() { return Type::getInt128Ty(Context); } /// Fetch the type representing an N-bit integer. IntegerType *getIntNTy(unsigned N) { return Type::getIntNTy(Context, N); } /// Fetch the type representing a 16-bit floating point value. Type *getHalfTy() { return Type::getHalfTy(Context); } /// Fetch the type representing a 32-bit floating point value. Type *getFloatTy() { return Type::getFloatTy(Context); } /// Fetch the type representing a 64-bit floating point value. Type *getDoubleTy() { return Type::getDoubleTy(Context); } /// Fetch the type representing void. Type *getVoidTy() { return Type::getVoidTy(Context); } /// Fetch the type representing a pointer to an 8-bit integer value. PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { return Type::getInt8PtrTy(Context, AddrSpace); } /// Fetch the type representing a pointer to an integer value. IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) { return DL.getIntPtrType(Context, AddrSpace); } //===--------------------------------------------------------------------===// // Intrinsic creation methods //===--------------------------------------------------------------------===// /// Create and insert a memset to the specified pointer and the /// specified value. /// /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag, ScopeTag, NoAliasTag); } CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// Create and insert an element unordered-atomic memset of the region of /// memory starting at the given pointer to the given value. /// /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size), Align, ElementSize, TBAATag, ScopeTag, NoAliasTag); } CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// Create and insert a memcpy between the specified pointers. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateMemCpy(Dst, DstAlign, Src, SrcAlign, getInt64(Size), isVolatile, TBAATag, TBAAStructTag, ScopeTag, NoAliasTag); } CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// Create and insert an element unordered-atomic memcpy between the /// specified pointers. /// /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, respectively. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateElementUnorderedAtomicMemCpy( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateElementUnorderedAtomicMemCpy( Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, TBAAStructTag, ScopeTag, NoAliasTag); } CallInst *CreateElementUnorderedAtomicMemCpy( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// Create and insert a memmove between the specified /// pointers. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateMemMove(Dst, DstAlign, Src, SrcAlign, getInt64(Size), isVolatile, TBAATag, ScopeTag, NoAliasTag); } CallInst *CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// \brief Create and insert an element unordered-atomic memmove between the /// specified pointers. /// /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, /// respectively. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateElementUnorderedAtomicMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { return CreateElementUnorderedAtomicMemMove( Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, TBAAStructTag, ScopeTag, NoAliasTag); } CallInst *CreateElementUnorderedAtomicMemMove( Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); /// Create a vector fadd reduction intrinsic of the source vector. /// The first parameter is a scalar accumulator value for ordered reductions. CallInst *CreateFAddReduce(Value *Acc, Value *Src); /// Create a vector fmul reduction intrinsic of the source vector. /// The first parameter is a scalar accumulator value for ordered reductions. CallInst *CreateFMulReduce(Value *Acc, Value *Src); /// Create a vector int add reduction intrinsic of the source vector. CallInst *CreateAddReduce(Value *Src); /// Create a vector int mul reduction intrinsic of the source vector. CallInst *CreateMulReduce(Value *Src); /// Create a vector int AND reduction intrinsic of the source vector. CallInst *CreateAndReduce(Value *Src); /// Create a vector int OR reduction intrinsic of the source vector. CallInst *CreateOrReduce(Value *Src); /// Create a vector int XOR reduction intrinsic of the source vector. CallInst *CreateXorReduce(Value *Src); /// Create a vector integer max reduction intrinsic of the source /// vector. CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false); /// Create a vector integer min reduction intrinsic of the source /// vector. CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false); /// Create a vector float max reduction intrinsic of the source /// vector. CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false); /// Create a vector float min reduction intrinsic of the source /// vector. CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false); /// Create a lifetime.start intrinsic. /// /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = nullptr); /// Create a lifetime.end intrinsic. /// /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = nullptr); /// Create a call to invariant.start intrinsic. /// /// If the pointer isn't i8* it will be converted. CallInst *CreateInvariantStart(Value *Ptr, ConstantInt *Size = nullptr); /// Create a call to Masked Load intrinsic CallInst *CreateMaskedLoad(Value *Ptr, unsigned Align, Value *Mask, Value *PassThru = nullptr, const Twine &Name = ""); /// Create a call to Masked Store intrinsic CallInst *CreateMaskedStore(Value *Val, Value *Ptr, unsigned Align, Value *Mask); /// Create a call to Masked Gather intrinsic CallInst *CreateMaskedGather(Value *Ptrs, unsigned Align, Value *Mask = nullptr, Value *PassThru = nullptr, const Twine& Name = ""); /// Create a call to Masked Scatter intrinsic CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, unsigned Align, Value *Mask = nullptr); /// Create an assume intrinsic call that allows the optimizer to /// assume that the provided condition will be true. CallInst *CreateAssumption(Value *Cond); /// Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, ArrayRef CallArgs, ArrayRef TransitionArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Conveninence function for the common case when CallArgs are filled /// in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be /// .get()'ed to get the Value pointer. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, ArrayRef CallArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create an invoke to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. InvokeInst * CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create an invoke to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. InvokeInst *CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, ArrayRef InvokeArgs, ArrayRef TransitionArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); // Convenience function for the common case when CallArgs are filled in using // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to // get the Value *. InvokeInst * CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef InvokeArgs, ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); /// Create a call to the experimental.gc.result intrinsic to extract /// the result from a call wrapped in a statepoint. CallInst *CreateGCResult(Instruction *Statepoint, Type *ResultType, const Twine &Name = ""); /// Create a call to the experimental.gc.relocate intrinsics to /// project the relocated value of one pointer from the statepoint. CallInst *CreateGCRelocate(Instruction *Statepoint, int BaseOffset, int DerivedOffset, Type *ResultType, const Twine &Name = ""); /// Create a call to intrinsic \p ID with 1 operand which is mangled on its /// type. CallInst *CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, Instruction *FMFSource = nullptr, const Twine &Name = ""); /// Create a call to intrinsic \p ID with 2 operands which is mangled on the /// first type. CallInst *CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource = nullptr, const Twine &Name = ""); /// Create a call to intrinsic \p ID with \p args, mangled using \p Types. If /// \p FMFSource is provided, copy fast-math-flags from that instruction to /// the intrinsic. CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef Types, ArrayRef Args, Instruction *FMFSource = nullptr, const Twine &Name = ""); /// Create call to the minnum intrinsic. CallInst *CreateMinNum(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS, nullptr, Name); } /// Create call to the maxnum intrinsic. CallInst *CreateMaxNum(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS, nullptr, Name); } /// Create call to the minimum intrinsic. CallInst *CreateMinimum(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateBinaryIntrinsic(Intrinsic::minimum, LHS, RHS, nullptr, Name); } /// Create call to the maximum intrinsic. CallInst *CreateMaximum(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateBinaryIntrinsic(Intrinsic::maximum, LHS, RHS, nullptr, Name); } private: /// Create a call to a masked intrinsic with given Id. CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef Ops, ArrayRef OverloadedTypes, const Twine &Name = ""); Value *getCastedInt8PtrValue(Value *Ptr); }; /// This provides a uniform API for creating instructions and inserting /// them into a basic block: either at the end of a BasicBlock, or at a specific /// iterator location in a block. /// /// Note that the builder does not expose the full generality of LLVM /// instructions. For access to extra instruction properties, use the mutators /// (e.g. setVolatile) on the instructions after they have been /// created. Convenience state exists to specify fast-math flags and fp-math /// tags. /// /// The first template argument specifies a class to use for creating constants. /// This defaults to creating minimally folded constants. The second template /// argument allows clients to specify custom insertion hooks that are called on /// every newly created insertion. template class IRBuilder : public IRBuilderBase, public Inserter { T Folder; public: IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(), MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(C, FPMathTag, OpBundles), Inserter(std::move(I)), Folder(F) {} explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(C, FPMathTag, OpBundles) {} explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) { SetInsertPoint(TheBB); } explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) { SetInsertPoint(TheBB); } explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(IP->getContext(), FPMathTag, OpBundles) { SetInsertPoint(IP); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T &F, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) { SetInsertPoint(TheBB, IP); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = nullptr, ArrayRef OpBundles = None) : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) { SetInsertPoint(TheBB, IP); } /// Get the constant folder being used. const T &getFolder() { return Folder; } /// Insert and return the specified instruction. template InstTy *Insert(InstTy *I, const Twine &Name = "") const { this->InsertHelper(I, Name, BB, InsertPt); this->SetInstDebugLocation(I); return I; } /// No-op overload to handle constants. Constant *Insert(Constant *C, const Twine& = "") const { return C; } //===--------------------------------------------------------------------===// // Instruction creation methods: Terminators //===--------------------------------------------------------------------===// private: /// Helper to add branch weight and unpredictable metadata onto an /// instruction. /// \returns The annotated instruction. template InstTy *addBranchMetadata(InstTy *I, MDNode *Weights, MDNode *Unpredictable) { if (Weights) I->setMetadata(LLVMContext::MD_prof, Weights); if (Unpredictable) I->setMetadata(LLVMContext::MD_unpredictable, Unpredictable); return I; } public: /// Create a 'ret void' instruction. ReturnInst *CreateRetVoid() { return Insert(ReturnInst::Create(Context)); } /// Create a 'ret ' instruction. ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(Context, V)); } /// Create a sequence of N insertvalue instructions, /// with one Value from the retVals array each, that build a aggregate /// return value one value at a time, and a ret instruction to return /// the resulting aggregate value. /// /// This is a convenience function for code that uses aggregate return values /// as a vehicle for having multiple return values. ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { Value *V = UndefValue::get(getCurrentFunctionReturnType()); for (unsigned i = 0; i != N; ++i) V = CreateInsertValue(V, retVals[i], i, "mrv"); return Insert(ReturnInst::Create(Context, V)); } /// Create an unconditional 'br label X' instruction. BranchInst *CreateBr(BasicBlock *Dest) { return Insert(BranchInst::Create(Dest)); } /// Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights = nullptr, MDNode *Unpredictable = nullptr) { return Insert(addBranchMetadata(BranchInst::Create(True, False, Cond), BranchWeights, Unpredictable)); } /// Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. Copy branch meta data if available. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, Instruction *MDSrc) { BranchInst *Br = BranchInst::Create(True, False, Cond); if (MDSrc) { unsigned WL[4] = {LLVMContext::MD_prof, LLVMContext::MD_unpredictable, LLVMContext::MD_make_implicit, LLVMContext::MD_dbg}; Br->copyMetadata(*MDSrc, makeArrayRef(&WL[0], 4)); } return Insert(Br); } /// Create a switch instruction with the specified value, default dest, /// and with a hint for the number of cases that will be added (for efficient /// allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, MDNode *BranchWeights = nullptr, MDNode *Unpredictable = nullptr) { return Insert(addBranchMetadata(SwitchInst::Create(V, Dest, NumCases), BranchWeights, Unpredictable)); } /// Create an indirect branch instruction with the specified address /// operand, with an optional hint for the number of destinations that will be /// added (for efficient allocation). IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { return Insert(IndirectBrInst::Create(Addr, NumDests)); } /// Create an invoke instruction. InvokeInst *CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "") { return Insert( InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args, OpBundles), Name); } InvokeInst *CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args = None, const Twine &Name = "") { return Insert(InvokeInst::Create(Ty, Callee, NormalDest, UnwindDest, Args), Name); } InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "") { return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest, UnwindDest, Args, OpBundles, Name); } InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args = None, const Twine &Name = "") { return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest, UnwindDest, Args, Name); } // Deprecated [opaque pointer types] InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "") { return CreateInvoke( cast( cast(Callee->getType())->getElementType()), Callee, NormalDest, UnwindDest, Args, OpBundles, Name); } // Deprecated [opaque pointer types] InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args = None, const Twine &Name = "") { return CreateInvoke( cast( cast(Callee->getType())->getElementType()), Callee, NormalDest, UnwindDest, Args, Name); } ResumeInst *CreateResume(Value *Exn) { return Insert(ResumeInst::Create(Exn)); } CleanupReturnInst *CreateCleanupRet(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB = nullptr) { return Insert(CleanupReturnInst::Create(CleanupPad, UnwindBB)); } CatchSwitchInst *CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, const Twine &Name = "") { return Insert(CatchSwitchInst::Create(ParentPad, UnwindBB, NumHandlers), Name); } CatchPadInst *CreateCatchPad(Value *ParentPad, ArrayRef Args, const Twine &Name = "") { return Insert(CatchPadInst::Create(ParentPad, Args), Name); } CleanupPadInst *CreateCleanupPad(Value *ParentPad, ArrayRef Args = None, const Twine &Name = "") { return Insert(CleanupPadInst::Create(ParentPad, Args), Name); } CatchReturnInst *CreateCatchRet(CatchPadInst *CatchPad, BasicBlock *BB) { return Insert(CatchReturnInst::Create(CatchPad, BB)); } UnreachableInst *CreateUnreachable() { return Insert(new UnreachableInst(Context)); } //===--------------------------------------------------------------------===// // Instruction creation methods: Binary Operators //===--------------------------------------------------------------------===// private: BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name, bool HasNUW, bool HasNSW) { BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); if (HasNUW) BO->setHasNoUnsignedWrap(); if (HasNSW) BO->setHasNoSignedWrap(); return BO; } Instruction *setFPAttrs(Instruction *I, MDNode *FPMD, FastMathFlags FMF) const { if (!FPMD) FPMD = DefaultFPMathTag; if (FPMD) I->setMetadata(LLVMContext::MD_fpmath, FPMD); I->setFastMathFlags(FMF); return I; } Value *foldConstant(Instruction::BinaryOps Opc, Value *L, Value *R, const Twine &Name = nullptr) const { auto *LC = dyn_cast(L); auto *RC = dyn_cast(R); return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr; } public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name, HasNUW, HasNSW); } Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateAdd(LHS, RHS, Name, false, true); } Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateAdd(LHS, RHS, Name, true, false); } Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateSub(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, HasNUW, HasNSW); } Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSub(LHS, RHS, Name, false, true); } Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSub(LHS, RHS, Name, true, false); } Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateMul(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, HasNUW, HasNSW); } Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateMul(LHS, RHS, Name, false, true); } Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateMul(LHS, RHS, Name, true, false); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateUDiv(LC, RC, isExact), Name); if (!isExact) return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name); } Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateUDiv(LHS, RHS, Name, true); } Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateSDiv(LC, RC, isExact), Name); if (!isExact) return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name); return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); } Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSDiv(LHS, RHS, Name, true); } Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::URem, LHS, RHS, Name)) return V; return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); } Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::SRem, LHS, RHS, Name)) return V; return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); } Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name, HasNUW, HasNSW); } Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, HasNUW, HasNSW); } Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name, HasNUW, HasNSW); } Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateLShr(LC, RC, isExact), Name); if (!isExact) return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name); } Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "", bool isExact = false) { return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); } Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "", bool isExact = false) { return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); } Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateAShr(LC, RC, isExact), Name); if (!isExact) return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name); } Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "", bool isExact = false) { return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); } Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "", bool isExact = false) { return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact); } Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { if (auto *RC = dyn_cast(RHS)) { if (isa(RC) && cast(RC)->isMinusOne()) return LHS; // LHS & -1 -> LHS if (auto *LC = dyn_cast(LHS)) return Insert(Folder.CreateAnd(LC, RC), Name); } return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") { return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") { return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { if (auto *RC = dyn_cast(RHS)) { if (RC->isNullValue()) return LHS; // LHS | 0 -> LHS if (auto *LC = dyn_cast(LHS)) return Insert(Folder.CreateOr(LC, RC), Name); } return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") { return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") { return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::Xor, LHS, RHS, Name)) return V; return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); } Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") { return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") { return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name); } Value *CreateFAdd(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMF); return Insert(I, Name); } /// Copy fast-math-flags from an instruction rather than using the builder's /// default FMF. Value *CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), nullptr, FMFSource->getFastMathFlags()); return Insert(I, Name); } Value *CreateFSub(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMF); return Insert(I, Name); } /// Copy fast-math-flags from an instruction rather than using the builder's /// default FMF. Value *CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), nullptr, FMFSource->getFastMathFlags()); return Insert(I, Name); } Value *CreateFMul(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMF); return Insert(I, Name); } /// Copy fast-math-flags from an instruction rather than using the builder's /// default FMF. Value *CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), nullptr, FMFSource->getFastMathFlags()); return Insert(I, Name); } Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMF); return Insert(I, Name); } /// Copy fast-math-flags from an instruction rather than using the builder's /// default FMF. Value *CreateFDivFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr, FMFSource->getFastMathFlags()); return Insert(I, Name); } Value *CreateFRem(Value *L, Value *R, const Twine &Name = "", MDNode *FPMD = nullptr) { if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMF); return Insert(I, Name); } /// Copy fast-math-flags from an instruction rather than using the builder's /// default FMF. Value *CreateFRemFMF(Value *L, Value *R, Instruction *FMFSource, const Twine &Name = "") { if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), nullptr, FMFSource->getFastMathFlags()); return Insert(I, Name); } Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { if (Value *V = foldConstant(Opc, LHS, RHS, Name)) return V; Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS); if (isa(BinOp)) BinOp = setFPAttrs(BinOp, FPMathTag, FMF); return Insert(BinOp, Name); } Value *CreateNeg(Value *V, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name); BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name); if (HasNUW) BO->setHasNoUnsignedWrap(); if (HasNSW) BO->setHasNoSignedWrap(); return BO; } Value *CreateNSWNeg(Value *V, const Twine &Name = "") { return CreateNeg(V, Name, false, true); } Value *CreateNUWNeg(Value *V, const Twine &Name = "") { return CreateNeg(V, Name, true, false); } Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = nullptr) { if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateFNeg(VC), Name); return Insert(setFPAttrs(BinaryOperator::CreateFNeg(V), FPMathTag, FMF), Name); } Value *CreateNot(Value *V, const Twine &Name = "") { if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateNot(VC), Name); return Insert(BinaryOperator::CreateNot(V), Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize = nullptr, const Twine &Name = "") { return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name); } AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr, const Twine &Name = "") { const DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name); } - /// Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of + /// Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of /// converting the string to 'bool' for the isVolatile parameter. - LoadInst *CreateLoad(Value *Ptr, const char *Name) { - return Insert(new LoadInst(Ptr), Name); - } - - LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { - return Insert(new LoadInst(Ptr), Name); + LoadInst *CreateLoad(Type *Ty, Value *Ptr, const char *Name) { + return Insert(new LoadInst(Ty, Ptr), Name); } LoadInst *CreateLoad(Type *Ty, Value *Ptr, const Twine &Name = "") { return Insert(new LoadInst(Ty, Ptr), Name); } + LoadInst *CreateLoad(Type *Ty, Value *Ptr, bool isVolatile, + const Twine &Name = "") { + return Insert(new LoadInst(Ty, Ptr, Twine(), isVolatile), Name); + } + + // Deprecated [opaque pointer types] + LoadInst *CreateLoad(Value *Ptr, const char *Name) { + return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, Name); + } + + // Deprecated [opaque pointer types] + LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") { + return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, Name); + } + + // Deprecated [opaque pointer types] LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") { - return Insert(new LoadInst(Ptr, nullptr, isVolatile), Name); + return CreateLoad(Ptr->getType()->getPointerElementType(), Ptr, isVolatile, + Name); } StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } /// Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' /// correctly, instead of converting the string to 'bool' for the isVolatile /// parameter. - LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { - LoadInst *LI = CreateLoad(Ptr, Name); + LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, + const char *Name) { + LoadInst *LI = CreateLoad(Ty, Ptr, Name); LI->setAlignment(Align); return LI; } - LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, + LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, const Twine &Name = "") { - LoadInst *LI = CreateLoad(Ptr, Name); + LoadInst *LI = CreateLoad(Ty, Ptr, Name); LI->setAlignment(Align); return LI; } - LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile, - const Twine &Name = "") { - LoadInst *LI = CreateLoad(Ptr, isVolatile, Name); + LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align, + bool isVolatile, const Twine &Name = "") { + LoadInst *LI = CreateLoad(Ty, Ptr, isVolatile, Name); LI->setAlignment(Align); return LI; } + // Deprecated [opaque pointer types] + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { + return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, + Align, Name); + } + // Deprecated [opaque pointer types] + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, + const Twine &Name = "") { + return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, + Align, Name); + } + // Deprecated [opaque pointer types] + LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile, + const Twine &Name = "") { + return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr, + Align, isVolatile, Name); + } + StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align, bool isVolatile = false) { StoreInst *SI = CreateStore(Val, Ptr, isVolatile); SI->setAlignment(Align); return SI; } FenceInst *CreateFence(AtomicOrdering Ordering, SyncScope::ID SSID = SyncScope::System, const Twine &Name = "") { return Insert(new FenceInst(Context, Ordering, SSID), Name); } AtomicCmpXchgInst * CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID = SyncScope::System) { return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering, SSID)); } AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, AtomicOrdering Ordering, SyncScope::ID SSID = SyncScope::System) { return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SSID)); } Value *CreateGEP(Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { return CreateGEP(nullptr, Ptr, IdxList, Name); } Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { if (auto *PC = dyn_cast(Ptr)) { // Every index must be constant. size_t i, e; for (i = 0, e = IdxList.size(); i != e; ++i) if (!isa(IdxList[i])) break; if (i == e) return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name); } return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name); } Value *CreateInBoundsGEP(Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { return CreateInBoundsGEP(nullptr, Ptr, IdxList, Name); } Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { if (auto *PC = dyn_cast(Ptr)) { // Every index must be constant. size_t i, e; for (i = 0, e = IdxList.size(); i != e; ++i) if (!isa(IdxList[i])) break; if (i == e) return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList), Name); } return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name); } Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { return CreateGEP(nullptr, Ptr, Idx, Name); } Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") { if (auto *PC = dyn_cast(Ptr)) if (auto *IC = dyn_cast(Idx)) return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name); return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); } Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") { if (auto *PC = dyn_cast(Ptr)) if (auto *IC = dyn_cast(Idx)) return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name); return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); } Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { return CreateConstGEP1_32(nullptr, Ptr, Idx0, Name); } Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name); return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name); return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name); } Value *CreateConstGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { Value *Idxs[] = { ConstantInt::get(Type::getInt32Ty(Context), Idx0), ConstantInt::get(Type::getInt32Ty(Context), Idx1) }; if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name); return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { Value *Idxs[] = { ConstantInt::get(Type::getInt32Ty(Context), Idx0), ConstantInt::get(Type::getInt32Ty(Context), Idx1) }; if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name); return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name); } Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idx), Name); return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idx), Name); return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name); } Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { Value *Idxs[] = { ConstantInt::get(Type::getInt64Ty(Context), Idx0), ConstantInt::get(Type::getInt64Ty(Context), Idx1) }; if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idxs), Name); return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { Value *Idxs[] = { ConstantInt::get(Type::getInt64Ty(Context), Idx0), ConstantInt::get(Type::getInt64Ty(Context), Idx1) }; if (auto *PC = dyn_cast(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idxs), Name); return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name); } Value *CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ty, Ptr, 0, Idx, Name); } Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(nullptr, Ptr, 0, Idx, Name); } /// Same as CreateGlobalString, but return a pointer with "i8*" type /// instead of a pointer to array of i8. Constant *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "", unsigned AddressSpace = 0) { GlobalVariable *GV = CreateGlobalString(Str, Name, AddressSpace); Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Constant *Indices[] = {Zero, Zero}; return ConstantExpr::getInBoundsGetElementPtr(GV->getValueType(), GV, Indices); } //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::Trunc, V, DestTy, Name); } Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::ZExt, V, DestTy, Name); } Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } /// Create a ZExt or Trunc from the integer value V to DestTy. Return /// the value untouched if the type of V is already DestTy. Value *CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { assert(V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && "Can only zero extend/truncate integers!"); Type *VTy = V->getType(); if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) return CreateZExt(V, DestTy, Name); if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) return CreateTrunc(V, DestTy, Name); return V; } /// Create a SExt or Trunc from the integer value V to DestTy. Return /// the value untouched if the type of V is already DestTy. Value *CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { assert(V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && "Can only sign extend/truncate integers!"); Type *VTy = V->getType(); if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits()) return CreateSExt(V, DestTy, Name); if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits()) return CreateTrunc(V, DestTy, Name); return V; } Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToUI, V, DestTy, Name); } Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToSI, V, DestTy, Name); } Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::UIToFP, V, DestTy, Name); } Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::SIToFP, V, DestTy, Name); } Value *CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPTrunc, V, DestTy, Name); } Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPExt, V, DestTy, Name); } Value *CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::PtrToInt, V, DestTy, Name); } Value *CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::IntToPtr, V, DestTy, Name); } Value *CreateBitCast(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::BitCast, V, DestTy, Name); } Value *CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::AddrSpaceCast, V, DestTy, Name); } Value *CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name); } Value *CreateSExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name); } Value *CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name); } Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateCast(Op, VC, DestTy), Name); return Insert(CastInst::Create(Op, V, DestTy), Name); } Value *CreatePointerCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreatePointerCast(VC, DestTy), Name); return Insert(CastInst::CreatePointerCast(V, DestTy), Name); } Value *CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) { return Insert(Folder.CreatePointerBitCastOrAddrSpaceCast(VC, DestTy), Name); } return Insert(CastInst::CreatePointerBitCastOrAddrSpaceCast(V, DestTy), Name); } Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name); return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); } Value *CreateBitOrPointerCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (V->getType()->isPtrOrPtrVectorTy() && DestTy->isIntOrIntVectorTy()) return CreatePtrToInt(V, DestTy, Name); if (V->getType()->isIntOrIntVectorTy() && DestTy->isPtrOrPtrVectorTy()) return CreateIntToPtr(V, DestTy, Name); return CreateBitCast(V, DestTy, Name); } Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (auto *VC = dyn_cast(V)) return Insert(Folder.CreateFPCast(VC, DestTy), Name); return Insert(CastInst::CreateFPCast(V, DestTy), Name); } // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a // compile time error, instead of converting the string to bool for the // isSigned parameter. Value *CreateIntCast(Value *, Type *, const char *) = delete; //===--------------------------------------------------------------------===// // Instruction creation methods: Compare Instructions //===--------------------------------------------------------------------===// Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name); } Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name); } Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name); } Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name); } Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name); } Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name); } Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name); } Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name); } Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name); } Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); } Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name, FPMathTag); } Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name, FPMathTag); } Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name = "") { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateICmp(P, LC, RC), Name); return Insert(new ICmpInst(P, LHS, RHS), Name); } Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { if (auto *LC = dyn_cast(LHS)) if (auto *RC = dyn_cast(RHS)) return Insert(Folder.CreateFCmp(P, LC, RC), Name); return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Other Instructions //===--------------------------------------------------------------------===// PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name = "") { return Insert(PHINode::Create(Ty, NumReservedValues), Name); } CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef Args = None, const Twine &Name = "", MDNode *FPMathTag = nullptr) { CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles); if (isa(CI)) CI = cast(setFPAttrs(CI, FPMathTag, FMF)); return Insert(CI, Name); } CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "", MDNode *FPMathTag = nullptr) { CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles); if (isa(CI)) CI = cast(setFPAttrs(CI, FPMathTag, FMF)); return Insert(CI, Name); } CallInst *CreateCall(Function *Callee, ArrayRef Args = None, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag); } CallInst *CreateCall(Function *Callee, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name, FPMathTag); } // Deprecated [opaque pointer types] CallInst *CreateCall(Value *Callee, ArrayRef Args = None, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateCall( cast(Callee->getType()->getPointerElementType()), Callee, Args, Name, FPMathTag); } // Deprecated [opaque pointer types] CallInst *CreateCall(Value *Callee, ArrayRef Args, ArrayRef OpBundles, const Twine &Name = "", MDNode *FPMathTag = nullptr) { return CreateCall( cast(Callee->getType()->getPointerElementType()), Callee, Args, OpBundles, Name, FPMathTag); } Value *CreateSelect(Value *C, Value *True, Value *False, const Twine &Name = "", Instruction *MDFrom = nullptr) { if (auto *CC = dyn_cast(C)) if (auto *TC = dyn_cast(True)) if (auto *FC = dyn_cast(False)) return Insert(Folder.CreateSelect(CC, TC, FC), Name); SelectInst *Sel = SelectInst::Create(C, True, False); if (MDFrom) { MDNode *Prof = MDFrom->getMetadata(LLVMContext::MD_prof); MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable); Sel = addBranchMetadata(Sel, Prof, Unpred); } return Insert(Sel, Name); } VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") { return Insert(new VAArgInst(List, Ty), Name); } Value *CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name = "") { if (auto *VC = dyn_cast(Vec)) if (auto *IC = dyn_cast(Idx)) return Insert(Folder.CreateExtractElement(VC, IC), Name); return Insert(ExtractElementInst::Create(Vec, Idx), Name); } Value *CreateExtractElement(Value *Vec, uint64_t Idx, const Twine &Name = "") { return CreateExtractElement(Vec, getInt64(Idx), Name); } Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name = "") { if (auto *VC = dyn_cast(Vec)) if (auto *NC = dyn_cast(NewElt)) if (auto *IC = dyn_cast(Idx)) return Insert(Folder.CreateInsertElement(VC, NC, IC), Name); return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name); } Value *CreateInsertElement(Value *Vec, Value *NewElt, uint64_t Idx, const Twine &Name = "") { return CreateInsertElement(Vec, NewElt, getInt64(Idx), Name); } Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name = "") { if (auto *V1C = dyn_cast(V1)) if (auto *V2C = dyn_cast(V2)) if (auto *MC = dyn_cast(Mask)) return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name); return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef IntMask, const Twine &Name = "") { Value *Mask = ConstantDataVector::get(Context, IntMask); return CreateShuffleVector(V1, V2, Mask, Name); } Value *CreateExtractValue(Value *Agg, ArrayRef Idxs, const Twine &Name = "") { if (auto *AggC = dyn_cast(Agg)) return Insert(Folder.CreateExtractValue(AggC, Idxs), Name); return Insert(ExtractValueInst::Create(Agg, Idxs), Name); } Value *CreateInsertValue(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &Name = "") { if (auto *AggC = dyn_cast(Agg)) if (auto *ValC = dyn_cast(Val)) return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name); return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); } LandingPadInst *CreateLandingPad(Type *Ty, unsigned NumClauses, const Twine &Name = "") { return Insert(LandingPadInst::Create(Ty, NumClauses), Name); } //===--------------------------------------------------------------------===// // Utility creation methods //===--------------------------------------------------------------------===// /// Return an i1 value testing if \p Arg is null. Value *CreateIsNull(Value *Arg, const Twine &Name = "") { return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), Name); } /// Return an i1 value testing if \p Arg is not null. Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), Name); } /// Return the i64 difference between two pointer values, dividing out /// the size of the pointed-to objects. /// /// This is intended to implement C-style pointer subtraction. As such, the /// pointers must be appropriately aligned for their element types and /// pointing into the same object. Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") { assert(LHS->getType() == RHS->getType() && "Pointer subtraction operand types must match!"); auto *ArgType = cast(LHS->getType()); Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context)); Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); Value *Difference = CreateSub(LHS_int, RHS_int); return CreateExactSDiv(Difference, ConstantExpr::getSizeOf(ArgType->getElementType()), Name); } /// Create a launder.invariant.group intrinsic call. If Ptr type is /// different from pointer to i8, it's casted to pointer to i8 in the same /// address space before call and casted back to Ptr type after call. Value *CreateLaunderInvariantGroup(Value *Ptr) { assert(isa(Ptr->getType()) && "launder.invariant.group only applies to pointers."); // FIXME: we could potentially avoid casts to/from i8*. auto *PtrType = Ptr->getType(); auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace()); if (PtrType != Int8PtrTy) Ptr = CreateBitCast(Ptr, Int8PtrTy); Module *M = BB->getParent()->getParent(); Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration( M, Intrinsic::launder_invariant_group, {Int8PtrTy}); assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && "LaunderInvariantGroup should take and return the same type"); CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr}); if (PtrType != Int8PtrTy) return CreateBitCast(Fn, PtrType); return Fn; } /// \brief Create a strip.invariant.group intrinsic call. If Ptr type is /// different from pointer to i8, it's casted to pointer to i8 in the same /// address space before call and casted back to Ptr type after call. Value *CreateStripInvariantGroup(Value *Ptr) { assert(isa(Ptr->getType()) && "strip.invariant.group only applies to pointers."); // FIXME: we could potentially avoid casts to/from i8*. auto *PtrType = Ptr->getType(); auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace()); if (PtrType != Int8PtrTy) Ptr = CreateBitCast(Ptr, Int8PtrTy); Module *M = BB->getParent()->getParent(); Function *FnStripInvariantGroup = Intrinsic::getDeclaration( M, Intrinsic::strip_invariant_group, {Int8PtrTy}); assert(FnStripInvariantGroup->getReturnType() == Int8PtrTy && FnStripInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && "StripInvariantGroup should take and return the same type"); CallInst *Fn = CreateCall(FnStripInvariantGroup, {Ptr}); if (PtrType != Int8PtrTy) return CreateBitCast(Fn, PtrType); return Fn; } /// Return a vector value that contains \arg V broadcasted to \p /// NumElts elements. Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") { assert(NumElts > 0 && "Cannot splat to an empty vector!"); // First insert it into an undef vector so we can shuffle it. Type *I32Ty = getInt32Ty(); Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts)); V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0), Name + ".splatinsert"); // Shuffle the value across the desired number of elements. Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts)); return CreateShuffleVector(V, Undef, Zeros, Name + ".splat"); } /// Return a value that has been extracted from a larger integer type. Value *CreateExtractInteger(const DataLayout &DL, Value *From, IntegerType *ExtractedTy, uint64_t Offset, const Twine &Name) { auto *IntTy = cast(From->getType()); assert(DL.getTypeStoreSize(ExtractedTy) + Offset <= DL.getTypeStoreSize(IntTy) && "Element extends past full value"); uint64_t ShAmt = 8 * Offset; Value *V = From; if (DL.isBigEndian()) ShAmt = 8 * (DL.getTypeStoreSize(IntTy) - DL.getTypeStoreSize(ExtractedTy) - Offset); if (ShAmt) { V = CreateLShr(V, ShAmt, Name + ".shift"); } assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() && "Cannot extract to a larger integer!"); if (ExtractedTy != IntTy) { V = CreateTrunc(V, ExtractedTy, Name + ".trunc"); } return V; } private: /// Helper function that creates an assume intrinsic call that /// represents an alignment assumption on the provided Ptr, Mask, Type /// and Offset. It may be sometimes useful to do some other logic /// based on this alignment check, thus it can be stored into 'TheCheck'. CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL, Value *PtrValue, Value *Mask, Type *IntPtrTy, Value *OffsetValue, Value **TheCheck) { Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); if (OffsetValue) { bool IsOffsetZero = false; if (const auto *CI = dyn_cast(OffsetValue)) IsOffsetZero = CI->isZero(); if (!IsOffsetZero) { if (OffsetValue->getType() != IntPtrTy) OffsetValue = CreateIntCast(OffsetValue, IntPtrTy, /*isSigned*/ true, "offsetcast"); PtrIntValue = CreateSub(PtrIntValue, OffsetValue, "offsetptr"); } } Value *Zero = ConstantInt::get(IntPtrTy, 0); Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr"); Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond"); if (TheCheck) *TheCheck = InvCond; return CreateAssumption(InvCond); } public: /// Create an assume intrinsic call that represents an alignment /// assumption on the provided pointer. /// /// An optional offset can be provided, and if it is provided, the offset /// must be subtracted from the provided pointer to get the pointer with the /// specified alignment. /// /// It may be sometimes useful to do some other logic /// based on this alignment check, thus it can be stored into 'TheCheck'. CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, unsigned Alignment, Value *OffsetValue = nullptr, Value **TheCheck = nullptr) { assert(isa(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?"); auto *PtrTy = cast(PtrValue->getType()); Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, OffsetValue, TheCheck); } /// Create an assume intrinsic call that represents an alignment /// assumption on the provided pointer. /// /// An optional offset can be provided, and if it is provided, the offset /// must be subtracted from the provided pointer to get the pointer with the /// specified alignment. /// /// It may be sometimes useful to do some other logic /// based on this alignment check, thus it can be stored into 'TheCheck'. /// /// This overload handles the condition where the Alignment is dependent /// on an existing value rather than a static value. CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, Value *Alignment, Value *OffsetValue = nullptr, Value **TheCheck = nullptr) { assert(isa(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?"); auto *PtrTy = cast(PtrValue->getType()); Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); if (Alignment->getType() != IntPtrTy) Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true, "alignmentcast"); Value *IsPositive = CreateICmp(CmpInst::ICMP_SGT, Alignment, ConstantInt::get(Alignment->getType(), 0), "ispositive"); Value *PositiveMask = CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask"); Value *Mask = CreateSelect(IsPositive, PositiveMask, ConstantInt::get(IntPtrTy, 0), "mask"); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, OffsetValue, TheCheck); } }; // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef) } // end namespace llvm #endif // LLVM_IR_IRBUILDER_H diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 5f0ac907e18c..0ff8f56f213a 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1,4985 +1,4996 @@ //===- llvm/Instructions.h - Instruction subclass 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 exposes the class definitions of all of the subclasses of the // Instruction class. This is meant to be an easy way to get access to all // instruction subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_IR_INSTRUCTIONS_H #define LLVM_IR_INSTRUCTIONS_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include #include #include #include namespace llvm { class APInt; class ConstantInt; class DataLayout; class LLVMContext; //===----------------------------------------------------------------------===// // AllocaInst Class //===----------------------------------------------------------------------===// /// an instruction to allocate memory on the stack class AllocaInst : public UnaryInstruction { Type *AllocatedType; protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; AllocaInst *cloneImpl() const; public: explicit AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize = nullptr, const Twine &Name = "", Instruction *InsertBefore = nullptr); AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, BasicBlock *InsertAtEnd); AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, Instruction *InsertBefore = nullptr); AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, BasicBlock *InsertAtEnd); AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name = "", Instruction *InsertBefore = nullptr); AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd); /// Return true if there is an allocation size parameter to the allocation /// instruction that is not 1. bool isArrayAllocation() const; /// Get the number of elements allocated. For a simple allocation of a single /// element, this will return a constant 1 value. const Value *getArraySize() const { return getOperand(0); } Value *getArraySize() { return getOperand(0); } /// Overload to return most specific pointer type. PointerType *getType() const { return cast(Instruction::getType()); } /// Get allocation size in bits. Returns None if size can't be determined, /// e.g. in case of a VLA. Optional getAllocationSizeInBits(const DataLayout &DL) const; /// Return the type that is being allocated by the instruction. Type *getAllocatedType() const { return AllocatedType; } /// for use only in special circumstances that need to generically /// transform a whole instruction (eg: IR linking and vectorization). void setAllocatedType(Type *Ty) { AllocatedType = Ty; } /// Return the alignment of the memory that is being allocated by the /// instruction. unsigned getAlignment() const { return (1u << (getSubclassDataFromInstruction() & 31)) >> 1; } void setAlignment(unsigned Align); /// Return true if this alloca is in the entry block of the function and is a /// constant size. If so, the code generator will fold it into the /// prolog/epilog code, so it is basically free. bool isStaticAlloca() const; /// Return true if this alloca is used as an inalloca argument to a call. Such /// allocas are never considered static even if they are in the entry block. bool isUsedWithInAlloca() const { return getSubclassDataFromInstruction() & 32; } /// Specify whether this alloca is used to represent the arguments to a call. void setUsedWithInAlloca(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~32) | (V ? 32 : 0)); } /// Return true if this alloca is used as a swifterror argument to a call. bool isSwiftError() const { return getSubclassDataFromInstruction() & 64; } /// Specify whether this alloca is used to represent a swifterror. void setSwiftError(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~64) | (V ? 64 : 0)); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Alloca); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } }; //===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// /// An instruction for reading from memory. This uses the SubclassData field in /// Value to store whether or not the load is volatile. class LoadInst : public UnaryInstruction { void AssertOK(); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; LoadInst *cloneImpl() const; public: - LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore); - LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); - LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile = false, + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false, - Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, - NameStr, isVolatile, InsertBefore) {} - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, + Instruction *InsertBefore = nullptr); + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, - Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, - NameStr, isVolatile, Align, InsertBefore) {} LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, Instruction *InsertBefore = nullptr); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, - AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, - Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, - NameStr, isVolatile, Align, Order, SSID, InsertBefore) {} LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, Instruction *InsertBefore = nullptr); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore); - LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd); - LoadInst(Type *Ty, Value *Ptr, const char *NameStr = nullptr, - bool isVolatile = false, Instruction *InsertBefore = nullptr); - explicit LoadInst(Value *Ptr, const char *NameStr = nullptr, - bool isVolatile = false, + + // Deprecated [opaque pointer types] + explicit LoadInst(Value *Ptr, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, - NameStr, isVolatile, InsertBefore) {} - LoadInst(Value *Ptr, const char *NameStr, bool isVolatile, - BasicBlock *InsertAtEnd); + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + InsertBefore) {} + LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + InsertAtEnd) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + Instruction *InsertBefore = nullptr) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, InsertBefore) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + BasicBlock *InsertAtEnd) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, InsertAtEnd) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + Instruction *InsertBefore = nullptr) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, Align, InsertBefore) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + BasicBlock *InsertAtEnd) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, Align, InsertAtEnd) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, + Instruction *InsertBefore = nullptr) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, Align, Order, SSID, InsertBefore) {} + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd) + : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, + isVolatile, Align, Order, SSID, InsertAtEnd) {} /// Return true if this is a load from a volatile memory location. bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// Specify whether this is a volatile load or not. void setVolatile(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | (V ? 1 : 0)); } /// Return the alignment of the access that is being performed. unsigned getAlignment() const { return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; } void setAlignment(unsigned Align); /// Returns the ordering constraint of this load instruction. AtomicOrdering getOrdering() const { return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7); } /// Sets the ordering constraint of this load instruction. May not be Release /// or AcquireRelease. void setOrdering(AtomicOrdering Ordering) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) | ((unsigned)Ordering << 7)); } /// Returns the synchronization scope ID of this load instruction. SyncScope::ID getSyncScopeID() const { return SSID; } /// Sets the synchronization scope ID of this load instruction. void setSyncScopeID(SyncScope::ID SSID) { this->SSID = SSID; } /// Sets the ordering constraint and the synchronization scope ID of this load /// instruction. void setAtomic(AtomicOrdering Ordering, SyncScope::ID SSID = SyncScope::System) { setOrdering(Ordering); setSyncScopeID(SSID); } bool isSimple() const { return !isAtomic() && !isVolatile(); } bool isUnordered() const { return (getOrdering() == AtomicOrdering::NotAtomic || getOrdering() == AtomicOrdering::Unordered) && !isVolatile(); } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperandType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } /// The synchronization scope ID of this load instruction. Not quite enough /// room in SubClassData for everything, so synchronization scope ID gets its /// own field. SyncScope::ID SSID; }; //===----------------------------------------------------------------------===// // StoreInst Class //===----------------------------------------------------------------------===// /// An instruction for storing to memory. class StoreInst : public Instruction { void AssertOK(); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; StoreInst *cloneImpl() const; public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, Instruction *InsertBefore = nullptr); StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile, unsigned Align, Instruction *InsertBefore = nullptr); StoreInst(Value *Val, Value *Ptr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, Instruction *InsertBefore = nullptr); StoreInst(Value *Val, Value *Ptr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); // allocate space for exactly two operands void *operator new(size_t s) { return User::operator new(s, 2); } /// Return true if this is a store to a volatile memory location. bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// Specify whether this is a volatile store or not. void setVolatile(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | (V ? 1 : 0)); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Return the alignment of the access that is being performed unsigned getAlignment() const { return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; } void setAlignment(unsigned Align); /// Returns the ordering constraint of this store instruction. AtomicOrdering getOrdering() const { return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7); } /// Sets the ordering constraint of this store instruction. May not be /// Acquire or AcquireRelease. void setOrdering(AtomicOrdering Ordering) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) | ((unsigned)Ordering << 7)); } /// Returns the synchronization scope ID of this store instruction. SyncScope::ID getSyncScopeID() const { return SSID; } /// Sets the synchronization scope ID of this store instruction. void setSyncScopeID(SyncScope::ID SSID) { this->SSID = SSID; } /// Sets the ordering constraint and the synchronization scope ID of this /// store instruction. void setAtomic(AtomicOrdering Ordering, SyncScope::ID SSID = SyncScope::System) { setOrdering(Ordering); setSyncScopeID(SSID); } bool isSimple() const { return !isAtomic() && !isVolatile(); } bool isUnordered() const { return (getOrdering() == AtomicOrdering::NotAtomic || getOrdering() == AtomicOrdering::Unordered) && !isVolatile(); } Value *getValueOperand() { return getOperand(0); } const Value *getValueOperand() const { return getOperand(0); } Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperandType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } /// The synchronization scope ID of this store instruction. Not quite enough /// room in SubClassData for everything, so synchronization scope ID gets its /// own field. SyncScope::ID SSID; }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) //===----------------------------------------------------------------------===// // FenceInst Class //===----------------------------------------------------------------------===// /// An instruction for ordering other memory operations. class FenceInst : public Instruction { void Init(AtomicOrdering Ordering, SyncScope::ID SSID); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; FenceInst *cloneImpl() const; public: // Ordering may only be Acquire, Release, AcquireRelease, or // SequentiallyConsistent. FenceInst(LLVMContext &C, AtomicOrdering Ordering, SyncScope::ID SSID = SyncScope::System, Instruction *InsertBefore = nullptr); FenceInst(LLVMContext &C, AtomicOrdering Ordering, SyncScope::ID SSID, BasicBlock *InsertAtEnd); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); } /// Returns the ordering constraint of this fence instruction. AtomicOrdering getOrdering() const { return AtomicOrdering(getSubclassDataFromInstruction() >> 1); } /// Sets the ordering constraint of this fence instruction. May only be /// Acquire, Release, AcquireRelease, or SequentiallyConsistent. void setOrdering(AtomicOrdering Ordering) { setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | ((unsigned)Ordering << 1)); } /// Returns the synchronization scope ID of this fence instruction. SyncScope::ID getSyncScopeID() const { return SSID; } /// Sets the synchronization scope ID of this fence instruction. void setSyncScopeID(SyncScope::ID SSID) { this->SSID = SSID; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Fence; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } /// The synchronization scope ID of this fence instruction. Not quite enough /// room in SubClassData for everything, so synchronization scope ID gets its /// own field. SyncScope::ID SSID; }; //===----------------------------------------------------------------------===// // AtomicCmpXchgInst Class //===----------------------------------------------------------------------===// /// an instruction that atomically checks whether a /// specified value is in a memory location, and, if it is, stores a new value /// there. Returns the value that was loaded. /// class AtomicCmpXchgInst : public Instruction { void Init(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; AtomicCmpXchgInst *cloneImpl() const; public: AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID, Instruction *InsertBefore = nullptr); AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID, BasicBlock *InsertAtEnd); // allocate space for exactly three operands void *operator new(size_t s) { return User::operator new(s, 3); } /// Return true if this is a cmpxchg from a volatile memory /// location. /// bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// Specify whether this is a volatile cmpxchg. /// void setVolatile(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | (unsigned)V); } /// Return true if this cmpxchg may spuriously fail. bool isWeak() const { return getSubclassDataFromInstruction() & 0x100; } void setWeak(bool IsWeak) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x100) | (IsWeak << 8)); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Returns the success ordering constraint of this cmpxchg instruction. AtomicOrdering getSuccessOrdering() const { return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7); } /// Sets the success ordering constraint of this cmpxchg instruction. void setSuccessOrdering(AtomicOrdering Ordering) { assert(Ordering != AtomicOrdering::NotAtomic && "CmpXchg instructions can only be atomic."); setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x1c) | ((unsigned)Ordering << 2)); } /// Returns the failure ordering constraint of this cmpxchg instruction. AtomicOrdering getFailureOrdering() const { return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7); } /// Sets the failure ordering constraint of this cmpxchg instruction. void setFailureOrdering(AtomicOrdering Ordering) { assert(Ordering != AtomicOrdering::NotAtomic && "CmpXchg instructions can only be atomic."); setInstructionSubclassData((getSubclassDataFromInstruction() & ~0xe0) | ((unsigned)Ordering << 5)); } /// Returns the synchronization scope ID of this cmpxchg instruction. SyncScope::ID getSyncScopeID() const { return SSID; } /// Sets the synchronization scope ID of this cmpxchg instruction. void setSyncScopeID(SyncScope::ID SSID) { this->SSID = SSID; } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } Value *getCompareOperand() { return getOperand(1); } const Value *getCompareOperand() const { return getOperand(1); } Value *getNewValOperand() { return getOperand(2); } const Value *getNewValOperand() const { return getOperand(2); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } /// Returns the strongest permitted ordering on failure, given the /// desired ordering on success. /// /// If the comparison in a cmpxchg operation fails, there is no atomic store /// so release semantics cannot be provided. So this function drops explicit /// Release requests from the AtomicOrdering. A SequentiallyConsistent /// operation would remain SequentiallyConsistent. static AtomicOrdering getStrongestFailureOrdering(AtomicOrdering SuccessOrdering) { switch (SuccessOrdering) { default: llvm_unreachable("invalid cmpxchg success ordering"); case AtomicOrdering::Release: case AtomicOrdering::Monotonic: return AtomicOrdering::Monotonic; case AtomicOrdering::AcquireRelease: case AtomicOrdering::Acquire: return AtomicOrdering::Acquire; case AtomicOrdering::SequentiallyConsistent: return AtomicOrdering::SequentiallyConsistent; } } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } /// The synchronization scope ID of this cmpxchg instruction. Not quite /// enough room in SubClassData for everything, so synchronization scope ID /// gets its own field. SyncScope::ID SSID; }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) //===----------------------------------------------------------------------===// // AtomicRMWInst Class //===----------------------------------------------------------------------===// /// an instruction that atomically reads a memory location, /// combines it with another value, and then stores the result back. Returns /// the old value. /// class AtomicRMWInst : public Instruction { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; AtomicRMWInst *cloneImpl() const; public: /// This enumeration lists the possible modifications atomicrmw can make. In /// the descriptions, 'p' is the pointer to the instruction's memory location, /// 'old' is the initial value of *p, and 'v' is the other value passed to the /// instruction. These instructions always return 'old'. enum BinOp { /// *p = v Xchg, /// *p = old + v Add, /// *p = old - v Sub, /// *p = old & v And, /// *p = ~(old & v) Nand, /// *p = old | v Or, /// *p = old ^ v Xor, /// *p = old >signed v ? old : v Max, /// *p = old unsigned v ? old : v UMax, /// *p = old (getSubclassDataFromInstruction() >> 5); } static StringRef getOperationName(BinOp Op); void setOperation(BinOp Operation) { unsigned short SubclassData = getSubclassDataFromInstruction(); setInstructionSubclassData((SubclassData & 31) | (Operation << 5)); } /// Return true if this is a RMW on a volatile memory location. /// bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } /// Specify whether this is a volatile RMW or not. /// void setVolatile(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | (unsigned)V); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Returns the ordering constraint of this rmw instruction. AtomicOrdering getOrdering() const { return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7); } /// Sets the ordering constraint of this rmw instruction. void setOrdering(AtomicOrdering Ordering) { assert(Ordering != AtomicOrdering::NotAtomic && "atomicrmw instructions can only be atomic."); setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 2)) | ((unsigned)Ordering << 2)); } /// Returns the synchronization scope ID of this rmw instruction. SyncScope::ID getSyncScopeID() const { return SSID; } /// Sets the synchronization scope ID of this rmw instruction. void setSyncScopeID(SyncScope::ID SSID) { this->SSID = SSID; } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } Value *getValOperand() { return getOperand(1); } const Value *getValOperand() const { return getOperand(1); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: void Init(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SyncScope::ID SSID); // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } /// The synchronization scope ID of this rmw instruction. Not quite enough /// room in SubClassData for everything, so synchronization scope ID gets its /// own field. SyncScope::ID SSID; }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value) //===----------------------------------------------------------------------===// // GetElementPtrInst Class //===----------------------------------------------------------------------===// // checkGEPType - Simple wrapper function to give a better assertion failure // message on bad indexes for a gep instruction. // inline Type *checkGEPType(Type *Ty) { assert(Ty && "Invalid GetElementPtrInst indices for type!"); return Ty; } /// an instruction for type-safe pointer arithmetic to /// access elements of arrays and structs /// class GetElementPtrInst : public Instruction { Type *SourceElementType; Type *ResultElementType; GetElementPtrInst(const GetElementPtrInst &GEPI); /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. inline GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, Instruction *InsertBefore); inline GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); void init(Value *Ptr, ArrayRef IdxList, const Twine &NameStr); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; GetElementPtrInst *cloneImpl() const; public: static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { unsigned Values = 1 + unsigned(IdxList.size()); if (!PointeeType) PointeeType = cast(Ptr->getType()->getScalarType())->getElementType(); else assert( PointeeType == cast(Ptr->getType()->getScalarType())->getElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertBefore); } static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, ArrayRef IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = 1 + unsigned(IdxList.size()); if (!PointeeType) PointeeType = cast(Ptr->getType()->getScalarType())->getElementType(); else assert( PointeeType == cast(Ptr->getType()->getScalarType())->getElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertAtEnd); } /// Create an "inbounds" getelementptr. See the documentation for the /// "inbounds" flag in LangRef.html for details. static GetElementPtrInst *CreateInBounds(Value *Ptr, ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr){ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore); } static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { GetElementPtrInst *GEP = Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore); GEP->setIsInBounds(true); return GEP; } static GetElementPtrInst *CreateInBounds(Value *Ptr, ArrayRef IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd); } static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { GetElementPtrInst *GEP = Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd); GEP->setIsInBounds(true); return GEP; } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Type *getSourceElementType() const { return SourceElementType; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; } void setResultElementType(Type *Ty) { ResultElementType = Ty; } Type *getResultElementType() const { assert(ResultElementType == cast(getType()->getScalarType())->getElementType()); return ResultElementType; } /// Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { // Note that this is always the same as the pointer operand's address space // and that is cheaper to compute, so cheat here. return getPointerAddressSpace(); } /// Returns the type of the element that would be loaded with /// a load instruction with the specified parameters. /// /// Null is returned if the indices are invalid for the specified /// pointer type. /// static Type *getIndexedType(Type *Ty, ArrayRef IdxList); static Type *getIndexedType(Type *Ty, ArrayRef IdxList); static Type *getIndexedType(Type *Ty, ArrayRef IdxList); inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } inline op_iterator idx_end() { return op_end(); } inline const_op_iterator idx_end() const { return op_end(); } inline iterator_range indices() { return make_range(idx_begin(), idx_end()); } inline iterator_range indices() const { return make_range(idx_begin(), idx_end()); } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; // get index for modifying correct operand. } /// Method to return the pointer operand as a /// PointerType. Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperandType()->getPointerAddressSpace(); } /// Returns the pointer type returned by the GEP /// instruction, which may be a vector of pointers. static Type *getGEPReturnType(Value *Ptr, ArrayRef IdxList) { return getGEPReturnType( cast(Ptr->getType()->getScalarType())->getElementType(), Ptr, IdxList); } static Type *getGEPReturnType(Type *ElTy, Value *Ptr, ArrayRef IdxList) { Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)), Ptr->getType()->getPointerAddressSpace()); // Vector GEP if (Ptr->getType()->isVectorTy()) { unsigned NumElem = Ptr->getType()->getVectorNumElements(); return VectorType::get(PtrTy, NumElem); } for (Value *Index : IdxList) if (Index->getType()->isVectorTy()) { unsigned NumElem = Index->getType()->getVectorNumElements(); return VectorType::get(PtrTy, NumElem); } // Scalar GEP return PtrTy; } unsigned getNumIndices() const { // Note: always non-negative return getNumOperands() - 1; } bool hasIndices() const { return getNumOperands() > 1; } /// Return true if all of the indices of this GEP are /// zeros. If so, the result pointer and the first operand have the same /// value, just potentially different types. bool hasAllZeroIndices() const; /// Return true if all of the indices of this GEP are /// constant integers. If so, the result pointer and the first operand have /// a constant offset between them. bool hasAllConstantIndices() const; /// Set or clear the inbounds flag on this GEP instruction. /// See LangRef.html for the meaning of inbounds on a getelementptr. void setIsInBounds(bool b = true); /// Determine whether the GEP has the inbounds flag. bool isInBounds() const; /// Accumulate the constant address offset of this GEP if possible. /// /// This routine accepts an APInt into which it will accumulate the constant /// offset of this GEP if the GEP is in fact constant. If the GEP is not /// all-constant, it returns false and the value of the offset APInt is /// undefined (it is *not* preserved!). The APInt passed into this routine /// must be at least as wide as the IntPtr type for the address space of /// the base GEP pointer. bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public VariadicOperandTraits { }; GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertBefore), SourceElementType(PointeeType), ResultElementType(getIndexedType(PointeeType, IdxList)) { assert(ResultElementType == cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, ArrayRef IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertAtEnd), SourceElementType(PointeeType), ResultElementType(getIndexedType(PointeeType, IdxList)) { assert(ResultElementType == cast(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) //===----------------------------------------------------------------------===// // UnaryOperator Class //===----------------------------------------------------------------------===// /// a unary instruction class UnaryOperator : public UnaryInstruction { void AssertOK(); protected: UnaryOperator(UnaryOps iType, Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore); UnaryOperator(UnaryOps iType, Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; UnaryOperator *cloneImpl() const; public: /// Construct a unary instruction, given the opcode and an operand. /// Optionally (if InstBefore is specified) insert the instruction /// into a BasicBlock right before the specified instruction. The specified /// Instruction is allowed to be a dereferenced end iterator. /// static UnaryOperator *Create(UnaryOps Op, Value *S, const Twine &Name = Twine(), Instruction *InsertBefore = nullptr); /// Construct a unary instruction, given the opcode and an operand. /// Also automatically insert this instruction to the end of the /// BasicBlock specified. /// static UnaryOperator *Create(UnaryOps Op, Value *S, const Twine &Name, BasicBlock *InsertAtEnd); /// These methods just forward to Create, and are useful when you /// statically know what type of instruction you're going to create. These /// helpers just save some typing. #define HANDLE_UNARY_INST(N, OPC, CLASS) \ static UnaryInstruction *Create##OPC(Value *V, \ const Twine &Name = "") {\ return Create(Instruction::OPC, V, Name);\ } #include "llvm/IR/Instruction.def" #define HANDLE_UNARY_INST(N, OPC, CLASS) \ static UnaryInstruction *Create##OPC(Value *V, \ const Twine &Name, BasicBlock *BB) {\ return Create(Instruction::OPC, V, Name, BB);\ } #include "llvm/IR/Instruction.def" #define HANDLE_UNARY_INST(N, OPC, CLASS) \ static UnaryInstruction *Create##OPC(Value *V, \ const Twine &Name, Instruction *I) {\ return Create(Instruction::OPC, V, Name, I);\ } #include "llvm/IR/Instruction.def" UnaryOps getOpcode() const { return static_cast(Instruction::getOpcode()); } }; //===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// /// This instruction compares its operands according to the predicate given /// to the constructor. It only operates on integers or pointers. The operands /// must be identical types. /// Represent an integer comparison operator. class ICmpInst: public CmpInst { void AssertOK() { assert(isIntPredicate() && "Invalid ICmp predicate value"); 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()->isIntOrIntVectorTy() || getOperand(0)->getType()->isPtrOrPtrVectorTy()) && "Invalid operand types for ICmp instruction"); } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical ICmpInst ICmpInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics. ICmpInst( Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::ICmp, pred, LHS, RHS, NameStr, InsertBefore) { #ifndef NDEBUG AssertOK(); #endif } /// Constructor with insert-at-end semantics. ICmpInst( BasicBlock &InsertAtEnd, ///< Block to insert into. Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::ICmp, pred, LHS, RHS, NameStr, &InsertAtEnd) { #ifndef NDEBUG AssertOK(); #endif } /// Constructor with no-insertion semantics ICmpInst( Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::ICmp, pred, LHS, RHS, NameStr) { #ifndef NDEBUG AssertOK(); #endif } /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc. /// @returns the predicate that would be the result if the operand were /// regarded as signed. /// Return the signed version of the predicate Predicate getSignedPredicate() const { return getSignedPredicate(getPredicate()); } /// This is a static version that you can use without an instruction. /// Return the signed version of the predicate. static Predicate getSignedPredicate(Predicate pred); /// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc. /// @returns the predicate that would be the result if the operand were /// regarded as unsigned. /// Return the unsigned version of the predicate Predicate getUnsignedPredicate() const { return getUnsignedPredicate(getPredicate()); } /// This is a static version that you can use without an instruction. /// Return the unsigned version of the predicate. static Predicate getUnsignedPredicate(Predicate pred); /// Return true if this predicate is either EQ or NE. This also /// tests for commutativity. static bool isEquality(Predicate P) { return P == ICMP_EQ || P == ICMP_NE; } /// Return true if this predicate is either EQ or NE. This also /// tests for commutativity. bool isEquality() const { return isEquality(getPredicate()); } /// @returns true if the predicate of this ICmpInst is commutative /// Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } /// Return true if the predicate is relational (not EQ or NE). /// bool isRelational() const { return !isEquality(); } /// Return true if the predicate is relational (not EQ or NE). /// static bool isRelational(Predicate P) { return !isEquality(P); } /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent /// (e.g. ult). /// Swap operands and adjust predicate. void swapOperands() { setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // FCmpInst Class //===----------------------------------------------------------------------===// /// This instruction compares its operands according to the predicate given /// to the constructor. It only operates on floating point values or packed /// vectors of floating point values. The operands must be identical types. /// Represents a floating point comparison operator. class FCmpInst: public CmpInst { void AssertOK() { assert(isFPPredicate() && "Invalid FCmp predicate value"); 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()->isFPOrFPVectorTy() && "Invalid operand types for FCmp instruction"); } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical FCmpInst FCmpInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics. FCmpInst( Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS, RHS, NameStr, InsertBefore) { AssertOK(); } /// Constructor with insert-at-end semantics. FCmpInst( BasicBlock &InsertAtEnd, ///< Block to insert into. Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS, RHS, NameStr, &InsertAtEnd) { AssertOK(); } /// Constructor with no-insertion semantics FCmpInst( Predicate Pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression const Twine &NameStr = "", ///< Name of the instruction Instruction *FlagsSource = nullptr ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, Pred, LHS, RHS, NameStr, nullptr, FlagsSource) { AssertOK(); } /// @returns true if the predicate of this instruction is EQ or NE. /// Determine if this is an equality predicate. static bool isEquality(Predicate Pred) { return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ || Pred == FCMP_UNE; } /// @returns true if the predicate of this instruction is EQ or NE. /// Determine if this is an equality predicate. bool isEquality() const { return isEquality(getPredicate()); } /// @returns true if the predicate of this instruction is commutative. /// Determine if this is a commutative predicate. bool isCommutative() const { return isEquality() || getPredicate() == FCMP_FALSE || getPredicate() == FCMP_TRUE || getPredicate() == FCMP_ORD || getPredicate() == FCMP_UNO; } /// @returns true if the predicate is relational (not EQ or NE). /// Determine if this a relational predicate. bool isRelational() const { return !isEquality(); } /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent /// (e.g. ult). /// Swap operands and adjust predicate. void swapOperands() { setPredicate(getSwappedPredicate()); Op<0>().swap(Op<1>()); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::FCmp; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// /// This class represents a function call, abstracting a target /// machine's calling convention. This class uses low bit of the SubClassData /// field to indicate whether or not this is a tail call. The rest of the bits /// hold the calling convention of the call. /// class CallInst : public CallBase { CallInst(const CallInst &CI); /// Construct a CallInst given a range of arguments. /// Construct a CallInst from a range of arguments inline CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, Instruction *InsertBefore); inline CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore) : CallInst(Ty, Func, Args, None, NameStr, InsertBefore) {} /// Construct a CallInst given a range of arguments. /// Construct a CallInst from a range of arguments inline CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd); explicit CallInst(FunctionType *Ty, Value *F, const Twine &NameStr, Instruction *InsertBefore); CallInst(FunctionType *ty, Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); void init(FunctionType *FTy, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr); void init(FunctionType *FTy, Value *Func, const Twine &NameStr); /// Compute the number of operands to allocate. static int ComputeNumOperands(int NumArgs, int NumBundleInputs = 0) { // We need one operand for the called function, plus the input operand // counts provided. return 1 + NumArgs + NumBundleInputs; } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; CallInst *cloneImpl() const; public: static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new (ComputeNumOperands(0)) CallInst(Ty, F, NameStr, InsertBefore); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { return new (ComputeNumOperands(Args.size())) CallInst(Ty, Func, Args, None, NameStr, InsertBefore); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { const int NumOperands = ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)); const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); return new (NumOperands, DescriptorBytes) CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore); } static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new (ComputeNumOperands(0)) CallInst(Ty, F, NameStr, InsertAtEnd); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new (ComputeNumOperands(Args.size())) CallInst(Ty, Func, Args, None, NameStr, InsertAtEnd); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { const int NumOperands = ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)); const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); return new (NumOperands, DescriptorBytes) CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd); } static CallInst *Create(Function *Func, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(Func->getFunctionType(), Func, NameStr, InsertBefore); } static CallInst *Create(Function *Func, ArrayRef Args, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore); } static CallInst *Create(Function *Func, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd); } static CallInst *Create(Function *Func, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast( cast(Func->getType())->getElementType()), Func, NameStr, InsertBefore); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(cast( cast(Func->getType())->getElementType()), Func, Args, NameStr, InsertBefore); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, ArrayRef Args, ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast( cast(Func->getType())->getElementType()), Func, Args, Bundles, NameStr, InsertBefore); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(cast( cast(Func->getType())->getElementType()), Func, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(cast( cast(Func->getType())->getElementType()), Func, Args, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] static CallInst *Create(Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(cast( cast(Func->getType())->getElementType()), Func, Args, Bundles, NameStr, InsertAtEnd); } /// Create a clone of \p CI with a different set of operand bundles and /// insert it before \p InsertPt. /// /// The returned call instruction is identical \p CI in every way except that /// the operand bundles for the new instruction are set to the operand bundles /// in \p Bundles. static CallInst *Create(CallInst *CI, ArrayRef Bundles, Instruction *InsertPt = nullptr); /// Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not /// constant 1. /// 2. Call malloc with that argument. /// 3. Bitcast the result of the malloc call to the specified type. static Instruction *CreateMalloc(Instruction *InsertBefore, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = nullptr, Function *MallocF = nullptr, const Twine &Name = ""); static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = nullptr, Function *MallocF = nullptr, const Twine &Name = ""); static Instruction *CreateMalloc(Instruction *InsertBefore, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = nullptr, ArrayRef Bundles = None, Function *MallocF = nullptr, const Twine &Name = ""); static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = nullptr, ArrayRef Bundles = None, Function *MallocF = nullptr, const Twine &Name = ""); /// Generate the IR for a call to the builtin free function. static Instruction *CreateFree(Value *Source, Instruction *InsertBefore); static Instruction *CreateFree(Value *Source, BasicBlock *InsertAtEnd); static Instruction *CreateFree(Value *Source, ArrayRef Bundles, Instruction *InsertBefore); static Instruction *CreateFree(Value *Source, ArrayRef Bundles, BasicBlock *InsertAtEnd); // Note that 'musttail' implies 'tail'. enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2, TCK_NoTail = 3 }; TailCallKind getTailCallKind() const { return TailCallKind(getSubclassDataFromInstruction() & 3); } bool isTailCall() const { unsigned Kind = getSubclassDataFromInstruction() & 3; return Kind == TCK_Tail || Kind == TCK_MustTail; } bool isMustTailCall() const { return (getSubclassDataFromInstruction() & 3) == TCK_MustTail; } bool isNoTailCall() const { return (getSubclassDataFromInstruction() & 3) == TCK_NoTail; } void setTailCall(bool isTC = true) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | unsigned(isTC ? TCK_Tail : TCK_None)); } void setTailCallKind(TailCallKind TCK) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) | unsigned(TCK)); } /// Return true if the call can return twice bool canReturnTwice() const { return hasFnAttr(Attribute::ReturnsTwice); } void setCanReturnTwice() { addAttribute(AttributeList::FunctionIndex, Attribute::ReturnsTwice); } /// Check if this call is an inline asm statement. bool isInlineAsm() const { return isa(getCalledOperand()); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } }; CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) : CallBase(Ty->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - (Args.size() + CountBundleInputs(Bundles) + 1), unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertAtEnd) { init(Ty, Func, Args, Bundles, NameStr); } CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, Instruction *InsertBefore) : CallBase(Ty->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - (Args.size() + CountBundleInputs(Bundles) + 1), unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertBefore) { init(Ty, Func, Args, Bundles, NameStr); } //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// /// This class represents the LLVM 'select' instruction. /// class SelectInst : public Instruction { SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr, Instruction *InsertBefore) : Instruction(S1->getType(), Instruction::Select, &Op<0>(), 3, InsertBefore) { init(C, S1, S2); setName(NameStr); } SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(S1->getType(), Instruction::Select, &Op<0>(), 3, InsertAtEnd) { init(C, S1, S2); setName(NameStr); } void init(Value *C, Value *S1, Value *S2) { assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select"); Op<0>() = C; Op<1>() = S1; Op<2>() = S2; } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; SelectInst *cloneImpl() const; public: static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr = "", Instruction *InsertBefore = nullptr, Instruction *MDFrom = nullptr) { SelectInst *Sel = new(3) SelectInst(C, S1, S2, NameStr, InsertBefore); if (MDFrom) Sel->copyMetadata(*MDFrom); return Sel; } static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new(3) SelectInst(C, S1, S2, NameStr, InsertAtEnd); } const Value *getCondition() const { return Op<0>(); } const Value *getTrueValue() const { return Op<1>(); } const Value *getFalseValue() const { return Op<2>(); } Value *getCondition() { return Op<0>(); } Value *getTrueValue() { return Op<1>(); } Value *getFalseValue() { return Op<2>(); } void setCondition(Value *V) { Op<0>() = V; } void setTrueValue(Value *V) { Op<1>() = V; } void setFalseValue(Value *V) { Op<2>() = V; } /// Return a string if the specified operands are invalid /// for a select operation, otherwise return null. static const char *areInvalidOperands(Value *Cond, Value *True, Value *False); /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Select; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value) //===----------------------------------------------------------------------===// // VAArgInst Class //===----------------------------------------------------------------------===// /// This class represents the va_arg llvm instruction, which returns /// an argument of the specified type given a va_list and increments that list /// class VAArgInst : public UnaryInstruction { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; VAArgInst *cloneImpl() const; public: VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) : UnaryInstruction(Ty, VAArg, List, InsertBefore) { setName(NameStr); } VAArgInst(Value *List, Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) { setName(NameStr); } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == VAArg; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // ExtractElementInst Class //===----------------------------------------------------------------------===// /// This instruction extracts a single (scalar) /// element from a VectorType value /// class ExtractElementInst : public Instruction { ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; ExtractElementInst *cloneImpl() const; public: static ExtractElementInst *Create(Value *Vec, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertBefore); } static ExtractElementInst *Create(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertAtEnd); } /// Return true if an extractelement instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *Idx); Value *getVectorOperand() { return Op<0>(); } Value *getIndexOperand() { return Op<1>(); } const Value *getVectorOperand() const { return Op<0>(); } const Value *getIndexOperand() const { return Op<1>(); } VectorType *getVectorOperandType() const { return cast(getVectorOperand()->getType()); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractElement; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value) //===----------------------------------------------------------------------===// // InsertElementInst Class //===----------------------------------------------------------------------===// /// This instruction inserts a single (scalar) /// element into a VectorType value /// class InsertElementInst : public Instruction { InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; InsertElementInst *cloneImpl() const; public: static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore); } static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertAtEnd); } /// Return true if an insertelement instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *NewElt, const Value *Idx); /// Overload to return most specific vector type. /// VectorType *getType() const { return cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertElement; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) //===----------------------------------------------------------------------===// // ShuffleVectorInst Class //===----------------------------------------------------------------------===// /// This instruction constructs a fixed permutation of two /// input vectors. /// class ShuffleVectorInst : public Instruction { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; ShuffleVectorInst *cloneImpl() const; public: ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &NameStr = "", Instruction *InsertBefor = nullptr); ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &NameStr, BasicBlock *InsertAtEnd); // allocate space for exactly three operands void *operator new(size_t s) { return User::operator new(s, 3); } /// Return true if a shufflevector instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask); /// Overload to return most specific vector type. /// VectorType *getType() const { return cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Constant *getMask() const { return cast(getOperand(2)); } /// Return the shuffle mask value for the specified element of the mask. /// Return -1 if the element is undef. static int getMaskValue(const Constant *Mask, unsigned Elt); /// Return the shuffle mask value of this instruction for the given element /// index. Return -1 if the element is undef. int getMaskValue(unsigned Elt) const { return getMaskValue(getMask(), Elt); } /// Convert the input shuffle mask operand to a vector of integers. Undefined /// elements of the mask are returned as -1. static void getShuffleMask(const Constant *Mask, SmallVectorImpl &Result); /// Return the mask for this instruction as a vector of integers. Undefined /// elements of the mask are returned as -1. void getShuffleMask(SmallVectorImpl &Result) const { return getShuffleMask(getMask(), Result); } SmallVector getShuffleMask() const { SmallVector Mask; getShuffleMask(Mask); return Mask; } /// Return true if this shuffle returns a vector with a different number of /// elements than its source vectors. /// Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3> /// shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5> bool changesLength() const { unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements(); unsigned NumMaskElts = getMask()->getType()->getVectorNumElements(); return NumSourceElts != NumMaskElts; } /// Return true if this shuffle returns a vector with a greater number of /// elements than its source vectors. /// Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3> bool increasesLength() const { unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements(); unsigned NumMaskElts = getMask()->getType()->getVectorNumElements(); return NumSourceElts < NumMaskElts; } /// Return true if this shuffle mask chooses elements from exactly one source /// vector. /// Example: <7,5,undef,7> /// This assumes that vector operands are the same length as the mask. static bool isSingleSourceMask(ArrayRef Mask); static bool isSingleSourceMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isSingleSourceMask(MaskAsInts); } /// Return true if this shuffle chooses elements from exactly one source /// vector without changing the length of that vector. /// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3> /// TODO: Optionally allow length-changing shuffles. bool isSingleSource() const { return !changesLength() && isSingleSourceMask(getMask()); } /// Return true if this shuffle mask chooses elements from exactly one source /// vector without lane crossings. A shuffle using this mask is not /// necessarily a no-op because it may change the number of elements from its /// input vectors or it may provide demanded bits knowledge via undef lanes. /// Example: static bool isIdentityMask(ArrayRef Mask); static bool isIdentityMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isIdentityMask(MaskAsInts); } /// Return true if this shuffle chooses elements from exactly one source /// vector without lane crossings and does not change the number of elements /// from its input vectors. /// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef> bool isIdentity() const { return !changesLength() && isIdentityMask(getShuffleMask()); } /// Return true if this shuffle lengthens exactly one source vector with /// undefs in the high elements. bool isIdentityWithPadding() const; /// Return true if this shuffle extracts the first N elements of exactly one /// source vector. bool isIdentityWithExtract() const; /// Return true if this shuffle concatenates its 2 source vectors. This /// returns false if either input is undefined. In that case, the shuffle is /// is better classified as an identity with padding operation. bool isConcat() const; /// Return true if this shuffle mask chooses elements from its source vectors /// without lane crossings. A shuffle using this mask would be /// equivalent to a vector select with a constant condition operand. /// Example: <4,1,6,undef> /// This returns false if the mask does not choose from both input vectors. /// In that case, the shuffle is better classified as an identity shuffle. /// This assumes that vector operands are the same length as the mask /// (a length-changing shuffle can never be equivalent to a vector select). static bool isSelectMask(ArrayRef Mask); static bool isSelectMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isSelectMask(MaskAsInts); } /// Return true if this shuffle chooses elements from its source vectors /// without lane crossings and all operands have the same number of elements. /// In other words, this shuffle is equivalent to a vector select with a /// constant condition operand. /// Example: shufflevector <4 x n> A, <4 x n> B, /// This returns false if the mask does not choose from both input vectors. /// In that case, the shuffle is better classified as an identity shuffle. /// TODO: Optionally allow length-changing shuffles. bool isSelect() const { return !changesLength() && isSelectMask(getMask()); } /// Return true if this shuffle mask swaps the order of elements from exactly /// one source vector. /// Example: <7,6,undef,4> /// This assumes that vector operands are the same length as the mask. static bool isReverseMask(ArrayRef Mask); static bool isReverseMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isReverseMask(MaskAsInts); } /// Return true if this shuffle swaps the order of elements from exactly /// one source vector. /// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef> /// TODO: Optionally allow length-changing shuffles. bool isReverse() const { return !changesLength() && isReverseMask(getMask()); } /// Return true if this shuffle mask chooses all elements with the same value /// as the first element of exactly one source vector. /// Example: <4,undef,undef,4> /// This assumes that vector operands are the same length as the mask. static bool isZeroEltSplatMask(ArrayRef Mask); static bool isZeroEltSplatMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isZeroEltSplatMask(MaskAsInts); } /// Return true if all elements of this shuffle are the same value as the /// first element of exactly one source vector without changing the length /// of that vector. /// Example: shufflevector <4 x n> A, <4 x n> B, /// TODO: Optionally allow length-changing shuffles. /// TODO: Optionally allow splats from other elements. bool isZeroEltSplat() const { return !changesLength() && isZeroEltSplatMask(getMask()); } /// Return true if this shuffle mask is a transpose mask. /// Transpose vector masks transpose a 2xn matrix. They read corresponding /// even- or odd-numbered vector elements from two n-dimensional source /// vectors and write each result into consecutive elements of an /// n-dimensional destination vector. Two shuffles are necessary to complete /// the transpose, one for the even elements and another for the odd elements. /// This description closely follows how the TRN1 and TRN2 AArch64 /// instructions operate. /// /// For example, a simple 2x2 matrix can be transposed with: /// /// ; Original matrix /// m0 = < a, b > /// m1 = < c, d > /// /// ; Transposed matrix /// t0 = < a, c > = shufflevector m0, m1, < 0, 2 > /// t1 = < b, d > = shufflevector m0, m1, < 1, 3 > /// /// For matrices having greater than n columns, the resulting nx2 transposed /// matrix is stored in two result vectors such that one vector contains /// interleaved elements from all the even-numbered rows and the other vector /// contains interleaved elements from all the odd-numbered rows. For example, /// a 2x4 matrix can be transposed with: /// /// ; Original matrix /// m0 = < a, b, c, d > /// m1 = < e, f, g, h > /// /// ; Transposed matrix /// t0 = < a, e, c, g > = shufflevector m0, m1 < 0, 4, 2, 6 > /// t1 = < b, f, d, h > = shufflevector m0, m1 < 1, 5, 3, 7 > static bool isTransposeMask(ArrayRef Mask); static bool isTransposeMask(const Constant *Mask) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isTransposeMask(MaskAsInts); } /// Return true if this shuffle transposes the elements of its inputs without /// changing the length of the vectors. This operation may also be known as a /// merge or interleave. See the description for isTransposeMask() for the /// exact specification. /// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6> bool isTranspose() const { return !changesLength() && isTransposeMask(getMask()); } /// Return true if this shuffle mask is an extract subvector mask. /// A valid extract subvector mask returns a smaller vector from a single /// source operand. The base extraction index is returned as well. static bool isExtractSubvectorMask(ArrayRef Mask, int NumSrcElts, int &Index); static bool isExtractSubvectorMask(const Constant *Mask, int NumSrcElts, int &Index) { assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant."); SmallVector MaskAsInts; getShuffleMask(Mask, MaskAsInts); return isExtractSubvectorMask(MaskAsInts, NumSrcElts, Index); } /// Return true if this shuffle mask is an extract subvector mask. bool isExtractSubvectorMask(int &Index) const { int NumSrcElts = Op<0>()->getType()->getVectorNumElements(); return isExtractSubvectorMask(getMask(), NumSrcElts, Index); } /// Change values in a shuffle permute mask assuming the two vector operands /// of length InVecNumElts have swapped position. static void commuteShuffleMask(MutableArrayRef Mask, unsigned InVecNumElts) { for (int &Idx : Mask) { if (Idx == -1) continue; Idx = Idx < (int)InVecNumElts ? Idx + InVecNumElts : Idx - InVecNumElts; assert(Idx >= 0 && Idx < (int)InVecNumElts * 2 && "shufflevector mask index out of range"); } } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value) //===----------------------------------------------------------------------===// // ExtractValueInst Class //===----------------------------------------------------------------------===// /// This instruction extracts a struct member or array /// element value from an aggregate value. /// class ExtractValueInst : public UnaryInstruction { SmallVector Indices; ExtractValueInst(const ExtractValueInst &EVI); /// Constructors - Create a extractvalue instruction with a base aggregate /// value and a list of indices. The first ctor can optionally insert before /// an existing instruction, the second appends the new instruction to the /// specified BasicBlock. inline ExtractValueInst(Value *Agg, ArrayRef Idxs, const Twine &NameStr, Instruction *InsertBefore); inline ExtractValueInst(Value *Agg, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd); void init(ArrayRef Idxs, const Twine &NameStr); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; ExtractValueInst *cloneImpl() const; public: static ExtractValueInst *Create(Value *Agg, ArrayRef Idxs, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new ExtractValueInst(Agg, Idxs, NameStr, InsertBefore); } static ExtractValueInst *Create(Value *Agg, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd); } /// Returns the type of the element that would be extracted /// with an extractvalue instruction with the specified parameters. /// /// Null is returned if the indices are invalid for the specified type. static Type *getIndexedType(Type *Agg, ArrayRef Idxs); using idx_iterator = const unsigned*; inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { return getOperand(0); } const Value *getAggregateOperand() const { return getOperand(0); } static unsigned getAggregateOperandIndex() { return 0U; // get index for modifying correct operand } ArrayRef getIndices() const { return Indices; } unsigned getNumIndices() const { return (unsigned)Indices.size(); } bool hasIndices() const { return true; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractValue; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; ExtractValueInst::ExtractValueInst(Value *Agg, ArrayRef Idxs, const Twine &NameStr, Instruction *InsertBefore) : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)), ExtractValue, Agg, InsertBefore) { init(Idxs, NameStr); } ExtractValueInst::ExtractValueInst(Value *Agg, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)), ExtractValue, Agg, InsertAtEnd) { init(Idxs, NameStr); } //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// /// This instruction inserts a struct field of array element /// value into an aggregate value. /// class InsertValueInst : public Instruction { SmallVector Indices; InsertValueInst(const InsertValueInst &IVI); /// Constructors - Create a insertvalue instruction with a base aggregate /// value, a value to insert, and a list of indices. The first ctor can /// optionally insert before an existing instruction, the second appends /// the new instruction to the specified BasicBlock. inline InsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr, Instruction *InsertBefore); inline InsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd); /// Constructors - These two constructors are convenience methods because one /// and two index insertvalue instructions are so common. InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); void init(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; InsertValueInst *cloneImpl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { return User::operator new(s, 2); } static InsertValueInst *Create(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore); } static InsertValueInst *Create(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); using idx_iterator = const unsigned*; inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { return getOperand(0); } const Value *getAggregateOperand() const { return getOperand(0); } static unsigned getAggregateOperandIndex() { return 0U; // get index for modifying correct operand } Value *getInsertedValueOperand() { return getOperand(1); } const Value *getInsertedValueOperand() const { return getOperand(1); } static unsigned getInsertedValueOperandIndex() { return 1U; // get index for modifying correct operand } ArrayRef getIndices() const { return Indices; } unsigned getNumIndices() const { return (unsigned)Indices.size(); } bool hasIndices() const { return true; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertValue; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; InsertValueInst::InsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr, Instruction *InsertBefore) : Instruction(Agg->getType(), InsertValue, OperandTraits::op_begin(this), 2, InsertBefore) { init(Agg, Val, Idxs, NameStr); } InsertValueInst::InsertValueInst(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Agg->getType(), InsertValue, OperandTraits::op_begin(this), 2, InsertAtEnd) { init(Agg, Val, Idxs, NameStr); } DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// // PHINode - The PHINode class is used to represent the magical mystical PHI // node, that can not exist in nature, but can be synthesized in a computer // scientist's overactive imagination. // class PHINode : public Instruction { /// The number of operands actually allocated. NumOperands is /// the number actually in use. unsigned ReservedSpace; PHINode(const PHINode &PN); explicit PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore), ReservedSpace(NumReservedValues) { setName(NameStr); allocHungoffUses(ReservedSpace); } PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertAtEnd), ReservedSpace(NumReservedValues) { setName(NameStr); allocHungoffUses(ReservedSpace); } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; PHINode *cloneImpl() const; // allocHungoffUses - this is more complicated than the generic // User::allocHungoffUses, because we have to allocate Uses for the incoming // values and pointers to the incoming blocks, all in one allocation. void allocHungoffUses(unsigned N) { User::allocHungoffUses(N, /* IsPhi */ true); } public: /// Constructors - NumReservedValues is a hint for the number of incoming /// edges that this phi node will have (use 0 if you really have no idea). static PHINode *Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore); } static PHINode *Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Block iterator interface. This provides access to the list of incoming // basic blocks, which parallels the list of incoming values. using block_iterator = BasicBlock **; using const_block_iterator = BasicBlock * const *; block_iterator block_begin() { Use::UserRef *ref = reinterpret_cast(op_begin() + ReservedSpace); return reinterpret_cast(ref + 1); } const_block_iterator block_begin() const { const Use::UserRef *ref = reinterpret_cast(op_begin() + ReservedSpace); return reinterpret_cast(ref + 1); } block_iterator block_end() { return block_begin() + getNumOperands(); } const_block_iterator block_end() const { return block_begin() + getNumOperands(); } iterator_range blocks() { return make_range(block_begin(), block_end()); } iterator_range blocks() const { return make_range(block_begin(), block_end()); } op_range incoming_values() { return operands(); } const_op_range incoming_values() const { return operands(); } /// Return the number of incoming edges /// unsigned getNumIncomingValues() const { return getNumOperands(); } /// Return incoming value number x /// Value *getIncomingValue(unsigned i) const { return getOperand(i); } void setIncomingValue(unsigned i, Value *V) { assert(V && "PHI node got a null value!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); setOperand(i, V); } static unsigned getOperandNumForIncomingValue(unsigned i) { return i; } static unsigned getIncomingValueNumForOperand(unsigned i) { return i; } /// Return incoming basic block number @p i. /// BasicBlock *getIncomingBlock(unsigned i) const { return block_begin()[i]; } /// Return incoming basic block corresponding /// to an operand of the PHI. /// BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); return getIncomingBlock(unsigned(&U - op_begin())); } /// Return incoming basic block corresponding /// to value use iterator. /// BasicBlock *getIncomingBlock(Value::const_user_iterator I) const { return getIncomingBlock(I.getUse()); } void setIncomingBlock(unsigned i, BasicBlock *BB) { assert(BB && "PHI node got a null basic block!"); block_begin()[i] = BB; } /// Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { if (getNumOperands() == ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. setNumHungOffUseOperands(getNumOperands() + 1); setIncomingValue(getNumOperands() - 1, V); setIncomingBlock(getNumOperands() - 1, BB); } /// Remove an incoming value. This is useful if a /// predecessor basic block is deleted. The value removed is returned. /// /// If the last incoming value for a PHI node is removed (and DeletePHIIfEmpty /// is true), the PHI node is destroyed and any uses of it are replaced with /// dummy values. The only time there should be zero incoming values to a PHI /// node is when the block is dead, so this strategy is sound. /// Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true); Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty=true) { int Idx = getBasicBlockIndex(BB); assert(Idx >= 0 && "Invalid basic block argument to remove!"); return removeIncomingValue(Idx, DeletePHIIfEmpty); } /// Return the first index of the specified basic /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) if (block_begin()[i] == BB) return i; return -1; } Value *getIncomingValueForBlock(const BasicBlock *BB) const { int Idx = getBasicBlockIndex(BB); assert(Idx >= 0 && "Invalid basic block argument!"); return getIncomingValue(Idx); } /// If the specified PHI node always merges together the /// same value, return the value, otherwise return null. Value *hasConstantValue() const; /// Whether the specified PHI node always merges /// together the same value, assuming undefs are equal to a unique /// non-undef value. bool hasConstantOrUndefValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::PHI; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: void growOperands(); }; template <> struct OperandTraits : public HungoffOperandTraits<2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value) //===----------------------------------------------------------------------===// // LandingPadInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// The landingpad instruction holds all of the information /// necessary to generate correct exception handling. The landingpad instruction /// cannot be moved from the top of a landing pad block, which itself is /// accessible only from the 'unwind' edge of an invoke. This uses the /// SubclassData field in Value to store whether or not the landingpad is a /// cleanup. /// class LandingPadInst : public Instruction { /// The number of operands actually allocated. NumOperands is /// the number actually in use. unsigned ReservedSpace; LandingPadInst(const LandingPadInst &LP); public: enum ClauseType { Catch, Filter }; private: explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues, const Twine &NameStr, Instruction *InsertBefore); explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd); // Allocate space for exactly zero operands. void *operator new(size_t s) { return User::operator new(s); } void growOperands(unsigned Size); void init(unsigned NumReservedValues, const Twine &NameStr); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; LandingPadInst *cloneImpl() const; public: /// Constructors - NumReservedClauses is a hint for the number of incoming /// clauses that this landingpad will have (use 0 if you really have no idea). static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr = "", Instruction *InsertBefore = nullptr); static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, BasicBlock *InsertAtEnd); /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Return 'true' if this landingpad instruction is a /// cleanup. I.e., it should be run when unwinding even if its landing pad /// doesn't catch the exception. bool isCleanup() const { return getSubclassDataFromInstruction() & 1; } /// Indicate that this landingpad instruction is a cleanup. void setCleanup(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | (V ? 1 : 0)); } /// Add a catch or filter clause to the landing pad. void addClause(Constant *ClauseVal); /// Get the value of the clause at index Idx. Use isCatch/isFilter to /// determine what type of clause this is. Constant *getClause(unsigned Idx) const { return cast(getOperandList()[Idx]); } /// Return 'true' if the clause and index Idx is a catch clause. bool isCatch(unsigned Idx) const { return !isa(getOperandList()[Idx]->getType()); } /// Return 'true' if the clause and index Idx is a filter clause. bool isFilter(unsigned Idx) const { return isa(getOperandList()[Idx]->getType()); } /// Get the number of clauses for this landing pad. unsigned getNumClauses() const { return getNumOperands(); } /// Grow the size of the operand list to accommodate the new /// number of clauses. void reserveClauses(unsigned Size) { growOperands(Size); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::LandingPad; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public HungoffOperandTraits<1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value) //===----------------------------------------------------------------------===// // ReturnInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// Return a value (possibly void), from a function. Execution /// does not continue in this function any longer. /// class ReturnInst : public Instruction { ReturnInst(const ReturnInst &RI); private: // ReturnInst constructors: // ReturnInst() - 'ret void' instruction // ReturnInst( null) - 'ret void' instruction // ReturnInst(Value* X) - 'ret X' instruction // ReturnInst( null, Inst *I) - 'ret void' instruction, insert before I // ReturnInst(Value* X, Inst *I) - 'ret X' instruction, insert before I // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of B // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of B // // NOTE: If the Value* passed is of type void then the constructor behaves as // if it was passed NULL. explicit ReturnInst(LLVMContext &C, Value *retVal = nullptr, Instruction *InsertBefore = nullptr); ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; ReturnInst *cloneImpl() const; public: static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr, Instruction *InsertBefore = nullptr) { return new(!!retVal) ReturnInst(C, retVal, InsertBefore); } static ReturnInst* Create(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd) { return new(!!retVal) ReturnInst(C, retVal, InsertAtEnd); } static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) { return new(0) ReturnInst(C, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Convenience accessor. Returns null if there is no return value. Value *getReturnValue() const { return getNumOperands() != 0 ? getOperand(0) : nullptr; } unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Ret); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: BasicBlock *getSuccessor(unsigned idx) const { llvm_unreachable("ReturnInst has no successors!"); } void setSuccessor(unsigned idx, BasicBlock *B) { llvm_unreachable("ReturnInst has no successors!"); } }; template <> struct OperandTraits : public VariadicOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value) //===----------------------------------------------------------------------===// // BranchInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// Conditional or Unconditional Branch instruction. /// class BranchInst : public Instruction { /// Ops list - Branches are strange. The operands are ordered: /// [Cond, FalseDest,] TrueDest. This makes some accessors faster because /// they don't have to check for cond/uncond branchness. These are mostly /// accessed relative from op_end(). BranchInst(const BranchInst &BI); // BranchInst constructors (where {B, T, F} are blocks, and C is a condition): // BranchInst(BB *B) - 'br B' // BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F' // BranchInst(BB* B, Inst *I) - 'br B' insert before I // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I // BranchInst(BB* B, BB *I) - 'br B' insert at end // BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore = nullptr); BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); void AssertOK(); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; BranchInst *cloneImpl() const; public: /// Iterator type that casts an operand to a basic block. /// /// This only makes sense because the successors are stored as adjacent /// operands for branch instructions. struct succ_op_iterator : iterator_adaptor_base { explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} BasicBlock *operator*() const { return cast(*I); } BasicBlock *operator->() const { return operator*(); } }; /// The const version of `succ_op_iterator`. struct const_succ_op_iterator : iterator_adaptor_base { explicit const_succ_op_iterator(const_value_op_iterator I) : iterator_adaptor_base(I) {} const BasicBlock *operator*() const { return cast(*I); } const BasicBlock *operator->() const { return operator*(); } }; static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr) { return new(1) BranchInst(IfTrue, InsertBefore); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore = nullptr) { return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) { return new(1) BranchInst(IfTrue, InsertAtEnd); } static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd) { return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); bool isUnconditional() const { return getNumOperands() == 1; } bool isConditional() const { return getNumOperands() == 3; } Value *getCondition() const { assert(isConditional() && "Cannot get condition of an uncond branch!"); return Op<-3>(); } void setCondition(Value *V) { assert(isConditional() && "Cannot set condition of unconditional branch!"); Op<-3>() = V; } unsigned getNumSuccessors() const { return 1+isConditional(); } BasicBlock *getSuccessor(unsigned i) const { assert(i < getNumSuccessors() && "Successor # out of range for Branch!"); return cast_or_null((&Op<-1>() - i)->get()); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); *(&Op<-1>() - idx) = NewSucc; } /// Swap the successors of this branch instruction. /// /// Swaps the successors of the branch instruction. This also swaps any /// branch weight metadata associated with the instruction so that it /// continues to map correctly to each operand. void swapSuccessors(); iterator_range successors() { return make_range( succ_op_iterator(std::next(value_op_begin(), isConditional() ? 1 : 0)), succ_op_iterator(value_op_end())); } iterator_range successors() const { return make_range(const_succ_op_iterator( std::next(value_op_begin(), isConditional() ? 1 : 0)), const_succ_op_iterator(value_op_end())); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public VariadicOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value) //===----------------------------------------------------------------------===// // SwitchInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// Multiway switch /// class SwitchInst : public Instruction { unsigned ReservedSpace; // Operand[0] = Value to switch on // Operand[1] = Default basic block destination // Operand[2n ] = Value to match // Operand[2n+1] = BasicBlock to go to on match SwitchInst(const SwitchInst &SI); /// Create a new switch instruction, specifying a value to switch on and a /// default destination. The number of additional cases can be specified here /// to make memory allocation more efficient. This constructor can also /// auto-insert before another instruction. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore); /// Create a new switch instruction, specifying a value to switch on and a /// default destination. The number of additional cases can be specified here /// to make memory allocation more efficient. This constructor also /// auto-inserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s); } void init(Value *Value, BasicBlock *Default, unsigned NumReserved); void growOperands(); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; SwitchInst *cloneImpl() const; public: // -2 static const unsigned DefaultPseudoIndex = static_cast(~0L-1); template class CaseIteratorImpl; /// A handle to a particular switch case. It exposes a convenient interface /// to both the case value and the successor block. /// /// We define this as a template and instantiate it to form both a const and /// non-const handle. template class CaseHandleImpl { // Directly befriend both const and non-const iterators. friend class SwitchInst::CaseIteratorImpl< CaseHandleImpl>; protected: // Expose the switch type we're parameterized with to the iterator. using SwitchInstType = SwitchInstT; SwitchInstT *SI; ptrdiff_t Index; CaseHandleImpl() = default; CaseHandleImpl(SwitchInstT *SI, ptrdiff_t Index) : SI(SI), Index(Index) {} public: /// Resolves case value for current case. ConstantIntT *getCaseValue() const { assert((unsigned)Index < SI->getNumCases() && "Index out the number of cases."); return reinterpret_cast(SI->getOperand(2 + Index * 2)); } /// Resolves successor for current case. BasicBlockT *getCaseSuccessor() const { assert(((unsigned)Index < SI->getNumCases() || (unsigned)Index == DefaultPseudoIndex) && "Index out the number of cases."); return SI->getSuccessor(getSuccessorIndex()); } /// Returns number of current case. unsigned getCaseIndex() const { return Index; } /// Returns successor index for current case successor. unsigned getSuccessorIndex() const { assert(((unsigned)Index == DefaultPseudoIndex || (unsigned)Index < SI->getNumCases()) && "Index out the number of cases."); return (unsigned)Index != DefaultPseudoIndex ? Index + 1 : 0; } bool operator==(const CaseHandleImpl &RHS) const { assert(SI == RHS.SI && "Incompatible operators."); return Index == RHS.Index; } }; using ConstCaseHandle = CaseHandleImpl; class CaseHandle : public CaseHandleImpl { friend class SwitchInst::CaseIteratorImpl; public: CaseHandle(SwitchInst *SI, ptrdiff_t Index) : CaseHandleImpl(SI, Index) {} /// Sets the new value for current case. void setValue(ConstantInt *V) { assert((unsigned)Index < SI->getNumCases() && "Index out the number of cases."); SI->setOperand(2 + Index*2, reinterpret_cast(V)); } /// Sets the new successor for current case. void setSuccessor(BasicBlock *S) { SI->setSuccessor(getSuccessorIndex(), S); } }; template class CaseIteratorImpl : public iterator_facade_base, std::random_access_iterator_tag, CaseHandleT> { using SwitchInstT = typename CaseHandleT::SwitchInstType; CaseHandleT Case; public: /// Default constructed iterator is in an invalid state until assigned to /// a case for a particular switch. CaseIteratorImpl() = default; /// Initializes case iterator for given SwitchInst and for given /// case number. CaseIteratorImpl(SwitchInstT *SI, unsigned CaseNum) : Case(SI, CaseNum) {} /// Initializes case iterator for given SwitchInst and for given /// successor index. static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI, unsigned SuccessorIndex) { assert(SuccessorIndex < SI->getNumSuccessors() && "Successor index # out of range!"); return SuccessorIndex != 0 ? CaseIteratorImpl(SI, SuccessorIndex - 1) : CaseIteratorImpl(SI, DefaultPseudoIndex); } /// Support converting to the const variant. This will be a no-op for const /// variant. operator CaseIteratorImpl() const { return CaseIteratorImpl(Case.SI, Case.Index); } CaseIteratorImpl &operator+=(ptrdiff_t N) { // Check index correctness after addition. // Note: Index == getNumCases() means end(). assert(Case.Index + N >= 0 && (unsigned)(Case.Index + N) <= Case.SI->getNumCases() && "Case.Index out the number of cases."); Case.Index += N; return *this; } CaseIteratorImpl &operator-=(ptrdiff_t N) { // Check index correctness after subtraction. // Note: Case.Index == getNumCases() means end(). assert(Case.Index - N >= 0 && (unsigned)(Case.Index - N) <= Case.SI->getNumCases() && "Case.Index out the number of cases."); Case.Index -= N; return *this; } ptrdiff_t operator-(const CaseIteratorImpl &RHS) const { assert(Case.SI == RHS.Case.SI && "Incompatible operators."); return Case.Index - RHS.Case.Index; } bool operator==(const CaseIteratorImpl &RHS) const { return Case == RHS.Case; } bool operator<(const CaseIteratorImpl &RHS) const { assert(Case.SI == RHS.Case.SI && "Incompatible operators."); return Case.Index < RHS.Case.Index; } CaseHandleT &operator*() { return Case; } const CaseHandleT &operator*() const { return Case; } }; using CaseIt = CaseIteratorImpl; using ConstCaseIt = CaseIteratorImpl; static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = nullptr) { return new SwitchInst(Value, Default, NumCases, InsertBefore); } static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd) { return new SwitchInst(Value, Default, NumCases, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Accessor Methods for Switch stmt Value *getCondition() const { return getOperand(0); } void setCondition(Value *V) { setOperand(0, V); } BasicBlock *getDefaultDest() const { return cast(getOperand(1)); } void setDefaultDest(BasicBlock *DefaultCase) { setOperand(1, reinterpret_cast(DefaultCase)); } /// Return the number of 'cases' in this switch instruction, excluding the /// default case. unsigned getNumCases() const { return getNumOperands()/2 - 1; } /// Returns a read/write iterator that points to the first case in the /// SwitchInst. CaseIt case_begin() { return CaseIt(this, 0); } /// Returns a read-only iterator that points to the first case in the /// SwitchInst. ConstCaseIt case_begin() const { return ConstCaseIt(this, 0); } /// Returns a read/write iterator that points one past the last in the /// SwitchInst. CaseIt case_end() { return CaseIt(this, getNumCases()); } /// Returns a read-only iterator that points one past the last in the /// SwitchInst. ConstCaseIt case_end() const { return ConstCaseIt(this, getNumCases()); } /// Iteration adapter for range-for loops. iterator_range cases() { return make_range(case_begin(), case_end()); } /// Constant iteration adapter for range-for loops. iterator_range cases() const { return make_range(case_begin(), case_end()); } /// Returns an iterator that points to the default case. /// Note: this iterator allows to resolve successor only. Attempt /// to resolve case value causes an assertion. /// Also note, that increment and decrement also causes an assertion and /// makes iterator invalid. CaseIt case_default() { return CaseIt(this, DefaultPseudoIndex); } ConstCaseIt case_default() const { return ConstCaseIt(this, DefaultPseudoIndex); } /// Search all of the case values for the specified constant. If it is /// explicitly handled, return the case iterator of it, otherwise return /// default case iterator to indicate that it is handled by the default /// handler. CaseIt findCaseValue(const ConstantInt *C) { CaseIt I = llvm::find_if( cases(), [C](CaseHandle &Case) { return Case.getCaseValue() == C; }); if (I != case_end()) return I; return case_default(); } ConstCaseIt findCaseValue(const ConstantInt *C) const { ConstCaseIt I = llvm::find_if(cases(), [C](ConstCaseHandle &Case) { return Case.getCaseValue() == C; }); if (I != case_end()) return I; return case_default(); } /// Finds the unique case value for a given successor. Returns null if the /// successor is not found, not unique, or is the default case. ConstantInt *findCaseDest(BasicBlock *BB) { if (BB == getDefaultDest()) return nullptr; ConstantInt *CI = nullptr; for (auto Case : cases()) { if (Case.getCaseSuccessor() != BB) continue; if (CI) return nullptr; // Multiple cases lead to BB. CI = Case.getCaseValue(); } return CI; } /// Add an entry to the switch instruction. /// Note: /// This action invalidates case_end(). Old case_end() iterator will /// point to the added case. void addCase(ConstantInt *OnVal, BasicBlock *Dest); /// This method removes the specified case and its successor from the switch /// instruction. Note that this operation may reorder the remaining cases at /// index idx and above. /// Note: /// This action invalidates iterators for all cases following the one removed, /// including the case_end() iterator. It returns an iterator for the next /// case. CaseIt removeCase(CaseIt I); unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!"); return cast(getOperand(idx*2+1)); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); setOperand(idx * 2 + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Switch; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public HungoffOperandTraits<2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value) //===----------------------------------------------------------------------===// // IndirectBrInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// Indirect Branch Instruction. /// class IndirectBrInst : public Instruction { unsigned ReservedSpace; // Operand[0] = Address to jump to // Operand[n+1] = n-th destination IndirectBrInst(const IndirectBrInst &IBI); /// Create a new indirectbr instruction, specifying an /// Address to jump to. The number of expected destinations can be specified /// here to make memory allocation more efficient. This constructor can also /// autoinsert before another instruction. IndirectBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore); /// Create a new indirectbr instruction, specifying an /// Address to jump to. The number of expected destinations can be specified /// here to make memory allocation more efficient. This constructor also /// autoinserts at the end of the specified BasicBlock. IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s); } void init(Value *Address, unsigned NumDests); void growOperands(); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; IndirectBrInst *cloneImpl() const; public: /// Iterator type that casts an operand to a basic block. /// /// This only makes sense because the successors are stored as adjacent /// operands for indirectbr instructions. struct succ_op_iterator : iterator_adaptor_base { explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {} BasicBlock *operator*() const { return cast(*I); } BasicBlock *operator->() const { return operator*(); } }; /// The const version of `succ_op_iterator`. struct const_succ_op_iterator : iterator_adaptor_base { explicit const_succ_op_iterator(const_value_op_iterator I) : iterator_adaptor_base(I) {} const BasicBlock *operator*() const { return cast(*I); } const BasicBlock *operator->() const { return operator*(); } }; static IndirectBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = nullptr) { return new IndirectBrInst(Address, NumDests, InsertBefore); } static IndirectBrInst *Create(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd) { return new IndirectBrInst(Address, NumDests, InsertAtEnd); } /// Provide fast operand accessors. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Accessor Methods for IndirectBrInst instruction. Value *getAddress() { return getOperand(0); } const Value *getAddress() const { return getOperand(0); } void setAddress(Value *V) { setOperand(0, V); } /// return the number of possible destinations in this /// indirectbr instruction. unsigned getNumDestinations() const { return getNumOperands()-1; } /// Return the specified destination. BasicBlock *getDestination(unsigned i) { return getSuccessor(i); } const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); } /// Add a destination. /// void addDestination(BasicBlock *Dest); /// This method removes the specified successor from the /// indirectbr instruction. void removeDestination(unsigned i); unsigned getNumSuccessors() const { return getNumOperands()-1; } BasicBlock *getSuccessor(unsigned i) const { return cast(getOperand(i+1)); } void setSuccessor(unsigned i, BasicBlock *NewSucc) { setOperand(i + 1, NewSucc); } iterator_range successors() { return make_range(succ_op_iterator(std::next(value_op_begin())), succ_op_iterator(value_op_end())); } iterator_range successors() const { return make_range(const_succ_op_iterator(std::next(value_op_begin())), const_succ_op_iterator(value_op_end())); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public HungoffOperandTraits<1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) //===----------------------------------------------------------------------===// // InvokeInst Class //===----------------------------------------------------------------------===// /// Invoke instruction. The SubclassData field is used to hold the /// calling convention of the call. /// class InvokeInst : public CallBase { /// The number of operands for this call beyond the called function, /// arguments, and operand bundles. static constexpr int NumExtraOperands = 2; /// The index from the end of the operand array to the normal destination. static constexpr int NormalDestOpEndIdx = -3; /// The index from the end of the operand array to the unwind destination. static constexpr int UnwindDestOpEndIdx = -2; InvokeInst(const InvokeInst &BI); /// Construct an InvokeInst given a range of arguments. /// /// Construct an InvokeInst from a range of arguments inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, int NumOperands, const Twine &NameStr, Instruction *InsertBefore); inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, int NumOperands, const Twine &NameStr, BasicBlock *InsertAtEnd); void init(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr); /// Compute the number of operands to allocate. static int ComputeNumOperands(int NumArgs, int NumBundleInputs = 0) { // We need one operand for the called function, plus our extra operands and // the input operand counts provided. return 1 + NumExtraOperands + NumArgs + NumBundleInputs; } protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; InvokeInst *cloneImpl() const; public: static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { int NumOperands = ComputeNumOperands(Args.size()); return new (NumOperands) InvokeInst(Ty, Func, IfNormal, IfException, Args, None, NumOperands, NameStr, InsertBefore); } static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { int NumOperands = ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)); unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); return new (NumOperands, DescriptorBytes) InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, NumOperands, NameStr, InsertBefore); } static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { int NumOperands = ComputeNumOperands(Args.size()); return new (NumOperands) InvokeInst(Ty, Func, IfNormal, IfException, Args, None, NumOperands, NameStr, InsertAtEnd); } static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { int NumOperands = ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)); unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); return new (NumOperands, DescriptorBytes) InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, NumOperands, NameStr, InsertAtEnd); } static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, None, NameStr, InsertBefore); } static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, Bundles, NameStr, InsertBefore); } static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, NameStr, InsertAtEnd); } static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, Bundles, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(cast( cast(Func->getType())->getElementType()), Func, IfNormal, IfException, Args, None, NameStr, InsertBefore); } // Deprecated [opaque pointer types] static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast( cast(Func->getType())->getElementType()), Func, IfNormal, IfException, Args, Bundles, NameStr, InsertBefore); } // Deprecated [opaque pointer types] static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(cast( cast(Func->getType())->getElementType()), Func, IfNormal, IfException, Args, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { return Create(cast( cast(Func->getType())->getElementType()), Func, IfNormal, IfException, Args, Bundles, NameStr, InsertAtEnd); } /// Create a clone of \p II with a different set of operand bundles and /// insert it before \p InsertPt. /// /// The returned invoke instruction is identical to \p II in every way except /// that the operand bundles for the new instruction are set to the operand /// bundles in \p Bundles. static InvokeInst *Create(InvokeInst *II, ArrayRef Bundles, Instruction *InsertPt = nullptr); /// Determine if the call should not perform indirect branch tracking. bool doesNoCfCheck() const { return hasFnAttr(Attribute::NoCfCheck); } /// Determine if the call cannot unwind. bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); } void setDoesNotThrow() { addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); } // get*Dest - Return the destination basic blocks... BasicBlock *getNormalDest() const { return cast(Op()); } BasicBlock *getUnwindDest() const { return cast(Op()); } void setNormalDest(BasicBlock *B) { Op() = reinterpret_cast(B); } void setUnwindDest(BasicBlock *B) { Op() = reinterpret_cast(B); } /// Get the landingpad instruction from the landing pad /// block (the unwind destination). LandingPadInst *getLandingPadInst() const; BasicBlock *getSuccessor(unsigned i) const { assert(i < 2 && "Successor # out of range for invoke!"); return i == 0 ? getNormalDest() : getUnwindDest(); } void setSuccessor(unsigned i, BasicBlock *NewSucc) { assert(i < 2 && "Successor # out of range for invoke!"); if (i == 0) setNormalDest(NewSucc); else setUnwindDest(NewSucc); } unsigned getNumSuccessors() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } }; InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, int NumOperands, const Twine &NameStr, Instruction *InsertBefore) : CallBase(Ty->getReturnType(), Instruction::Invoke, OperandTraits::op_end(this) - NumOperands, NumOperands, InsertBefore) { init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr); } InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, int NumOperands, const Twine &NameStr, BasicBlock *InsertAtEnd) : CallBase(Ty->getReturnType(), Instruction::Invoke, OperandTraits::op_end(this) - NumOperands, NumOperands, InsertAtEnd) { init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr); } //===----------------------------------------------------------------------===// // ResumeInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// Resume the propagation of an exception. /// class ResumeInst : public Instruction { ResumeInst(const ResumeInst &RI); explicit ResumeInst(Value *Exn, Instruction *InsertBefore=nullptr); ResumeInst(Value *Exn, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; ResumeInst *cloneImpl() const; public: static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = nullptr) { return new(1) ResumeInst(Exn, InsertBefore); } static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) { return new(1) ResumeInst(Exn, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Convenience accessor. Value *getValue() const { return Op<0>(); } unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Resume; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: BasicBlock *getSuccessor(unsigned idx) const { llvm_unreachable("ResumeInst has no successors!"); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { llvm_unreachable("ResumeInst has no successors!"); } }; template <> struct OperandTraits : public FixedNumOperandTraits { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) //===----------------------------------------------------------------------===// // CatchSwitchInst Class //===----------------------------------------------------------------------===// class CatchSwitchInst : public Instruction { /// The number of operands actually allocated. NumOperands is /// the number actually in use. unsigned ReservedSpace; // Operand[0] = Outer scope // Operand[1] = Unwind block destination // Operand[n] = BasicBlock to go to on match CatchSwitchInst(const CatchSwitchInst &CSI); /// Create a new switch instruction, specifying a /// default destination. The number of additional handlers can be specified /// here to make memory allocation more efficient. /// This constructor can also autoinsert before another instruction. CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumHandlers, const Twine &NameStr, Instruction *InsertBefore); /// Create a new switch instruction, specifying a /// default destination. The number of additional handlers can be specified /// here to make memory allocation more efficient. /// This constructor also autoinserts at the end of the specified BasicBlock. CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s); } void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved); void growOperands(unsigned Size); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; CatchSwitchInst *cloneImpl() const; public: static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumHandlers, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, InsertBefore); } static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Accessor Methods for CatchSwitch stmt Value *getParentPad() const { return getOperand(0); } void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); } // Accessor Methods for CatchSwitch stmt bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } bool unwindsToCaller() const { return !hasUnwindDest(); } BasicBlock *getUnwindDest() const { if (hasUnwindDest()) return cast(getOperand(1)); return nullptr; } void setUnwindDest(BasicBlock *UnwindDest) { assert(UnwindDest); assert(hasUnwindDest()); setOperand(1, UnwindDest); } /// return the number of 'handlers' in this catchswitch /// instruction, except the default handler unsigned getNumHandlers() const { if (hasUnwindDest()) return getNumOperands() - 2; return getNumOperands() - 1; } private: static BasicBlock *handler_helper(Value *V) { return cast(V); } static const BasicBlock *handler_helper(const Value *V) { return cast(V); } public: using DerefFnTy = BasicBlock *(*)(Value *); using handler_iterator = mapped_iterator; using handler_range = iterator_range; using ConstDerefFnTy = const BasicBlock *(*)(const Value *); using const_handler_iterator = mapped_iterator; using const_handler_range = iterator_range; /// Returns an iterator that points to the first handler in CatchSwitchInst. handler_iterator handler_begin() { op_iterator It = op_begin() + 1; if (hasUnwindDest()) ++It; return handler_iterator(It, DerefFnTy(handler_helper)); } /// Returns an iterator that points to the first handler in the /// CatchSwitchInst. const_handler_iterator handler_begin() const { const_op_iterator It = op_begin() + 1; if (hasUnwindDest()) ++It; return const_handler_iterator(It, ConstDerefFnTy(handler_helper)); } /// Returns a read-only iterator that points one past the last /// handler in the CatchSwitchInst. handler_iterator handler_end() { return handler_iterator(op_end(), DerefFnTy(handler_helper)); } /// Returns an iterator that points one past the last handler in the /// CatchSwitchInst. const_handler_iterator handler_end() const { return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper)); } /// iteration adapter for range-for loops. handler_range handlers() { return make_range(handler_begin(), handler_end()); } /// iteration adapter for range-for loops. const_handler_range handlers() const { return make_range(handler_begin(), handler_end()); } /// Add an entry to the switch instruction... /// Note: /// This action invalidates handler_end(). Old handler_end() iterator will /// point to the added handler. void addHandler(BasicBlock *Dest); void removeHandler(handler_iterator HI); unsigned getNumSuccessors() const { return getNumOperands() - 1; } BasicBlock *getSuccessor(unsigned Idx) const { assert(Idx < getNumSuccessors() && "Successor # out of range for catchswitch!"); return cast(getOperand(Idx + 1)); } void setSuccessor(unsigned Idx, BasicBlock *NewSucc) { assert(Idx < getNumSuccessors() && "Successor # out of range for catchswitch!"); setOperand(Idx + 1, NewSucc); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchSwitch; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; template <> struct OperandTraits : public HungoffOperandTraits<2> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value) //===----------------------------------------------------------------------===// // CleanupPadInst Class //===----------------------------------------------------------------------===// class CleanupPadInst : public FuncletPadInst { private: explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, NameStr, InsertBefore) {} explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, NameStr, InsertAtEnd) {} public: static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { unsigned Values = 1 + Args.size(); return new (Values) CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore); } static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = 1 + Args.size(); return new (Values) CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CleanupPad; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // CatchPadInst Class //===----------------------------------------------------------------------===// class CatchPadInst : public FuncletPadInst { private: explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, NameStr, InsertBefore) {} explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, NameStr, InsertAtEnd) {} public: static CatchPadInst *Create(Value *CatchSwitch, ArrayRef Args, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { unsigned Values = 1 + Args.size(); return new (Values) CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore); } static CatchPadInst *Create(Value *CatchSwitch, ArrayRef Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = 1 + Args.size(); return new (Values) CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertAtEnd); } /// Convenience accessors CatchSwitchInst *getCatchSwitch() const { return cast(Op<-1>()); } void setCatchSwitch(Value *CatchSwitch) { assert(CatchSwitch); Op<-1>() = CatchSwitch; } /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchPad; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // CatchReturnInst Class //===----------------------------------------------------------------------===// class CatchReturnInst : public Instruction { CatchReturnInst(const CatchReturnInst &RI); CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore); CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd); void init(Value *CatchPad, BasicBlock *BB); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; CatchReturnInst *cloneImpl() const; public: static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore = nullptr) { assert(CatchPad); assert(BB); return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); } static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) { assert(CatchPad); assert(BB); return new (2) CatchReturnInst(CatchPad, BB, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// Convenience accessors. CatchPadInst *getCatchPad() const { return cast(Op<0>()); } void setCatchPad(CatchPadInst *CatchPad) { assert(CatchPad); Op<0>() = CatchPad; } BasicBlock *getSuccessor() const { return cast(Op<1>()); } void setSuccessor(BasicBlock *NewSucc) { assert(NewSucc); Op<1>() = NewSucc; } unsigned getNumSuccessors() const { return 1; } /// Get the parentPad of this catchret's catchpad's catchswitch. /// The successor block is implicitly a member of this funclet. Value *getCatchSwitchParentPad() const { return getCatchPad()->getCatchSwitch()->getParentPad(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CatchRet); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: BasicBlock *getSuccessor(unsigned Idx) const { assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!"); return getSuccessor(); } void setSuccessor(unsigned Idx, BasicBlock *B) { assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!"); setSuccessor(B); } }; template <> struct OperandTraits : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value) //===----------------------------------------------------------------------===// // CleanupReturnInst Class //===----------------------------------------------------------------------===// class CleanupReturnInst : public Instruction { private: CleanupReturnInst(const CleanupReturnInst &RI); CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, Instruction *InsertBefore = nullptr); CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, BasicBlock *InsertAtEnd); void init(Value *CleanupPad, BasicBlock *UnwindBB); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; CleanupReturnInst *cloneImpl() const; public: static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB = nullptr, Instruction *InsertBefore = nullptr) { assert(CleanupPad); unsigned Values = 1; if (UnwindBB) ++Values; return new (Values) CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore); } static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB, BasicBlock *InsertAtEnd) { assert(CleanupPad); unsigned Values = 1; if (UnwindBB) ++Values; return new (Values) CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } bool unwindsToCaller() const { return !hasUnwindDest(); } /// Convenience accessor. CleanupPadInst *getCleanupPad() const { return cast(Op<0>()); } void setCleanupPad(CleanupPadInst *CleanupPad) { assert(CleanupPad); Op<0>() = CleanupPad; } unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } BasicBlock *getUnwindDest() const { return hasUnwindDest() ? cast(Op<1>()) : nullptr; } void setUnwindDest(BasicBlock *NewDest) { assert(NewDest); assert(hasUnwindDest()); Op<1>() = NewDest; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CleanupRet); } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: BasicBlock *getSuccessor(unsigned Idx) const { assert(Idx == 0); return getUnwindDest(); } void setSuccessor(unsigned Idx, BasicBlock *B) { assert(Idx == 0); setUnwindDest(B); } // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } }; template <> struct OperandTraits : public VariadicOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value) //===----------------------------------------------------------------------===// // UnreachableInst Class //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- /// This function has undefined behavior. In particular, the /// presence of this instruction indicates some higher level knowledge that the /// end of the block cannot be reached. /// class UnreachableInst : public Instruction { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; UnreachableInst *cloneImpl() const; public: explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = nullptr); explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); } unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Unreachable; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: BasicBlock *getSuccessor(unsigned idx) const { llvm_unreachable("UnreachableInst has no successors!"); } void setSuccessor(unsigned idx, BasicBlock *B) { llvm_unreachable("UnreachableInst has no successors!"); } }; //===----------------------------------------------------------------------===// // TruncInst Class //===----------------------------------------------------------------------===// /// This class represents a truncation of integer types. class TruncInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical TruncInst TruncInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics TruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The (smaller) type to truncate to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics TruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The (smaller) type to truncate to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Trunc; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // ZExtInst Class //===----------------------------------------------------------------------===// /// This class represents zero extension of integer types. class ZExtInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical ZExtInst ZExtInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics ZExtInst( Value *S, ///< The value to be zero extended Type *Ty, ///< The type to zero extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end semantics. ZExtInst( Value *S, ///< The value to be zero extended Type *Ty, ///< The type to zero extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == ZExt; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // SExtInst Class //===----------------------------------------------------------------------===// /// This class represents a sign extension of integer types. class SExtInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical SExtInst SExtInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics SExtInst( Value *S, ///< The value to be sign extended Type *Ty, ///< The type to sign extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics SExtInst( Value *S, ///< The value to be sign extended Type *Ty, ///< The type to sign extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == SExt; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // FPTruncInst Class //===----------------------------------------------------------------------===// /// This class represents a truncation of floating point types. class FPTruncInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical FPTruncInst FPTruncInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The type to truncate to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated Type *Ty, ///< The type to truncate to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPTrunc; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // FPExtInst Class //===----------------------------------------------------------------------===// /// This class represents an extension of floating point types. class FPExtInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical FPExtInst FPExtInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics FPExtInst( Value *S, ///< The value to be extended Type *Ty, ///< The type to extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics FPExtInst( Value *S, ///< The value to be extended Type *Ty, ///< The type to extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPExt; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // UIToFPInst Class //===----------------------------------------------------------------------===// /// This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical UIToFPInst UIToFPInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics UIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics UIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == UIToFP; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // SIToFPInst Class //===----------------------------------------------------------------------===// /// This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical SIToFPInst SIToFPInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics SIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics SIToFPInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == SIToFP; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // FPToUIInst Class //===----------------------------------------------------------------------===// /// This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical FPToUIInst FPToUIInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics FPToUIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics FPToUIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPToUI; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // FPToSIInst Class //===----------------------------------------------------------------------===// /// This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical FPToSIInst FPToSIInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics FPToSIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics FPToSIInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == FPToSI; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // IntToPtrInst Class //===----------------------------------------------------------------------===// /// This class represents a cast from an integer to a pointer. class IntToPtrInst : public CastInst { public: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Constructor with insert-before-instruction semantics IntToPtrInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics IntToPtrInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Clone an identical IntToPtrInst. IntToPtrInst *cloneImpl() const; /// Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { return getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == IntToPtr; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // PtrToIntInst Class //===----------------------------------------------------------------------===// /// This class represents a cast from a pointer to an integer. class PtrToIntInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical PtrToIntInst. PtrToIntInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics PtrToIntInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics PtrToIntInst( Value *S, ///< The value to be converted Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// Gets the pointer operand. Value *getPointerOperand() { return getOperand(0); } /// Gets the pointer operand. const Value *getPointerOperand() const { return getOperand(0); } /// Gets the operand index of the pointer operand. static unsigned getPointerOperandIndex() { return 0U; } /// Returns the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == PtrToInt; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // BitCastInst Class //===----------------------------------------------------------------------===// /// This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical BitCastInst. BitCastInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics BitCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics BitCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == BitCast; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; //===----------------------------------------------------------------------===// // AddrSpaceCastInst Class //===----------------------------------------------------------------------===// /// This class represents a conversion between pointers from one address space /// to another. class AddrSpaceCastInst : public CastInst { protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; /// Clone an identical AddrSpaceCastInst. AddrSpaceCastInst *cloneImpl() const; public: /// Constructor with insert-before-instruction semantics AddrSpaceCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = nullptr ///< Where to insert the new instruction ); /// Constructor with insert-at-end-of-block semantics AddrSpaceCastInst( Value *S, ///< The value to be casted Type *Ty, ///< The type to casted to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == AddrSpaceCast; } static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } /// Gets the pointer operand. Value *getPointerOperand() { return getOperand(0); } /// Gets the pointer operand. const Value *getPointerOperand() const { return getOperand(0); } /// Gets the operand index of the pointer operand. static unsigned getPointerOperandIndex() { return 0U; } /// Returns the address space of the pointer operand. unsigned getSrcAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } /// Returns the address space of the result. unsigned getDestAddressSpace() const { return getType()->getPointerAddressSpace(); } }; /// A helper function that returns the pointer operand of a load or store /// instruction. Returns nullptr if not load or store. inline Value *getLoadStorePointerOperand(Value *V) { if (auto *Load = dyn_cast(V)) return Load->getPointerOperand(); if (auto *Store = dyn_cast(V)) return Store->getPointerOperand(); return nullptr; } /// A helper function that returns the pointer operand of a load, store /// or GEP instruction. Returns nullptr if not load, store, or GEP. inline Value *getPointerOperand(Value *V) { if (auto *Ptr = getLoadStorePointerOperand(V)) return Ptr; if (auto *Gep = dyn_cast(V)) return Gep->getPointerOperand(); return nullptr; } /// A helper function that returns the alignment of load or store instruction. inline unsigned getLoadStoreAlignment(Value *I) { assert((isa(I) || isa(I)) && "Expected Load or Store instruction"); if (auto *LI = dyn_cast(I)) return LI->getAlignment(); return cast(I)->getAlignment(); } /// A helper function that returns the address space of the pointer operand of /// load or store instruction. inline unsigned getLoadStoreAddressSpace(Value *I) { assert((isa(I) || isa(I)) && "Expected Load or Store instruction"); if (auto *LI = dyn_cast(I)) return LI->getPointerAddressSpace(); return cast(I)->getPointerAddressSpace(); } } // end namespace llvm #endif // LLVM_IR_INSTRUCTIONS_H diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 8916d47841b7..37303ff6431e 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1,3881 +1,3889 @@ //===-- Core.cpp ----------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the common infrastructure (including the C bindings) // for libLLVMCore.a, which implements the LLVM intermediate representation. // //===----------------------------------------------------------------------===// #include "llvm-c/Core.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" #include #include #include #include using namespace llvm; #define DEBUG_TYPE "ir" void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreeWrapperPassPass(Registry); initializePrintModulePassWrapperPass(Registry); initializePrintFunctionPassWrapperPass(Registry); initializePrintBasicBlockPassPass(Registry); initializeSafepointIRVerifierPass(Registry); initializeVerifierLegacyPassPass(Registry); } void LLVMInitializeCore(LLVMPassRegistryRef R) { initializeCore(*unwrap(R)); } void LLVMShutdown() { llvm_shutdown(); } /*===-- Error handling ----------------------------------------------------===*/ char *LLVMCreateMessage(const char *Message) { return strdup(Message); } void LLVMDisposeMessage(char *Message) { free(Message); } /*===-- Operations on contexts --------------------------------------------===*/ static ManagedStatic GlobalContext; LLVMContextRef LLVMContextCreate() { return wrap(new LLVMContext()); } LLVMContextRef LLVMGetGlobalContext() { return wrap(&*GlobalContext); } void LLVMContextSetDiagnosticHandler(LLVMContextRef C, LLVMDiagnosticHandler Handler, void *DiagnosticContext) { unwrap(C)->setDiagnosticHandlerCallBack( LLVM_EXTENSION reinterpret_cast( Handler), DiagnosticContext); } LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C) { return LLVM_EXTENSION reinterpret_cast( unwrap(C)->getDiagnosticHandlerCallBack()); } void *LLVMContextGetDiagnosticContext(LLVMContextRef C) { return unwrap(C)->getDiagnosticContext(); } void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback, void *OpaqueHandle) { auto YieldCallback = LLVM_EXTENSION reinterpret_cast(Callback); unwrap(C)->setYieldCallback(YieldCallback, OpaqueHandle); } LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C) { return unwrap(C)->shouldDiscardValueNames(); } void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard) { unwrap(C)->setDiscardValueNames(Discard); } void LLVMContextDispose(LLVMContextRef C) { delete unwrap(C); } unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name, unsigned SLen) { return unwrap(C)->getMDKindID(StringRef(Name, SLen)); } unsigned LLVMGetMDKindID(const char *Name, unsigned SLen) { return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen); } #define GET_ATTR_KIND_FROM_NAME #include "AttributesCompatFunc.inc" unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) { return getAttrKindFromName(StringRef(Name, SLen)); } unsigned LLVMGetLastEnumAttributeKind(void) { return Attribute::AttrKind::EndAttrKinds; } LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID, uint64_t Val) { return wrap(Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID, Val)); } unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) { return unwrap(A).getKindAsEnum(); } uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A) { auto Attr = unwrap(A); if (Attr.isEnumAttribute()) return 0; return Attr.getValueAsInt(); } LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C, const char *K, unsigned KLength, const char *V, unsigned VLength) { return wrap(Attribute::get(*unwrap(C), StringRef(K, KLength), StringRef(V, VLength))); } const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, unsigned *Length) { auto S = unwrap(A).getKindAsString(); *Length = S.size(); return S.data(); } const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length) { auto S = unwrap(A).getValueAsString(); *Length = S.size(); return S.data(); } LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A) { auto Attr = unwrap(A); return Attr.isEnumAttribute() || Attr.isIntAttribute(); } LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A) { return unwrap(A).isStringAttribute(); } char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { std::string MsgStorage; raw_string_ostream Stream(MsgStorage); DiagnosticPrinterRawOStream DP(Stream); unwrap(DI)->print(DP); Stream.flush(); return LLVMCreateMessage(MsgStorage.c_str()); } LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI) { LLVMDiagnosticSeverity severity; switch(unwrap(DI)->getSeverity()) { default: severity = LLVMDSError; break; case DS_Warning: severity = LLVMDSWarning; break; case DS_Remark: severity = LLVMDSRemark; break; case DS_Note: severity = LLVMDSNote; break; } return severity; } /*===-- Operations on modules ---------------------------------------------===*/ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { return wrap(new Module(ModuleID, *GlobalContext)); } LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, LLVMContextRef C) { return wrap(new Module(ModuleID, *unwrap(C))); } void LLVMDisposeModule(LLVMModuleRef M) { delete unwrap(M); } const char *LLVMGetModuleIdentifier(LLVMModuleRef M, size_t *Len) { auto &Str = unwrap(M)->getModuleIdentifier(); *Len = Str.length(); return Str.c_str(); } void LLVMSetModuleIdentifier(LLVMModuleRef M, const char *Ident, size_t Len) { unwrap(M)->setModuleIdentifier(StringRef(Ident, Len)); } const char *LLVMGetSourceFileName(LLVMModuleRef M, size_t *Len) { auto &Str = unwrap(M)->getSourceFileName(); *Len = Str.length(); return Str.c_str(); } void LLVMSetSourceFileName(LLVMModuleRef M, const char *Name, size_t Len) { unwrap(M)->setSourceFileName(StringRef(Name, Len)); } /*--.. Data layout .........................................................--*/ const char *LLVMGetDataLayoutStr(LLVMModuleRef M) { return unwrap(M)->getDataLayoutStr().c_str(); } const char *LLVMGetDataLayout(LLVMModuleRef M) { return LLVMGetDataLayoutStr(M); } void LLVMSetDataLayout(LLVMModuleRef M, const char *DataLayoutStr) { unwrap(M)->setDataLayout(DataLayoutStr); } /*--.. Target triple .......................................................--*/ const char * LLVMGetTarget(LLVMModuleRef M) { return unwrap(M)->getTargetTriple().c_str(); } void LLVMSetTarget(LLVMModuleRef M, const char *Triple) { unwrap(M)->setTargetTriple(Triple); } /*--.. Module flags ........................................................--*/ struct LLVMOpaqueModuleFlagEntry { LLVMModuleFlagBehavior Behavior; const char *Key; size_t KeyLen; LLVMMetadataRef Metadata; }; static Module::ModFlagBehavior map_to_llvmModFlagBehavior(LLVMModuleFlagBehavior Behavior) { switch (Behavior) { case LLVMModuleFlagBehaviorError: return Module::ModFlagBehavior::Error; case LLVMModuleFlagBehaviorWarning: return Module::ModFlagBehavior::Warning; case LLVMModuleFlagBehaviorRequire: return Module::ModFlagBehavior::Require; case LLVMModuleFlagBehaviorOverride: return Module::ModFlagBehavior::Override; case LLVMModuleFlagBehaviorAppend: return Module::ModFlagBehavior::Append; case LLVMModuleFlagBehaviorAppendUnique: return Module::ModFlagBehavior::AppendUnique; } llvm_unreachable("Unknown LLVMModuleFlagBehavior"); } static LLVMModuleFlagBehavior map_from_llvmModFlagBehavior(Module::ModFlagBehavior Behavior) { switch (Behavior) { case Module::ModFlagBehavior::Error: return LLVMModuleFlagBehaviorError; case Module::ModFlagBehavior::Warning: return LLVMModuleFlagBehaviorWarning; case Module::ModFlagBehavior::Require: return LLVMModuleFlagBehaviorRequire; case Module::ModFlagBehavior::Override: return LLVMModuleFlagBehaviorOverride; case Module::ModFlagBehavior::Append: return LLVMModuleFlagBehaviorAppend; case Module::ModFlagBehavior::AppendUnique: return LLVMModuleFlagBehaviorAppendUnique; default: llvm_unreachable("Unhandled Flag Behavior"); } } LLVMModuleFlagEntry *LLVMCopyModuleFlagsMetadata(LLVMModuleRef M, size_t *Len) { SmallVector MFEs; unwrap(M)->getModuleFlagsMetadata(MFEs); LLVMOpaqueModuleFlagEntry *Result = static_cast( safe_malloc(MFEs.size() * sizeof(LLVMOpaqueModuleFlagEntry))); for (unsigned i = 0; i < MFEs.size(); ++i) { const auto &ModuleFlag = MFEs[i]; Result[i].Behavior = map_from_llvmModFlagBehavior(ModuleFlag.Behavior); Result[i].Key = ModuleFlag.Key->getString().data(); Result[i].KeyLen = ModuleFlag.Key->getString().size(); Result[i].Metadata = wrap(ModuleFlag.Val); } *Len = MFEs.size(); return Result; } void LLVMDisposeModuleFlagsMetadata(LLVMModuleFlagEntry *Entries) { free(Entries); } LLVMModuleFlagBehavior LLVMModuleFlagEntriesGetFlagBehavior(LLVMModuleFlagEntry *Entries, unsigned Index) { LLVMOpaqueModuleFlagEntry MFE = static_cast(Entries[Index]); return MFE.Behavior; } const char *LLVMModuleFlagEntriesGetKey(LLVMModuleFlagEntry *Entries, unsigned Index, size_t *Len) { LLVMOpaqueModuleFlagEntry MFE = static_cast(Entries[Index]); *Len = MFE.KeyLen; return MFE.Key; } LLVMMetadataRef LLVMModuleFlagEntriesGetMetadata(LLVMModuleFlagEntry *Entries, unsigned Index) { LLVMOpaqueModuleFlagEntry MFE = static_cast(Entries[Index]); return MFE.Metadata; } LLVMMetadataRef LLVMGetModuleFlag(LLVMModuleRef M, const char *Key, size_t KeyLen) { return wrap(unwrap(M)->getModuleFlag({Key, KeyLen})); } void LLVMAddModuleFlag(LLVMModuleRef M, LLVMModuleFlagBehavior Behavior, const char *Key, size_t KeyLen, LLVMMetadataRef Val) { unwrap(M)->addModuleFlag(map_to_llvmModFlagBehavior(Behavior), {Key, KeyLen}, unwrap(Val)); } /*--.. Printing modules ....................................................--*/ void LLVMDumpModule(LLVMModuleRef M) { unwrap(M)->print(errs(), nullptr, /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true); } LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, char **ErrorMessage) { std::error_code EC; raw_fd_ostream dest(Filename, EC, sys::fs::F_Text); if (EC) { *ErrorMessage = strdup(EC.message().c_str()); return true; } unwrap(M)->print(dest, nullptr); dest.close(); if (dest.has_error()) { std::string E = "Error printing to file: " + dest.error().message(); *ErrorMessage = strdup(E.c_str()); return true; } return false; } char *LLVMPrintModuleToString(LLVMModuleRef M) { std::string buf; raw_string_ostream os(buf); unwrap(M)->print(os, nullptr); os.flush(); return strdup(buf.c_str()); } /*--.. Operations on inline assembler ......................................--*/ void LLVMSetModuleInlineAsm2(LLVMModuleRef M, const char *Asm, size_t Len) { unwrap(M)->setModuleInlineAsm(StringRef(Asm, Len)); } void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) { unwrap(M)->setModuleInlineAsm(StringRef(Asm)); } void LLVMAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm, size_t Len) { unwrap(M)->appendModuleInlineAsm(StringRef(Asm, Len)); } const char *LLVMGetModuleInlineAsm(LLVMModuleRef M, size_t *Len) { auto &Str = unwrap(M)->getModuleInlineAsm(); *Len = Str.length(); return Str.c_str(); } LLVMValueRef LLVMGetInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringSize, char *Constraints, size_t ConstraintsSize, LLVMBool HasSideEffects, LLVMBool IsAlignStack, LLVMInlineAsmDialect Dialect) { InlineAsm::AsmDialect AD; switch (Dialect) { case LLVMInlineAsmDialectATT: AD = InlineAsm::AD_ATT; break; case LLVMInlineAsmDialectIntel: AD = InlineAsm::AD_Intel; break; } return wrap(InlineAsm::get(unwrap(Ty), StringRef(AsmString, AsmStringSize), StringRef(Constraints, ConstraintsSize), HasSideEffects, IsAlignStack, AD)); } /*--.. Operations on module contexts ......................................--*/ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M) { return wrap(&unwrap(M)->getContext()); } /*===-- Operations on types -----------------------------------------------===*/ /*--.. Operations on all types (mostly) ....................................--*/ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { switch (unwrap(Ty)->getTypeID()) { case Type::VoidTyID: return LLVMVoidTypeKind; case Type::HalfTyID: return LLVMHalfTypeKind; case Type::FloatTyID: return LLVMFloatTypeKind; case Type::DoubleTyID: return LLVMDoubleTypeKind; case Type::X86_FP80TyID: return LLVMX86_FP80TypeKind; case Type::FP128TyID: return LLVMFP128TypeKind; case Type::PPC_FP128TyID: return LLVMPPC_FP128TypeKind; case Type::LabelTyID: return LLVMLabelTypeKind; case Type::MetadataTyID: return LLVMMetadataTypeKind; case Type::IntegerTyID: return LLVMIntegerTypeKind; case Type::FunctionTyID: return LLVMFunctionTypeKind; case Type::StructTyID: return LLVMStructTypeKind; case Type::ArrayTyID: return LLVMArrayTypeKind; case Type::PointerTyID: return LLVMPointerTypeKind; case Type::VectorTyID: return LLVMVectorTypeKind; case Type::X86_MMXTyID: return LLVMX86_MMXTypeKind; case Type::TokenTyID: return LLVMTokenTypeKind; } llvm_unreachable("Unhandled TypeID."); } LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty) { return unwrap(Ty)->isSized(); } LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) { return wrap(&unwrap(Ty)->getContext()); } void LLVMDumpType(LLVMTypeRef Ty) { return unwrap(Ty)->print(errs(), /*IsForDebug=*/true); } char *LLVMPrintTypeToString(LLVMTypeRef Ty) { std::string buf; raw_string_ostream os(buf); if (unwrap(Ty)) unwrap(Ty)->print(os); else os << "Printing Type"; os.flush(); return strdup(buf.c_str()); } /*--.. Operations on integer types .........................................--*/ LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt1Ty(*unwrap(C)); } LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt8Ty(*unwrap(C)); } LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt16Ty(*unwrap(C)); } LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt32Ty(*unwrap(C)); } LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt64Ty(*unwrap(C)); } LLVMTypeRef LLVMInt128TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getInt128Ty(*unwrap(C)); } LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits) { return wrap(IntegerType::get(*unwrap(C), NumBits)); } LLVMTypeRef LLVMInt1Type(void) { return LLVMInt1TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMInt8Type(void) { return LLVMInt8TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMInt16Type(void) { return LLVMInt16TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMInt32Type(void) { return LLVMInt32TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMInt64Type(void) { return LLVMInt64TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMInt128Type(void) { return LLVMInt128TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMIntType(unsigned NumBits) { return LLVMIntTypeInContext(LLVMGetGlobalContext(), NumBits); } unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { return unwrap(IntegerTy)->getBitWidth(); } /*--.. Operations on real types ............................................--*/ LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getHalfTy(*unwrap(C)); } LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getFloatTy(*unwrap(C)); } LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getDoubleTy(*unwrap(C)); } LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getX86_FP80Ty(*unwrap(C)); } LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getFP128Ty(*unwrap(C)); } LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getPPC_FP128Ty(*unwrap(C)); } LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) { return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C)); } LLVMTypeRef LLVMHalfType(void) { return LLVMHalfTypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMFloatType(void) { return LLVMFloatTypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMDoubleType(void) { return LLVMDoubleTypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMX86FP80Type(void) { return LLVMX86FP80TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMFP128Type(void) { return LLVMFP128TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMPPCFP128Type(void) { return LLVMPPCFP128TypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMX86MMXType(void) { return LLVMX86MMXTypeInContext(LLVMGetGlobalContext()); } /*--.. Operations on function types ........................................--*/ LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType, LLVMTypeRef *ParamTypes, unsigned ParamCount, LLVMBool IsVarArg) { ArrayRef Tys(unwrap(ParamTypes), ParamCount); return wrap(FunctionType::get(unwrap(ReturnType), Tys, IsVarArg != 0)); } LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) { return unwrap(FunctionTy)->isVarArg(); } LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy) { return wrap(unwrap(FunctionTy)->getReturnType()); } unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy) { return unwrap(FunctionTy)->getNumParams(); } void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { FunctionType *Ty = unwrap(FunctionTy); for (FunctionType::param_iterator I = Ty->param_begin(), E = Ty->param_end(); I != E; ++I) *Dest++ = wrap(*I); } /*--.. Operations on struct types ..........................................--*/ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed) { ArrayRef Tys(unwrap(ElementTypes), ElementCount); return wrap(StructType::get(*unwrap(C), Tys, Packed != 0)); } LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed) { return LLVMStructTypeInContext(LLVMGetGlobalContext(), ElementTypes, ElementCount, Packed); } LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name) { return wrap(StructType::create(*unwrap(C), Name)); } const char *LLVMGetStructName(LLVMTypeRef Ty) { StructType *Type = unwrap(Ty); if (!Type->hasName()) return nullptr; return Type->getName().data(); } void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed) { ArrayRef Tys(unwrap(ElementTypes), ElementCount); unwrap(StructTy)->setBody(Tys, Packed != 0); } unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) { return unwrap(StructTy)->getNumElements(); } void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest) { StructType *Ty = unwrap(StructTy); for (StructType::element_iterator I = Ty->element_begin(), E = Ty->element_end(); I != E; ++I) *Dest++ = wrap(*I); } LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i) { StructType *Ty = unwrap(StructTy); return wrap(Ty->getTypeAtIndex(i)); } LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) { return unwrap(StructTy)->isPacked(); } LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy) { return unwrap(StructTy)->isOpaque(); } LLVMBool LLVMIsLiteralStruct(LLVMTypeRef StructTy) { return unwrap(StructTy)->isLiteral(); } LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { return wrap(unwrap(M)->getTypeByName(Name)); } /*--.. Operations on array, pointer, and vector types (sequence types) .....--*/ void LLVMGetSubtypes(LLVMTypeRef Tp, LLVMTypeRef *Arr) { int i = 0; for (auto *T : unwrap(Tp)->subtypes()) { Arr[i] = wrap(T); i++; } } LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) { return wrap(ArrayType::get(unwrap(ElementType), ElementCount)); } LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace) { return wrap(PointerType::get(unwrap(ElementType), AddressSpace)); } LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) { return wrap(VectorType::get(unwrap(ElementType), ElementCount)); } LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) { auto *Ty = unwrap(WrappedTy); if (auto *PTy = dyn_cast(Ty)) return wrap(PTy->getElementType()); return wrap(cast(Ty)->getElementType()); } unsigned LLVMGetNumContainedTypes(LLVMTypeRef Tp) { return unwrap(Tp)->getNumContainedTypes(); } unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) { return unwrap(ArrayTy)->getNumElements(); } unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy) { return unwrap(PointerTy)->getAddressSpace(); } unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) { return unwrap(VectorTy)->getNumElements(); } /*--.. Operations on other types ...........................................--*/ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) { return wrap(Type::getVoidTy(*unwrap(C))); } LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C) { return wrap(Type::getLabelTy(*unwrap(C))); } LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C) { return wrap(Type::getTokenTy(*unwrap(C))); } LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { return wrap(Type::getMetadataTy(*unwrap(C))); } LLVMTypeRef LLVMVoidType(void) { return LLVMVoidTypeInContext(LLVMGetGlobalContext()); } LLVMTypeRef LLVMLabelType(void) { return LLVMLabelTypeInContext(LLVMGetGlobalContext()); } /*===-- Operations on values ----------------------------------------------===*/ /*--.. Operations on all values ............................................--*/ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) { return wrap(unwrap(Val)->getType()); } LLVMValueKind LLVMGetValueKind(LLVMValueRef Val) { switch(unwrap(Val)->getValueID()) { #define HANDLE_VALUE(Name) \ case Value::Name##Val: \ return LLVM##Name##ValueKind; #include "llvm/IR/Value.def" default: return LLVMInstructionValueKind; } } const char *LLVMGetValueName2(LLVMValueRef Val, size_t *Length) { auto *V = unwrap(Val); *Length = V->getName().size(); return V->getName().data(); } void LLVMSetValueName2(LLVMValueRef Val, const char *Name, size_t NameLen) { unwrap(Val)->setName(StringRef(Name, NameLen)); } const char *LLVMGetValueName(LLVMValueRef Val) { return unwrap(Val)->getName().data(); } void LLVMSetValueName(LLVMValueRef Val, const char *Name) { unwrap(Val)->setName(Name); } void LLVMDumpValue(LLVMValueRef Val) { unwrap(Val)->print(errs(), /*IsForDebug=*/true); } char* LLVMPrintValueToString(LLVMValueRef Val) { std::string buf; raw_string_ostream os(buf); if (unwrap(Val)) unwrap(Val)->print(os); else os << "Printing Value"; os.flush(); return strdup(buf.c_str()); } void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); } int LLVMHasMetadata(LLVMValueRef Inst) { return unwrap(Inst)->hasMetadata(); } LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { auto *I = unwrap(Inst); assert(I && "Expected instruction"); if (auto *MD = I->getMetadata(KindID)) return wrap(MetadataAsValue::get(I->getContext(), MD)); return nullptr; } // MetadataAsValue uses a canonical format which strips the actual MDNode for // MDNode with just a single constant value, storing just a ConstantAsMetadata // This undoes this canonicalization, reconstructing the MDNode. static MDNode *extractMDNode(MetadataAsValue *MAV) { Metadata *MD = MAV->getMetadata(); assert((isa(MD) || isa(MD)) && "Expected a metadata node or a canonicalized constant"); if (MDNode *N = dyn_cast(MD)) return N; return MDNode::get(MAV->getContext(), MD); } void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { MDNode *N = Val ? extractMDNode(unwrap(Val)) : nullptr; unwrap(Inst)->setMetadata(KindID, N); } struct LLVMOpaqueValueMetadataEntry { unsigned Kind; LLVMMetadataRef Metadata; }; using MetadataEntries = SmallVectorImpl>; static LLVMValueMetadataEntry * llvm_getMetadata(size_t *NumEntries, llvm::function_ref AccessMD) { SmallVector, 8> MVEs; AccessMD(MVEs); LLVMOpaqueValueMetadataEntry *Result = static_cast( safe_malloc(MVEs.size() * sizeof(LLVMOpaqueValueMetadataEntry))); for (unsigned i = 0; i < MVEs.size(); ++i) { const auto &ModuleFlag = MVEs[i]; Result[i].Kind = ModuleFlag.first; Result[i].Metadata = wrap(ModuleFlag.second); } *NumEntries = MVEs.size(); return Result; } LLVMValueMetadataEntry * LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Value, size_t *NumEntries) { return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) { unwrap(Value)->getAllMetadata(Entries); }); } /*--.. Conversion functions ................................................--*/ #define LLVM_DEFINE_VALUE_CAST(name) \ LLVMValueRef LLVMIsA##name(LLVMValueRef Val) { \ return wrap(static_cast(dyn_cast_or_null(unwrap(Val)))); \ } LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST) LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) { if (auto *MD = dyn_cast_or_null(unwrap(Val))) if (isa(MD->getMetadata()) || isa(MD->getMetadata())) return Val; return nullptr; } LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) { if (auto *MD = dyn_cast_or_null(unwrap(Val))) if (isa(MD->getMetadata())) return Val; return nullptr; } /*--.. Operations on Uses ..................................................--*/ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value *V = unwrap(Val); Value::use_iterator I = V->use_begin(); if (I == V->use_end()) return nullptr; return wrap(&*I); } LLVMUseRef LLVMGetNextUse(LLVMUseRef U) { Use *Next = unwrap(U)->getNext(); if (Next) return wrap(Next); return nullptr; } LLVMValueRef LLVMGetUser(LLVMUseRef U) { return wrap(unwrap(U)->getUser()); } LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) { return wrap(unwrap(U)->get()); } /*--.. Operations on Users .................................................--*/ static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N, unsigned Index) { Metadata *Op = N->getOperand(Index); if (!Op) return nullptr; if (auto *C = dyn_cast(Op)) return wrap(C->getValue()); return wrap(MetadataAsValue::get(Context, Op)); } LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { Value *V = unwrap(Val); if (auto *MD = dyn_cast(V)) { if (auto *L = dyn_cast(MD->getMetadata())) { assert(Index == 0 && "Function-local metadata can only have one operand"); return wrap(L->getValue()); } return getMDNodeOperandImpl(V->getContext(), cast(MD->getMetadata()), Index); } return wrap(cast(V)->getOperand(Index)); } LLVMUseRef LLVMGetOperandUse(LLVMValueRef Val, unsigned Index) { Value *V = unwrap(Val); return wrap(&cast(V)->getOperandUse(Index)); } void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) { unwrap(Val)->setOperand(Index, unwrap(Op)); } int LLVMGetNumOperands(LLVMValueRef Val) { Value *V = unwrap(Val); if (isa(V)) return LLVMGetMDNodeNumOperands(Val); return cast(V)->getNumOperands(); } /*--.. Operations on constants of any type .................................--*/ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty) { return wrap(Constant::getNullValue(unwrap(Ty))); } LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty) { return wrap(Constant::getAllOnesValue(unwrap(Ty))); } LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty) { return wrap(UndefValue::get(unwrap(Ty))); } LLVMBool LLVMIsConstant(LLVMValueRef Ty) { return isa(unwrap(Ty)); } LLVMBool LLVMIsNull(LLVMValueRef Val) { if (Constant *C = dyn_cast(unwrap(Val))) return C->isNullValue(); return false; } LLVMBool LLVMIsUndef(LLVMValueRef Val) { return isa(unwrap(Val)); } LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) { return wrap(ConstantPointerNull::get(unwrap(Ty))); } /*--.. Operations on metadata nodes ........................................--*/ LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, unsigned SLen) { LLVMContext &Context = *unwrap(C); return wrap(MetadataAsValue::get( Context, MDString::get(Context, StringRef(Str, SLen)))); } LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { return LLVMMDStringInContext(LLVMGetGlobalContext(), Str, SLen); } LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, unsigned Count) { LLVMContext &Context = *unwrap(C); SmallVector MDs; for (auto *OV : makeArrayRef(Vals, Count)) { Value *V = unwrap(OV); Metadata *MD; if (!V) MD = nullptr; else if (auto *C = dyn_cast(V)) MD = ConstantAsMetadata::get(C); else if (auto *MDV = dyn_cast(V)) { MD = MDV->getMetadata(); assert(!isa(MD) && "Unexpected function-local metadata " "outside of direct argument to call"); } else { // This is function-local metadata. Pretend to make an MDNode. assert(Count == 1 && "Expected only one operand to function-local metadata"); return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V))); } MDs.push_back(MD); } return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs))); } LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count); } LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) { return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD))); } LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val) { auto *V = unwrap(Val); if (auto *C = dyn_cast(V)) return wrap(ConstantAsMetadata::get(C)); if (auto *MAV = dyn_cast(V)) return wrap(MAV->getMetadata()); return wrap(ValueAsMetadata::get(V)); } const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length) { if (const auto *MD = dyn_cast(unwrap(V))) if (const MDString *S = dyn_cast(MD->getMetadata())) { *Length = S->getString().size(); return S->getString().data(); } *Length = 0; return nullptr; } unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) { auto *MD = cast(unwrap(V)); if (isa(MD->getMetadata())) return 1; return cast(MD->getMetadata())->getNumOperands(); } LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::named_metadata_iterator I = Mod->named_metadata_begin(); if (I == Mod->named_metadata_end()) return nullptr; return wrap(&*I); } LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::named_metadata_iterator I = Mod->named_metadata_end(); if (I == Mod->named_metadata_begin()) return nullptr; return wrap(&*--I); } LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NMD) { NamedMDNode *NamedNode = unwrap(NMD); Module::named_metadata_iterator I(NamedNode); if (++I == NamedNode->getParent()->named_metadata_end()) return nullptr; return wrap(&*I); } LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NMD) { NamedMDNode *NamedNode = unwrap(NMD); Module::named_metadata_iterator I(NamedNode); if (I == NamedNode->getParent()->named_metadata_begin()) return nullptr; return wrap(&*--I); } LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M, const char *Name, size_t NameLen) { return wrap(unwrap(M)->getNamedMetadata(StringRef(Name, NameLen))); } LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M, const char *Name, size_t NameLen) { return wrap(unwrap(M)->getOrInsertNamedMetadata({Name, NameLen})); } const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NMD, size_t *NameLen) { NamedMDNode *NamedNode = unwrap(NMD); *NameLen = NamedNode->getName().size(); return NamedNode->getName().data(); } void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) { auto *MD = cast(unwrap(V)); if (auto *MDV = dyn_cast(MD->getMetadata())) { *Dest = wrap(MDV->getValue()); return; } const auto *N = cast(MD->getMetadata()); const unsigned numOperands = N->getNumOperands(); LLVMContext &Context = unwrap(V)->getContext(); for (unsigned i = 0; i < numOperands; i++) Dest[i] = getMDNodeOperandImpl(Context, N, i); } unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name) { if (NamedMDNode *N = unwrap(M)->getNamedMetadata(Name)) { return N->getNumOperands(); } return 0; } void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char *Name, LLVMValueRef *Dest) { NamedMDNode *N = unwrap(M)->getNamedMetadata(Name); if (!N) return; LLVMContext &Context = unwrap(M)->getContext(); for (unsigned i=0;igetNumOperands();i++) Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i))); } void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char *Name, LLVMValueRef Val) { NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(Name); if (!N) return; if (!Val) return; N->addOperand(extractMDNode(unwrap(Val))); } const char *LLVMGetDebugLocDirectory(LLVMValueRef Val, unsigned *Length) { if (!Length) return nullptr; StringRef S; if (const auto *I = unwrap(Val)) { S = I->getDebugLoc()->getDirectory(); } else if (const auto *GV = unwrap(Val)) { SmallVector GVEs; GV->getDebugInfo(GVEs); if (GVEs.size()) if (const DIGlobalVariable *DGV = GVEs[0]->getVariable()) S = DGV->getDirectory(); } else if (const auto *F = unwrap(Val)) { if (const DISubprogram *DSP = F->getSubprogram()) S = DSP->getDirectory(); } else { assert(0 && "Expected Instruction, GlobalVariable or Function"); return nullptr; } *Length = S.size(); return S.data(); } const char *LLVMGetDebugLocFilename(LLVMValueRef Val, unsigned *Length) { if (!Length) return nullptr; StringRef S; if (const auto *I = unwrap(Val)) { S = I->getDebugLoc()->getFilename(); } else if (const auto *GV = unwrap(Val)) { SmallVector GVEs; GV->getDebugInfo(GVEs); if (GVEs.size()) if (const DIGlobalVariable *DGV = GVEs[0]->getVariable()) S = DGV->getFilename(); } else if (const auto *F = unwrap(Val)) { if (const DISubprogram *DSP = F->getSubprogram()) S = DSP->getFilename(); } else { assert(0 && "Expected Instruction, GlobalVariable or Function"); return nullptr; } *Length = S.size(); return S.data(); } unsigned LLVMGetDebugLocLine(LLVMValueRef Val) { unsigned L = 0; if (const auto *I = unwrap(Val)) { L = I->getDebugLoc()->getLine(); } else if (const auto *GV = unwrap(Val)) { SmallVector GVEs; GV->getDebugInfo(GVEs); if (GVEs.size()) if (const DIGlobalVariable *DGV = GVEs[0]->getVariable()) L = DGV->getLine(); } else if (const auto *F = unwrap(Val)) { if (const DISubprogram *DSP = F->getSubprogram()) L = DSP->getLine(); } else { assert(0 && "Expected Instruction, GlobalVariable or Function"); return -1; } return L; } unsigned LLVMGetDebugLocColumn(LLVMValueRef Val) { unsigned C = 0; if (const auto *I = unwrap(Val)) if (const auto &L = I->getDebugLoc()) C = L->getColumn(); return C; } /*--.. Operations on scalar constants ......................................--*/ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, LLVMBool SignExtend) { return wrap(ConstantInt::get(unwrap(IntTy), N, SignExtend != 0)); } LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, unsigned NumWords, const uint64_t Words[]) { IntegerType *Ty = unwrap(IntTy); return wrap(ConstantInt::get(Ty->getContext(), APInt(Ty->getBitWidth(), makeArrayRef(Words, NumWords)))); } LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[], uint8_t Radix) { return wrap(ConstantInt::get(unwrap(IntTy), StringRef(Str), Radix)); } LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char Str[], unsigned SLen, uint8_t Radix) { return wrap(ConstantInt::get(unwrap(IntTy), StringRef(Str, SLen), Radix)); } LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N) { return wrap(ConstantFP::get(unwrap(RealTy), N)); } LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text) { return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Text))); } LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[], unsigned SLen) { return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen))); } unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) { return unwrap(ConstantVal)->getZExtValue(); } long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal) { return unwrap(ConstantVal)->getSExtValue(); } double LLVMConstRealGetDouble(LLVMValueRef ConstantVal, LLVMBool *LosesInfo) { ConstantFP *cFP = unwrap(ConstantVal) ; Type *Ty = cFP->getType(); if (Ty->isFloatTy()) { *LosesInfo = false; return cFP->getValueAPF().convertToFloat(); } if (Ty->isDoubleTy()) { *LosesInfo = false; return cFP->getValueAPF().convertToDouble(); } bool APFLosesInfo; APFloat APF = cFP->getValueAPF(); APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &APFLosesInfo); *LosesInfo = APFLosesInfo; return APF.convertToDouble(); } /*--.. Operations on composite constants ...................................--*/ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, unsigned Length, LLVMBool DontNullTerminate) { /* Inverted the sense of AddNull because ', 0)' is a better mnemonic for null termination than ', 1)'. */ return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), DontNullTerminate == 0)); } LLVMValueRef LLVMConstString(const char *Str, unsigned Length, LLVMBool DontNullTerminate) { return LLVMConstStringInContext(LLVMGetGlobalContext(), Str, Length, DontNullTerminate); } LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx) { return wrap(unwrap(C)->getElementAsConstant(idx)); } LLVMBool LLVMIsConstantString(LLVMValueRef C) { return unwrap(C)->isString(); } const char *LLVMGetAsString(LLVMValueRef C, size_t *Length) { StringRef Str = unwrap(C)->getAsString(); *Length = Str.size(); return Str.data(); } LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { ArrayRef V(unwrap(ConstantVals, Length), Length); return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); } LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { Constant **Elements = unwrap(ConstantVals, Count); return wrap(ConstantStruct::getAnon(*unwrap(C), makeArrayRef(Elements, Count), Packed != 0)); } LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count, Packed); } LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, LLVMValueRef *ConstantVals, unsigned Count) { Constant **Elements = unwrap(ConstantVals, Count); StructType *Ty = cast(unwrap(StructTy)); return wrap(ConstantStruct::get(Ty, makeArrayRef(Elements, Count))); } LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { return wrap(ConstantVector::get(makeArrayRef( unwrap(ScalarConstantVals, Size), Size))); } /*-- Opcode mapping */ static LLVMOpcode map_to_llvmopcode(int opcode) { switch (opcode) { default: llvm_unreachable("Unhandled Opcode."); #define HANDLE_INST(num, opc, clas) case num: return LLVM##opc; #include "llvm/IR/Instruction.def" #undef HANDLE_INST } } static int map_from_llvmopcode(LLVMOpcode code) { switch (code) { #define HANDLE_INST(num, opc, clas) case LLVM##opc: return num; #include "llvm/IR/Instruction.def" #undef HANDLE_INST } llvm_unreachable("Unhandled Opcode."); } /*--.. Constant expressions ................................................--*/ LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) { return map_to_llvmopcode(unwrap(ConstantVal)->getOpcode()); } LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty) { return wrap(ConstantExpr::getAlignOf(unwrap(Ty))); } LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) { return wrap(ConstantExpr::getSizeOf(unwrap(Ty))); } LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) { return wrap(ConstantExpr::getNeg(unwrap(ConstantVal))); } LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) { return wrap(ConstantExpr::getNSWNeg(unwrap(ConstantVal))); } LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) { return wrap(ConstantExpr::getNUWNeg(unwrap(ConstantVal))); } LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) { return wrap(ConstantExpr::getFNeg(unwrap(ConstantVal))); } LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal) { return wrap(ConstantExpr::getNot(unwrap(ConstantVal))); } LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getAdd(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNSWAdd(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNUWAdd(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFAdd(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getSub(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNSWSub(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNUWSub(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFSub(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getMul(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNSWMul(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getNUWMul(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFMul(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getUDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstExactUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getExactUDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getSDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getExactSDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getURem(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getSRem(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFRem(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getAnd(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getOr(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getXor(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate, LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getICmp(Predicate, unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate, LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFCmp(Predicate, unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getShl(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getLShr(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getAShr(unwrap(LHSConstant), unwrap(RHSConstant))); } LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices) { ArrayRef IdxList(unwrap(ConstantIndices, NumIndices), NumIndices); return wrap(ConstantExpr::getGetElementPtr( nullptr, unwrap(ConstantVal), IdxList)); } LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices) { Constant* Val = unwrap(ConstantVal); ArrayRef IdxList(unwrap(ConstantIndices, NumIndices), NumIndices); return wrap(ConstantExpr::getInBoundsGetElementPtr(nullptr, Val, IdxList)); } LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getTrunc(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getSExt(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getZExt(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getFPTrunc(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getFPExtend(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getUIToFP(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getSIToFP(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getFPToUI(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getFPToSI(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getPtrToInt(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getIntToPtr(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getBitCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getAddrSpaceCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getZExtOrBitCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getSExtOrBitCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getTruncOrBitCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getPointerCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType, LLVMBool isSigned) { return wrap(ConstantExpr::getIntegerCast(unwrap(ConstantVal), unwrap(ToType), isSigned)); } LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { return wrap(ConstantExpr::getFPCast(unwrap(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition, LLVMValueRef ConstantIfTrue, LLVMValueRef ConstantIfFalse) { return wrap(ConstantExpr::getSelect(unwrap(ConstantCondition), unwrap(ConstantIfTrue), unwrap(ConstantIfFalse))); } LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant, LLVMValueRef IndexConstant) { return wrap(ConstantExpr::getExtractElement(unwrap(VectorConstant), unwrap(IndexConstant))); } LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef ElementValueConstant, LLVMValueRef IndexConstant) { return wrap(ConstantExpr::getInsertElement(unwrap(VectorConstant), unwrap(ElementValueConstant), unwrap(IndexConstant))); } LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant) { return wrap(ConstantExpr::getShuffleVector(unwrap(VectorAConstant), unwrap(VectorBConstant), unwrap(MaskConstant))); } LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx) { return wrap(ConstantExpr::getExtractValue(unwrap(AggConstant), makeArrayRef(IdxList, NumIdx))); } LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx) { return wrap(ConstantExpr::getInsertValue(unwrap(AggConstant), unwrap(ElementValueConstant), makeArrayRef(IdxList, NumIdx))); } LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, const char *Constraints, LLVMBool HasSideEffects, LLVMBool IsAlignStack) { return wrap(InlineAsm::get(dyn_cast(unwrap(Ty)), AsmString, Constraints, HasSideEffects, IsAlignStack)); } LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB) { return wrap(BlockAddress::get(unwrap(F), unwrap(BB))); } /*--.. Operations on global variables, functions, and aliases (globals) ....--*/ LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global) { return wrap(unwrap(Global)->getParent()); } LLVMBool LLVMIsDeclaration(LLVMValueRef Global) { return unwrap(Global)->isDeclaration(); } LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { switch (unwrap(Global)->getLinkage()) { case GlobalValue::ExternalLinkage: return LLVMExternalLinkage; case GlobalValue::AvailableExternallyLinkage: return LLVMAvailableExternallyLinkage; case GlobalValue::LinkOnceAnyLinkage: return LLVMLinkOnceAnyLinkage; case GlobalValue::LinkOnceODRLinkage: return LLVMLinkOnceODRLinkage; case GlobalValue::WeakAnyLinkage: return LLVMWeakAnyLinkage; case GlobalValue::WeakODRLinkage: return LLVMWeakODRLinkage; case GlobalValue::AppendingLinkage: return LLVMAppendingLinkage; case GlobalValue::InternalLinkage: return LLVMInternalLinkage; case GlobalValue::PrivateLinkage: return LLVMPrivateLinkage; case GlobalValue::ExternalWeakLinkage: return LLVMExternalWeakLinkage; case GlobalValue::CommonLinkage: return LLVMCommonLinkage; } llvm_unreachable("Invalid GlobalValue linkage!"); } void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { GlobalValue *GV = unwrap(Global); switch (Linkage) { case LLVMExternalLinkage: GV->setLinkage(GlobalValue::ExternalLinkage); break; case LLVMAvailableExternallyLinkage: GV->setLinkage(GlobalValue::AvailableExternallyLinkage); break; case LLVMLinkOnceAnyLinkage: GV->setLinkage(GlobalValue::LinkOnceAnyLinkage); break; case LLVMLinkOnceODRLinkage: GV->setLinkage(GlobalValue::LinkOnceODRLinkage); break; case LLVMLinkOnceODRAutoHideLinkage: LLVM_DEBUG( errs() << "LLVMSetLinkage(): LLVMLinkOnceODRAutoHideLinkage is no " "longer supported."); break; case LLVMWeakAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); break; case LLVMWeakODRLinkage: GV->setLinkage(GlobalValue::WeakODRLinkage); break; case LLVMAppendingLinkage: GV->setLinkage(GlobalValue::AppendingLinkage); break; case LLVMInternalLinkage: GV->setLinkage(GlobalValue::InternalLinkage); break; case LLVMPrivateLinkage: GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMLinkerPrivateLinkage: GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMLinkerPrivateWeakLinkage: GV->setLinkage(GlobalValue::PrivateLinkage); break; case LLVMDLLImportLinkage: LLVM_DEBUG( errs() << "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported."); break; case LLVMDLLExportLinkage: LLVM_DEBUG( errs() << "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported."); break; case LLVMExternalWeakLinkage: GV->setLinkage(GlobalValue::ExternalWeakLinkage); break; case LLVMGhostLinkage: LLVM_DEBUG( errs() << "LLVMSetLinkage(): LLVMGhostLinkage is no longer supported."); break; case LLVMCommonLinkage: GV->setLinkage(GlobalValue::CommonLinkage); break; } } const char *LLVMGetSection(LLVMValueRef Global) { // Using .data() is safe because of how GlobalObject::setSection is // implemented. return unwrap(Global)->getSection().data(); } void LLVMSetSection(LLVMValueRef Global, const char *Section) { unwrap(Global)->setSection(Section); } LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { return static_cast( unwrap(Global)->getVisibility()); } void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { unwrap(Global) ->setVisibility(static_cast(Viz)); } LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global) { return static_cast( unwrap(Global)->getDLLStorageClass()); } void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) { unwrap(Global)->setDLLStorageClass( static_cast(Class)); } LLVMUnnamedAddr LLVMGetUnnamedAddress(LLVMValueRef Global) { switch (unwrap(Global)->getUnnamedAddr()) { case GlobalVariable::UnnamedAddr::None: return LLVMNoUnnamedAddr; case GlobalVariable::UnnamedAddr::Local: return LLVMLocalUnnamedAddr; case GlobalVariable::UnnamedAddr::Global: return LLVMGlobalUnnamedAddr; } llvm_unreachable("Unknown UnnamedAddr kind!"); } void LLVMSetUnnamedAddress(LLVMValueRef Global, LLVMUnnamedAddr UnnamedAddr) { GlobalValue *GV = unwrap(Global); switch (UnnamedAddr) { case LLVMNoUnnamedAddr: return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::None); case LLVMLocalUnnamedAddr: return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::Local); case LLVMGlobalUnnamedAddr: return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::Global); } } LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) { return unwrap(Global)->hasGlobalUnnamedAddr(); } void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) { unwrap(Global)->setUnnamedAddr( HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global : GlobalValue::UnnamedAddr::None); } LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef Global) { return wrap(unwrap(Global)->getValueType()); } /*--.. Operations on global variables, load and store instructions .........--*/ unsigned LLVMGetAlignment(LLVMValueRef V) { Value *P = unwrap(V); if (GlobalValue *GV = dyn_cast(P)) return GV->getAlignment(); if (AllocaInst *AI = dyn_cast(P)) return AI->getAlignment(); if (LoadInst *LI = dyn_cast(P)) return LI->getAlignment(); if (StoreInst *SI = dyn_cast(P)) return SI->getAlignment(); llvm_unreachable( "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); } void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { Value *P = unwrap(V); if (GlobalObject *GV = dyn_cast(P)) GV->setAlignment(Bytes); else if (AllocaInst *AI = dyn_cast(P)) AI->setAlignment(Bytes); else if (LoadInst *LI = dyn_cast(P)) LI->setAlignment(Bytes); else if (StoreInst *SI = dyn_cast(P)) SI->setAlignment(Bytes); else llvm_unreachable( "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); } LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value, size_t *NumEntries) { return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) { if (Instruction *Instr = dyn_cast(unwrap(Value))) { Instr->getAllMetadata(Entries); } else { unwrap(Value)->getAllMetadata(Entries); } }); } unsigned LLVMValueMetadataEntriesGetKind(LLVMValueMetadataEntry *Entries, unsigned Index) { LLVMOpaqueValueMetadataEntry MVE = static_cast(Entries[Index]); return MVE.Kind; } LLVMMetadataRef LLVMValueMetadataEntriesGetMetadata(LLVMValueMetadataEntry *Entries, unsigned Index) { LLVMOpaqueValueMetadataEntry MVE = static_cast(Entries[Index]); return MVE.Metadata; } void LLVMDisposeValueMetadataEntries(LLVMValueMetadataEntry *Entries) { free(Entries); } void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind, LLVMMetadataRef MD) { unwrap(Global)->setMetadata(Kind, unwrap(MD)); } void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind) { unwrap(Global)->eraseMetadata(Kind); } void LLVMGlobalClearMetadata(LLVMValueRef Global) { unwrap(Global)->clearMetadata(); } /*--.. Operations on global variables ......................................--*/ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, GlobalValue::ExternalLinkage, nullptr, Name)); } LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name, unsigned AddressSpace) { return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace)); } LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) { return wrap(unwrap(M)->getNamedGlobal(Name)); } LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::global_iterator I = Mod->global_begin(); if (I == Mod->global_end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::global_iterator I = Mod->global_end(); if (I == Mod->global_begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar) { GlobalVariable *GV = unwrap(GlobalVar); Module::global_iterator I(GV); if (++I == GV->getParent()->global_end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar) { GlobalVariable *GV = unwrap(GlobalVar); Module::global_iterator I(GV); if (I == GV->getParent()->global_begin()) return nullptr; return wrap(&*--I); } void LLVMDeleteGlobal(LLVMValueRef GlobalVar) { unwrap(GlobalVar)->eraseFromParent(); } LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) { GlobalVariable* GV = unwrap(GlobalVar); if ( !GV->hasInitializer() ) return nullptr; return wrap(GV->getInitializer()); } void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) { unwrap(GlobalVar) ->setInitializer(unwrap(ConstantVal)); } LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar) { return unwrap(GlobalVar)->isThreadLocal(); } void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal) { unwrap(GlobalVar)->setThreadLocal(IsThreadLocal != 0); } LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar) { return unwrap(GlobalVar)->isConstant(); } void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant) { unwrap(GlobalVar)->setConstant(IsConstant != 0); } LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar) { switch (unwrap(GlobalVar)->getThreadLocalMode()) { case GlobalVariable::NotThreadLocal: return LLVMNotThreadLocal; case GlobalVariable::GeneralDynamicTLSModel: return LLVMGeneralDynamicTLSModel; case GlobalVariable::LocalDynamicTLSModel: return LLVMLocalDynamicTLSModel; case GlobalVariable::InitialExecTLSModel: return LLVMInitialExecTLSModel; case GlobalVariable::LocalExecTLSModel: return LLVMLocalExecTLSModel; } llvm_unreachable("Invalid GlobalVariable thread local mode"); } void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode) { GlobalVariable *GV = unwrap(GlobalVar); switch (Mode) { case LLVMNotThreadLocal: GV->setThreadLocalMode(GlobalVariable::NotThreadLocal); break; case LLVMGeneralDynamicTLSModel: GV->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel); break; case LLVMLocalDynamicTLSModel: GV->setThreadLocalMode(GlobalVariable::LocalDynamicTLSModel); break; case LLVMInitialExecTLSModel: GV->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); break; case LLVMLocalExecTLSModel: GV->setThreadLocalMode(GlobalVariable::LocalExecTLSModel); break; } } LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar) { return unwrap(GlobalVar)->isExternallyInitialized(); } void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit) { unwrap(GlobalVar)->setExternallyInitialized(IsExtInit); } /*--.. Operations on aliases ......................................--*/ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name) { auto *PTy = cast(unwrap(Ty)); return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), GlobalValue::ExternalLinkage, Name, unwrap(Aliasee), unwrap(M))); } LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M, const char *Name, size_t NameLen) { return wrap(unwrap(M)->getNamedAlias(Name)); } LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::alias_iterator I = Mod->alias_begin(); if (I == Mod->alias_end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::alias_iterator I = Mod->alias_end(); if (I == Mod->alias_begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA) { GlobalAlias *Alias = unwrap(GA); Module::alias_iterator I(Alias); if (++I == Alias->getParent()->alias_end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA) { GlobalAlias *Alias = unwrap(GA); Module::alias_iterator I(Alias); if (I == Alias->getParent()->alias_begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias) { return wrap(unwrap(Alias)->getAliasee()); } void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee) { unwrap(Alias)->setAliasee(unwrap(Aliasee)); } /*--.. Operations on functions .............................................--*/ LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy) { return wrap(Function::Create(unwrap(FunctionTy), GlobalValue::ExternalLinkage, Name, unwrap(M))); } LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name) { return wrap(unwrap(M)->getFunction(Name)); } LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::iterator I = Mod->begin(); if (I == Mod->end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) { Module *Mod = unwrap(M); Module::iterator I = Mod->end(); if (I == Mod->begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Module::iterator I(Func); if (++I == Func->getParent()->end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Module::iterator I(Func); if (I == Func->getParent()->begin()) return nullptr; return wrap(&*--I); } void LLVMDeleteFunction(LLVMValueRef Fn) { unwrap(Fn)->eraseFromParent(); } LLVMBool LLVMHasPersonalityFn(LLVMValueRef Fn) { return unwrap(Fn)->hasPersonalityFn(); } LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn) { return wrap(unwrap(Fn)->getPersonalityFn()); } void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn) { unwrap(Fn)->setPersonalityFn(unwrap(PersonalityFn)); } unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) { if (Function *F = dyn_cast(unwrap(Fn))) return F->getIntrinsicID(); return 0; } static Intrinsic::ID llvm_map_to_intrinsic_id(unsigned ID) { assert(ID < llvm::Intrinsic::num_intrinsics && "Intrinsic ID out of range"); return llvm::Intrinsic::ID(ID); } LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount) { ArrayRef Tys(unwrap(ParamTypes), ParamCount); auto IID = llvm_map_to_intrinsic_id(ID); return wrap(llvm::Intrinsic::getDeclaration(unwrap(Mod), IID, Tys)); } const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) { auto IID = llvm_map_to_intrinsic_id(ID); auto Str = llvm::Intrinsic::getName(IID); *NameLength = Str.size(); return Str.data(); } LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount) { auto IID = llvm_map_to_intrinsic_id(ID); ArrayRef Tys(unwrap(ParamTypes), ParamCount); return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys)); } const char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount, size_t *NameLength) { auto IID = llvm_map_to_intrinsic_id(ID); ArrayRef Tys(unwrap(ParamTypes), ParamCount); auto Str = llvm::Intrinsic::getName(IID, Tys); *NameLength = Str.length(); return strdup(Str.c_str()); } LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID) { auto IID = llvm_map_to_intrinsic_id(ID); return llvm::Intrinsic::isOverloaded(IID); } unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) { return unwrap(Fn)->getCallingConv(); } void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { return unwrap(Fn)->setCallingConv( static_cast(CC)); } const char *LLVMGetGC(LLVMValueRef Fn) { Function *F = unwrap(Fn); return F->hasGC()? F->getGC().c_str() : nullptr; } void LLVMSetGC(LLVMValueRef Fn, const char *GC) { Function *F = unwrap(Fn); if (GC) F->setGC(GC); else F->clearGC(); } void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A) { unwrap(F)->addAttribute(Idx, unwrap(A)); } unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) { auto AS = unwrap(F)->getAttributes().getAttributes(Idx); return AS.getNumAttributes(); } void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { auto AS = unwrap(F)->getAttributes().getAttributes(Idx); for (auto A : AS) *Attrs++ = wrap(A); } LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { return wrap(unwrap(F)->getAttribute(Idx, (Attribute::AttrKind)KindID)); } LLVMAttributeRef LLVMGetStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { return wrap(unwrap(F)->getAttribute(Idx, StringRef(K, KLen))); } void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { unwrap(F)->removeAttribute(Idx, (Attribute::AttrKind)KindID); } void LLVMRemoveStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { unwrap(F)->removeAttribute(Idx, StringRef(K, KLen)); } void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, const char *V) { Function *Func = unwrap(Fn); Attribute Attr = Attribute::get(Func->getContext(), A, V); Func->addAttribute(AttributeList::FunctionIndex, Attr); } /*--.. Operations on parameters ............................................--*/ unsigned LLVMCountParams(LLVMValueRef FnRef) { // This function is strictly redundant to // LLVMCountParamTypes(LLVMGetElementType(LLVMTypeOf(FnRef))) return unwrap(FnRef)->arg_size(); } void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) { Function *Fn = unwrap(FnRef); for (Function::arg_iterator I = Fn->arg_begin(), E = Fn->arg_end(); I != E; I++) *ParamRefs++ = wrap(&*I); } LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) { Function *Fn = unwrap(FnRef); return wrap(&Fn->arg_begin()[index]); } LLVMValueRef LLVMGetParamParent(LLVMValueRef V) { return wrap(unwrap(V)->getParent()); } LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Function::arg_iterator I = Func->arg_begin(); if (I == Func->arg_end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Function::arg_iterator I = Func->arg_end(); if (I == Func->arg_begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg) { Argument *A = unwrap(Arg); Function *Fn = A->getParent(); if (A->getArgNo() + 1 >= Fn->arg_size()) return nullptr; return wrap(&Fn->arg_begin()[A->getArgNo() + 1]); } LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) { Argument *A = unwrap(Arg); if (A->getArgNo() == 0) return nullptr; return wrap(&A->getParent()->arg_begin()[A->getArgNo() - 1]); } void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { Argument *A = unwrap(Arg); A->addAttr(Attribute::getWithAlignment(A->getContext(), align)); } /*--.. Operations on basic blocks ..........................................--*/ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB) { return wrap(static_cast(unwrap(BB))); } LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val) { return isa(unwrap(Val)); } LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) { return wrap(unwrap(Val)); } const char *LLVMGetBasicBlockName(LLVMBasicBlockRef BB) { return unwrap(BB)->getName().data(); } LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB) { return wrap(unwrap(BB)->getParent()); } LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB) { return wrap(unwrap(BB)->getTerminator()); } unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) { return unwrap(FnRef)->size(); } void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){ Function *Fn = unwrap(FnRef); for (BasicBlock &BB : *Fn) *BasicBlocksRefs++ = wrap(&BB); } LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) { return wrap(&unwrap(Fn)->getEntryBlock()); } LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Function::iterator I = Func->begin(); if (I == Func->end()) return nullptr; return wrap(&*I); } LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) { Function *Func = unwrap(Fn); Function::iterator I = Func->end(); if (I == Func->begin()) return nullptr; return wrap(&*--I); } LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); Function::iterator I(Block); if (++I == Block->getParent()->end()) return nullptr; return wrap(&*I); } LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); Function::iterator I(Block); if (I == Block->getParent()->begin()) return nullptr; return wrap(&*--I); } LLVMBasicBlockRef LLVMCreateBasicBlockInContext(LLVMContextRef C, const char *Name) { return wrap(llvm::BasicBlock::Create(*unwrap(C), Name)); } LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C, LLVMValueRef FnRef, const char *Name) { return wrap(BasicBlock::Create(*unwrap(C), Name, unwrap(FnRef))); } LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) { return LLVMAppendBasicBlockInContext(LLVMGetGlobalContext(), FnRef, Name); } LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C, LLVMBasicBlockRef BBRef, const char *Name) { BasicBlock *BB = unwrap(BBRef); return wrap(BasicBlock::Create(*unwrap(C), Name, BB->getParent(), BB)); } LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef BBRef, const char *Name) { return LLVMInsertBasicBlockInContext(LLVMGetGlobalContext(), BBRef, Name); } void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) { unwrap(BBRef)->eraseFromParent(); } void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BBRef) { unwrap(BBRef)->removeFromParent(); } void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) { unwrap(BB)->moveBefore(unwrap(MovePos)); } void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) { unwrap(BB)->moveAfter(unwrap(MovePos)); } /*--.. Operations on instructions ..........................................--*/ LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst) { return wrap(unwrap(Inst)->getParent()); } LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); BasicBlock::iterator I = Block->begin(); if (I == Block->end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) { BasicBlock *Block = unwrap(BB); BasicBlock::iterator I = Block->end(); if (I == Block->begin()) return nullptr; return wrap(&*--I); } LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst) { Instruction *Instr = unwrap(Inst); BasicBlock::iterator I(Instr); if (++I == Instr->getParent()->end()) return nullptr; return wrap(&*I); } LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) { Instruction *Instr = unwrap(Inst); BasicBlock::iterator I(Instr); if (I == Instr->getParent()->begin()) return nullptr; return wrap(&*--I); } void LLVMInstructionRemoveFromParent(LLVMValueRef Inst) { unwrap(Inst)->removeFromParent(); } void LLVMInstructionEraseFromParent(LLVMValueRef Inst) { unwrap(Inst)->eraseFromParent(); } LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst) { if (ICmpInst *I = dyn_cast(unwrap(Inst))) return (LLVMIntPredicate)I->getPredicate(); if (ConstantExpr *CE = dyn_cast(unwrap(Inst))) if (CE->getOpcode() == Instruction::ICmp) return (LLVMIntPredicate)CE->getPredicate(); return (LLVMIntPredicate)0; } LLVMRealPredicate LLVMGetFCmpPredicate(LLVMValueRef Inst) { if (FCmpInst *I = dyn_cast(unwrap(Inst))) return (LLVMRealPredicate)I->getPredicate(); if (ConstantExpr *CE = dyn_cast(unwrap(Inst))) if (CE->getOpcode() == Instruction::FCmp) return (LLVMRealPredicate)CE->getPredicate(); return (LLVMRealPredicate)0; } LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst) { if (Instruction *C = dyn_cast(unwrap(Inst))) return map_to_llvmopcode(C->getOpcode()); return (LLVMOpcode)0; } LLVMValueRef LLVMInstructionClone(LLVMValueRef Inst) { if (Instruction *C = dyn_cast(unwrap(Inst))) return wrap(C->clone()); return nullptr; } LLVMValueRef LLVMIsATerminatorInst(LLVMValueRef Inst) { Instruction *I = dyn_cast(unwrap(Inst)); return (I && I->isTerminator()) ? wrap(I) : nullptr; } unsigned LLVMGetNumArgOperands(LLVMValueRef Instr) { if (FuncletPadInst *FPI = dyn_cast(unwrap(Instr))) { return FPI->getNumArgOperands(); } return unwrap(Instr)->getNumArgOperands(); } /*--.. Call and invoke instructions ........................................--*/ unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) { return unwrap(Instr)->getCallingConv(); } void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { return unwrap(Instr)->setCallingConv( static_cast(CC)); } void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned align) { auto *Call = unwrap(Instr); Attribute AlignAttr = Attribute::getWithAlignment(Call->getContext(), align); Call->addAttribute(index, AlignAttr); } void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef A) { unwrap(C)->addAttribute(Idx, unwrap(A)); } unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx) { auto *Call = unwrap(C); auto AS = Call->getAttributes().getAttributes(Idx); return AS.getNumAttributes(); } void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { auto *Call = unwrap(C); auto AS = Call->getAttributes().getAttributes(Idx); for (auto A : AS) *Attrs++ = wrap(A); } LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) { return wrap( unwrap(C)->getAttribute(Idx, (Attribute::AttrKind)KindID)); } LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { return wrap(unwrap(C)->getAttribute(Idx, StringRef(K, KLen))); } void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) { unwrap(C)->removeAttribute(Idx, (Attribute::AttrKind)KindID); } void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { unwrap(C)->removeAttribute(Idx, StringRef(K, KLen)); } LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) { return wrap(unwrap(Instr)->getCalledValue()); } LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef Instr) { return wrap(unwrap(Instr)->getFunctionType()); } /*--.. Operations on call instructions (only) ..............................--*/ LLVMBool LLVMIsTailCall(LLVMValueRef Call) { return unwrap(Call)->isTailCall(); } void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) { unwrap(Call)->setTailCall(isTailCall); } /*--.. Operations on invoke instructions (only) ............................--*/ LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) { return wrap(unwrap(Invoke)->getNormalDest()); } LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef Invoke) { if (CleanupReturnInst *CRI = dyn_cast(unwrap(Invoke))) { return wrap(CRI->getUnwindDest()); } else if (CatchSwitchInst *CSI = dyn_cast(unwrap(Invoke))) { return wrap(CSI->getUnwindDest()); } return wrap(unwrap(Invoke)->getUnwindDest()); } void LLVMSetNormalDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) { unwrap(Invoke)->setNormalDest(unwrap(B)); } void LLVMSetUnwindDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) { if (CleanupReturnInst *CRI = dyn_cast(unwrap(Invoke))) { return CRI->setUnwindDest(unwrap(B)); } else if (CatchSwitchInst *CSI = dyn_cast(unwrap(Invoke))) { return CSI->setUnwindDest(unwrap(B)); } unwrap(Invoke)->setUnwindDest(unwrap(B)); } /*--.. Operations on terminators ...........................................--*/ unsigned LLVMGetNumSuccessors(LLVMValueRef Term) { return unwrap(Term)->getNumSuccessors(); } LLVMBasicBlockRef LLVMGetSuccessor(LLVMValueRef Term, unsigned i) { return wrap(unwrap(Term)->getSuccessor(i)); } void LLVMSetSuccessor(LLVMValueRef Term, unsigned i, LLVMBasicBlockRef block) { return unwrap(Term)->setSuccessor(i, unwrap(block)); } /*--.. Operations on branch instructions (only) ............................--*/ LLVMBool LLVMIsConditional(LLVMValueRef Branch) { return unwrap(Branch)->isConditional(); } LLVMValueRef LLVMGetCondition(LLVMValueRef Branch) { return wrap(unwrap(Branch)->getCondition()); } void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond) { return unwrap(Branch)->setCondition(unwrap(Cond)); } /*--.. Operations on switch instructions (only) ............................--*/ LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef Switch) { return wrap(unwrap(Switch)->getDefaultDest()); } /*--.. Operations on alloca instructions (only) ............................--*/ LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca) { return wrap(unwrap(Alloca)->getAllocatedType()); } /*--.. Operations on gep instructions (only) ...............................--*/ LLVMBool LLVMIsInBounds(LLVMValueRef GEP) { return unwrap(GEP)->isInBounds(); } void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds) { return unwrap(GEP)->setIsInBounds(InBounds); } /*--.. Operations on phi nodes .............................................--*/ void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, LLVMBasicBlockRef *IncomingBlocks, unsigned Count) { PHINode *PhiVal = unwrap(PhiNode); for (unsigned I = 0; I != Count; ++I) PhiVal->addIncoming(unwrap(IncomingValues[I]), unwrap(IncomingBlocks[I])); } unsigned LLVMCountIncoming(LLVMValueRef PhiNode) { return unwrap(PhiNode)->getNumIncomingValues(); } LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index) { return wrap(unwrap(PhiNode)->getIncomingValue(Index)); } LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index) { return wrap(unwrap(PhiNode)->getIncomingBlock(Index)); } /*--.. Operations on extractvalue and insertvalue nodes ....................--*/ unsigned LLVMGetNumIndices(LLVMValueRef Inst) { auto *I = unwrap(Inst); if (auto *GEP = dyn_cast(I)) return GEP->getNumIndices(); if (auto *EV = dyn_cast(I)) return EV->getNumIndices(); if (auto *IV = dyn_cast(I)) return IV->getNumIndices(); if (auto *CE = dyn_cast(I)) return CE->getIndices().size(); llvm_unreachable( "LLVMGetNumIndices applies only to extractvalue and insertvalue!"); } const unsigned *LLVMGetIndices(LLVMValueRef Inst) { auto *I = unwrap(Inst); if (auto *EV = dyn_cast(I)) return EV->getIndices().data(); if (auto *IV = dyn_cast(I)) return IV->getIndices().data(); if (auto *CE = dyn_cast(I)) return CE->getIndices().data(); llvm_unreachable( "LLVMGetIndices applies only to extractvalue and insertvalue!"); } /*===-- Instruction builders ----------------------------------------------===*/ LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C) { return wrap(new IRBuilder<>(*unwrap(C))); } LLVMBuilderRef LLVMCreateBuilder(void) { return LLVMCreateBuilderInContext(LLVMGetGlobalContext()); } void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr) { BasicBlock *BB = unwrap(Block); auto I = Instr ? unwrap(Instr)->getIterator() : BB->end(); unwrap(Builder)->SetInsertPoint(BB, I); } void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) { Instruction *I = unwrap(Instr); unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator()); } void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) { BasicBlock *BB = unwrap(Block); unwrap(Builder)->SetInsertPoint(BB); } LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) { return wrap(unwrap(Builder)->GetInsertBlock()); } void LLVMClearInsertionPosition(LLVMBuilderRef Builder) { unwrap(Builder)->ClearInsertionPoint(); } void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr) { unwrap(Builder)->Insert(unwrap(Instr)); } void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr, const char *Name) { unwrap(Builder)->Insert(unwrap(Instr), Name); } void LLVMDisposeBuilder(LLVMBuilderRef Builder) { delete unwrap(Builder); } /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { MDNode *Loc = L ? cast(unwrap(L)->getMetadata()) : nullptr; unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { LLVMContext &Context = unwrap(Builder)->getContext(); return wrap(MetadataAsValue::get( Context, unwrap(Builder)->getCurrentDebugLocation().getAsMDNode())); } void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) { unwrap(Builder)->SetInstDebugLocation(unwrap(Inst)); } /*--.. Instruction builders ................................................--*/ LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) { return wrap(unwrap(B)->CreateRetVoid()); } LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { return wrap(unwrap(B)->CreateRet(unwrap(V))); } LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef B, LLVMValueRef *RetVals, unsigned N) { return wrap(unwrap(B)->CreateAggregateRet(unwrap(RetVals), N)); } LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { return wrap(unwrap(B)->CreateBr(unwrap(Dest))); } LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If, LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) { return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else))); } LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V, LLVMBasicBlockRef Else, unsigned NumCases) { return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases)); } LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr, unsigned NumDests) { return wrap(unwrap(B)->CreateIndirectBr(unwrap(Addr), NumDests)); } LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name) { Value *V = unwrap(Fn); FunctionType *FnT = cast(cast(V->getType())->getElementType()); return wrap( unwrap(B)->CreateInvoke(FnT, unwrap(Fn), unwrap(Then), unwrap(Catch), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name) { return wrap(unwrap(B)->CreateInvoke( unwrap(Ty), unwrap(Fn), unwrap(Then), unwrap(Catch), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef PersFn, unsigned NumClauses, const char *Name) { // The personality used to live on the landingpad instruction, but now it // lives on the parent function. For compatibility, take the provided // personality and put it on the parent function. if (PersFn) unwrap(B)->GetInsertBlock()->getParent()->setPersonalityFn( cast(unwrap(PersFn))); return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), NumClauses, Name)); } LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMValueRef *Args, unsigned NumArgs, const char *Name) { return wrap(unwrap(B)->CreateCatchPad(unwrap(ParentPad), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMValueRef *Args, unsigned NumArgs, const char *Name) { if (ParentPad == nullptr) { Type *Ty = Type::getTokenTy(unwrap(B)->getContext()); ParentPad = wrap(Constant::getNullValue(Ty)); } return wrap(unwrap(B)->CreateCleanupPad(unwrap(ParentPad), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) { return wrap(unwrap(B)->CreateResume(unwrap(Exn))); } LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad, LLVMBasicBlockRef UnwindBB, unsigned NumHandlers, const char *Name) { if (ParentPad == nullptr) { Type *Ty = Type::getTokenTy(unwrap(B)->getContext()); ParentPad = wrap(Constant::getNullValue(Ty)); } return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(UnwindBB), NumHandlers, Name)); } LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad, LLVMBasicBlockRef BB) { return wrap(unwrap(B)->CreateCatchRet(unwrap(CatchPad), unwrap(BB))); } LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CatchPad, LLVMBasicBlockRef BB) { return wrap(unwrap(B)->CreateCleanupRet(unwrap(CatchPad), unwrap(BB))); } LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { return wrap(unwrap(B)->CreateUnreachable()); } void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest) { unwrap(Switch)->addCase(unwrap(OnVal), unwrap(Dest)); } void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) { unwrap(IndirectBr)->addDestination(unwrap(Dest)); } unsigned LLVMGetNumClauses(LLVMValueRef LandingPad) { return unwrap(LandingPad)->getNumClauses(); } LLVMValueRef LLVMGetClause(LLVMValueRef LandingPad, unsigned Idx) { return wrap(unwrap(LandingPad)->getClause(Idx)); } void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal) { unwrap(LandingPad)-> addClause(cast(unwrap(ClauseVal))); } LLVMBool LLVMIsCleanup(LLVMValueRef LandingPad) { return unwrap(LandingPad)->isCleanup(); } void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) { unwrap(LandingPad)->setCleanup(Val); } void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef Dest) { unwrap(CatchSwitch)->addHandler(unwrap(Dest)); } unsigned LLVMGetNumHandlers(LLVMValueRef CatchSwitch) { return unwrap(CatchSwitch)->getNumHandlers(); } void LLVMGetHandlers(LLVMValueRef CatchSwitch, LLVMBasicBlockRef *Handlers) { CatchSwitchInst *CSI = unwrap(CatchSwitch); for (CatchSwitchInst::handler_iterator I = CSI->handler_begin(), E = CSI->handler_end(); I != E; ++I) *Handlers++ = wrap(*I); } LLVMValueRef LLVMGetParentCatchSwitch(LLVMValueRef CatchPad) { return wrap(unwrap(CatchPad)->getCatchSwitch()); } void LLVMSetParentCatchSwitch(LLVMValueRef CatchPad, LLVMValueRef CatchSwitch) { unwrap(CatchPad) ->setCatchSwitch(unwrap(CatchSwitch)); } /*--.. Funclets ...........................................................--*/ LLVMValueRef LLVMGetArgOperand(LLVMValueRef Funclet, unsigned i) { return wrap(unwrap(Funclet)->getArgOperand(i)); } void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value) { unwrap(Funclet)->setArgOperand(i, unwrap(value)); } /*--.. Arithmetic ..........................................................--*/ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNSWAdd(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNUWAdd(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFAdd(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNSWSub(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNUWSub(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFSub(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNSWMul(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateNUWMul(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFMul(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateExactSDiv(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateBinOp(Instruction::BinaryOps(map_from_llvmopcode(Op)), unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNeg(unwrap(V), Name)); } LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNSWNeg(unwrap(V), Name)); } LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNUWNeg(unwrap(V), Name)); } LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name)); } LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); } /*--.. Memory ..............................................................--*/ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), ITy, unwrap(Ty), AllocSize, nullptr, nullptr, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name) { Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), ITy, unwrap(Ty), AllocSize, unwrap(Val), nullptr, ""); return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); } LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Len, unsigned Align) { return wrap(unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Len), Align)); } LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size) { return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), DstAlign, unwrap(Src), SrcAlign, unwrap(Size))); } LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size) { return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), DstAlign, unwrap(Src), SrcAlign, unwrap(Size))); } LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), nullptr, Name)); } LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name) { return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name)); } LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { return wrap(unwrap(B)->Insert( CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock()))); } LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, const char *Name) { - return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); + Value *V = unwrap(PointerVal); + PointerType *Ty = cast(V->getType()); + + return wrap(unwrap(B)->CreateLoad(Ty->getElementType(), V, Name)); +} + +LLVMValueRef LLVMBuildLoad2(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef PointerVal, const char *Name) { + return wrap(unwrap(B)->CreateLoad(unwrap(Ty), unwrap(PointerVal), Name)); } LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, LLVMValueRef PointerVal) { return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); } static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) { switch (Ordering) { case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic; case LLVMAtomicOrderingUnordered: return AtomicOrdering::Unordered; case LLVMAtomicOrderingMonotonic: return AtomicOrdering::Monotonic; case LLVMAtomicOrderingAcquire: return AtomicOrdering::Acquire; case LLVMAtomicOrderingRelease: return AtomicOrdering::Release; case LLVMAtomicOrderingAcquireRelease: return AtomicOrdering::AcquireRelease; case LLVMAtomicOrderingSequentiallyConsistent: return AtomicOrdering::SequentiallyConsistent; } llvm_unreachable("Invalid LLVMAtomicOrdering value!"); } static LLVMAtomicOrdering mapToLLVMOrdering(AtomicOrdering Ordering) { switch (Ordering) { case AtomicOrdering::NotAtomic: return LLVMAtomicOrderingNotAtomic; case AtomicOrdering::Unordered: return LLVMAtomicOrderingUnordered; case AtomicOrdering::Monotonic: return LLVMAtomicOrderingMonotonic; case AtomicOrdering::Acquire: return LLVMAtomicOrderingAcquire; case AtomicOrdering::Release: return LLVMAtomicOrderingRelease; case AtomicOrdering::AcquireRelease: return LLVMAtomicOrderingAcquireRelease; case AtomicOrdering::SequentiallyConsistent: return LLVMAtomicOrderingSequentiallyConsistent; } llvm_unreachable("Invalid AtomicOrdering value!"); } // TODO: Should this and other atomic instructions support building with // "syncscope"? LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering, LLVMBool isSingleThread, const char *Name) { return wrap( unwrap(B)->CreateFence(mapFromLLVMOrdering(Ordering), isSingleThread ? SyncScope::SingleThread : SyncScope::System, Name)); } LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef *Indices, unsigned NumIndices, const char *Name) { ArrayRef IdxList(unwrap(Indices), NumIndices); return wrap(unwrap(B)->CreateGEP(nullptr, unwrap(Pointer), IdxList, Name)); } LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef *Indices, unsigned NumIndices, const char *Name) { ArrayRef IdxList(unwrap(Indices), NumIndices); return wrap( unwrap(B)->CreateInBoundsGEP(nullptr, unwrap(Pointer), IdxList, Name)); } LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer, unsigned Idx, const char *Name) { return wrap(unwrap(B)->CreateStructGEP(nullptr, unwrap(Pointer), Idx, Name)); } LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str, const char *Name) { return wrap(unwrap(B)->CreateGlobalString(Str, Name)); } LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str, const char *Name) { return wrap(unwrap(B)->CreateGlobalStringPtr(Str, Name)); } LLVMBool LLVMGetVolatile(LLVMValueRef MemAccessInst) { Value *P = unwrap(MemAccessInst); if (LoadInst *LI = dyn_cast(P)) return LI->isVolatile(); return cast(P)->isVolatile(); } void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) { Value *P = unwrap(MemAccessInst); if (LoadInst *LI = dyn_cast(P)) return LI->setVolatile(isVolatile); return cast(P)->setVolatile(isVolatile); } LLVMAtomicOrdering LLVMGetOrdering(LLVMValueRef MemAccessInst) { Value *P = unwrap(MemAccessInst); AtomicOrdering O; if (LoadInst *LI = dyn_cast(P)) O = LI->getOrdering(); else O = cast(P)->getOrdering(); return mapToLLVMOrdering(O); } void LLVMSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering) { Value *P = unwrap(MemAccessInst); AtomicOrdering O = mapFromLLVMOrdering(Ordering); if (LoadInst *LI = dyn_cast(P)) return LI->setOrdering(O); return cast(P)->setOrdering(O); } /*--.. Casts ...............................................................--*/ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateSExtOrBitCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateTruncOrBitCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateCast(Instruction::CastOps(map_from_llvmopcode(Op)), unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreatePointerCast(unwrap(Val), unwrap(DestTy), Name)); } LLVMValueRef LLVMBuildIntCast2(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, LLVMBool IsSigned, const char *Name) { return wrap( unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), IsSigned, Name)); } LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), /*isSigned*/true, Name)); } LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef B, LLVMValueRef Val, LLVMTypeRef DestTy, const char *Name) { return wrap(unwrap(B)->CreateFPCast(unwrap(Val), unwrap(DestTy), Name)); } /*--.. Comparisons .........................................................--*/ LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateICmp(static_cast(Op), unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFCmp(static_cast(Op), unwrap(LHS), unwrap(RHS), Name)); } /*--.. Miscellaneous instructions ..........................................--*/ LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { return wrap(unwrap(B)->CreatePHI(unwrap(Ty), 0, Name)); } LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name) { Value *V = unwrap(Fn); FunctionType *FnT = cast(cast(V->getType())->getElementType()); return wrap(unwrap(B)->CreateCall(FnT, unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildCall2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name) { FunctionType *FTy = unwrap(Ty); return wrap(unwrap(B)->CreateCall(FTy, unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name)); } LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, const char *Name) { return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else), Name)); } LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List, LLVMTypeRef Ty, const char *Name) { return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name)); } LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal, LLVMValueRef Index, const char *Name) { return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index), Name)); } LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, const char *Name) { return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal), unwrap(Index), Name)); } LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, const char *Name) { return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2), unwrap(Mask), Name)); } LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef B, LLVMValueRef AggVal, unsigned Index, const char *Name) { return wrap(unwrap(B)->CreateExtractValue(unwrap(AggVal), Index, Name)); } LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, const char *Name) { return wrap(unwrap(B)->CreateInsertValue(unwrap(AggVal), unwrap(EltVal), Index, Name)); } LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val, const char *Name) { return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name)); } LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef B, LLVMValueRef Val, const char *Name) { return wrap(unwrap(B)->CreateIsNotNull(unwrap(Val), Name)); } LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name)); } LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, LLVMValueRef PTR, LLVMValueRef Val, LLVMAtomicOrdering ordering, LLVMBool singleThread) { AtomicRMWInst::BinOp intop; switch (op) { case LLVMAtomicRMWBinOpXchg: intop = AtomicRMWInst::Xchg; break; case LLVMAtomicRMWBinOpAdd: intop = AtomicRMWInst::Add; break; case LLVMAtomicRMWBinOpSub: intop = AtomicRMWInst::Sub; break; case LLVMAtomicRMWBinOpAnd: intop = AtomicRMWInst::And; break; case LLVMAtomicRMWBinOpNand: intop = AtomicRMWInst::Nand; break; case LLVMAtomicRMWBinOpOr: intop = AtomicRMWInst::Or; break; case LLVMAtomicRMWBinOpXor: intop = AtomicRMWInst::Xor; break; case LLVMAtomicRMWBinOpMax: intop = AtomicRMWInst::Max; break; case LLVMAtomicRMWBinOpMin: intop = AtomicRMWInst::Min; break; case LLVMAtomicRMWBinOpUMax: intop = AtomicRMWInst::UMax; break; case LLVMAtomicRMWBinOpUMin: intop = AtomicRMWInst::UMin; break; } return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), mapFromLLVMOrdering(ordering), singleThread ? SyncScope::SingleThread : SyncScope::System)); } LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Cmp, LLVMValueRef New, LLVMAtomicOrdering SuccessOrdering, LLVMAtomicOrdering FailureOrdering, LLVMBool singleThread) { return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(Ptr), unwrap(Cmp), unwrap(New), mapFromLLVMOrdering(SuccessOrdering), mapFromLLVMOrdering(FailureOrdering), singleThread ? SyncScope::SingleThread : SyncScope::System)); } LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) { Value *P = unwrap(AtomicInst); if (AtomicRMWInst *I = dyn_cast(P)) return I->getSyncScopeID() == SyncScope::SingleThread; return cast(P)->getSyncScopeID() == SyncScope::SingleThread; } void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) { Value *P = unwrap(AtomicInst); SyncScope::ID SSID = NewValue ? SyncScope::SingleThread : SyncScope::System; if (AtomicRMWInst *I = dyn_cast(P)) return I->setSyncScopeID(SSID); return cast(P)->setSyncScopeID(SSID); } LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) { Value *P = unwrap(CmpXchgInst); return mapToLLVMOrdering(cast(P)->getSuccessOrdering()); } void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst, LLVMAtomicOrdering Ordering) { Value *P = unwrap(CmpXchgInst); AtomicOrdering O = mapFromLLVMOrdering(Ordering); return cast(P)->setSuccessOrdering(O); } LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst) { Value *P = unwrap(CmpXchgInst); return mapToLLVMOrdering(cast(P)->getFailureOrdering()); } void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst, LLVMAtomicOrdering Ordering) { Value *P = unwrap(CmpXchgInst); AtomicOrdering O = mapFromLLVMOrdering(Ordering); return cast(P)->setFailureOrdering(O); } /*===-- Module providers --------------------------------------------------===*/ LLVMModuleProviderRef LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M) { return reinterpret_cast(M); } void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) { delete unwrap(MP); } /*===-- Memory buffers ----------------------------------------------------===*/ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile( const char *Path, LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { ErrorOr> MBOrErr = MemoryBuffer::getFile(Path); if (std::error_code EC = MBOrErr.getError()) { *OutMessage = strdup(EC.message().c_str()); return 1; } *OutMemBuf = wrap(MBOrErr.get().release()); return 0; } LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { ErrorOr> MBOrErr = MemoryBuffer::getSTDIN(); if (std::error_code EC = MBOrErr.getError()) { *OutMessage = strdup(EC.message().c_str()); return 1; } *OutMemBuf = wrap(MBOrErr.get().release()); return 0; } LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange( const char *InputData, size_t InputDataLength, const char *BufferName, LLVMBool RequiresNullTerminator) { return wrap(MemoryBuffer::getMemBuffer(StringRef(InputData, InputDataLength), StringRef(BufferName), RequiresNullTerminator).release()); } LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy( const char *InputData, size_t InputDataLength, const char *BufferName) { return wrap( MemoryBuffer::getMemBufferCopy(StringRef(InputData, InputDataLength), StringRef(BufferName)).release()); } const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf) { return unwrap(MemBuf)->getBufferStart(); } size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf) { return unwrap(MemBuf)->getBufferSize(); } void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { delete unwrap(MemBuf); } /*===-- Pass Registry -----------------------------------------------------===*/ LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) { return wrap(PassRegistry::getPassRegistry()); } /*===-- Pass Manager ------------------------------------------------------===*/ LLVMPassManagerRef LLVMCreatePassManager() { return wrap(new legacy::PassManager()); } LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) { return wrap(new legacy::FunctionPassManager(unwrap(M))); } LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) { return LLVMCreateFunctionPassManagerForModule( reinterpret_cast(P)); } LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { return unwrap(PM)->run(*unwrap(M)); } LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) { return unwrap(FPM)->doInitialization(); } LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) { return unwrap(FPM)->run(*unwrap(F)); } LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) { return unwrap(FPM)->doFinalization(); } void LLVMDisposePassManager(LLVMPassManagerRef PM) { delete unwrap(PM); } /*===-- Threading ------------------------------------------------------===*/ LLVMBool LLVMStartMultithreaded() { return LLVMIsMultithreaded(); } void LLVMStopMultithreaded() { } LLVMBool LLVMIsMultithreaded() { return llvm_is_multithreaded(); } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index d88779bae738..06b46724a87f 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1,4043 +1,4002 @@ //===- Instructions.cpp - Implement the LLVM instructions -----------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements all of the non-inline methods for the LLVM instruction // classes. // //===----------------------------------------------------------------------===// #include "llvm/IR/Instructions.h" #include "LLVMContextImpl.h" #include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include #include #include #include using namespace llvm; //===----------------------------------------------------------------------===// // AllocaInst Class //===----------------------------------------------------------------------===// Optional AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const { uint64_t Size = DL.getTypeAllocSizeInBits(getAllocatedType()); if (isArrayAllocation()) { auto C = dyn_cast(getArraySize()); if (!C) return None; Size *= C->getZExtValue(); } return Size; } //===----------------------------------------------------------------------===// // CallSite Class //===----------------------------------------------------------------------===// User::op_iterator CallSite::getCallee() const { return cast(getInstruction())->op_end() - 1; } //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// /// areInvalidOperands - Return a string if the specified operands are invalid /// for a select operation, otherwise return null. const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { if (Op1->getType() != Op2->getType()) return "both values to select must have same type"; if (Op1->getType()->isTokenTy()) return "select values cannot have token type"; if (VectorType *VT = dyn_cast(Op0->getType())) { // Vector select. if (VT->getElementType() != Type::getInt1Ty(Op0->getContext())) return "vector select condition element type must be i1"; VectorType *ET = dyn_cast(Op1->getType()); if (!ET) return "selected values for vector select must be vectors"; if (ET->getNumElements() != VT->getNumElements()) return "vector select requires selected vectors to have " "the same vector length as select condition"; } else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) { return "select condition must be i1 or "; } return nullptr; } //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// PHINode::PHINode(const PHINode &PN) : Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { allocHungoffUses(PN.getNumOperands()); std::copy(PN.op_begin(), PN.op_end(), op_begin()); std::copy(PN.block_begin(), PN.block_end(), block_begin()); SubclassOptionalData = PN.SubclassOptionalData; } // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { Value *Removed = getIncomingValue(Idx); // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, // clients might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. Op<-1>().set(nullptr); setNumHungOffUseOperands(getNumOperands() - 1); // If the PHI node is dead, because it has zero entries, nuke it now. if (getNumOperands() == 0 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); } return Removed; } /// growOperands - grow operands - This grows the operand list in response /// to a push_back style of operation. This grows the number of ops by 1.5 /// times. /// void PHINode::growOperands() { unsigned e = getNumOperands(); unsigned NumOps = e + e / 2; if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. ReservedSpace = NumOps; growHungoffUses(ReservedSpace, /* IsPhi */ true); } /// hasConstantValue - If the specified PHI node always merges together the same /// value, return the value, otherwise return null. Value *PHINode::hasConstantValue() const { // Exploit the fact that phi nodes always have at least one entry. Value *ConstantValue = getIncomingValue(0); for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i) if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) { if (ConstantValue != this) return nullptr; // Incoming values not all the same. // The case where the first value is this PHI. ConstantValue = getIncomingValue(i); } if (ConstantValue == this) return UndefValue::get(getType()); return ConstantValue; } /// hasConstantOrUndefValue - Whether the specified PHI node always merges /// together the same value, assuming that undefs result in the same value as /// non-undefs. /// Unlike \ref hasConstantValue, this does not return a value because the /// unique non-undef incoming value need not dominate the PHI node. bool PHINode::hasConstantOrUndefValue() const { Value *ConstantValue = nullptr; for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i) { Value *Incoming = getIncomingValue(i); if (Incoming != this && !isa(Incoming)) { if (ConstantValue && ConstantValue != Incoming) return false; ConstantValue = Incoming; } } return true; } //===----------------------------------------------------------------------===// // LandingPadInst Implementation //===----------------------------------------------------------------------===// LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues, const Twine &NameStr, Instruction *InsertBefore) : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) { init(NumReservedValues, NameStr); } LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertAtEnd) { init(NumReservedValues, NameStr); } LandingPadInst::LandingPadInst(const LandingPadInst &LP) : Instruction(LP.getType(), Instruction::LandingPad, nullptr, LP.getNumOperands()), ReservedSpace(LP.getNumOperands()) { allocHungoffUses(LP.getNumOperands()); Use *OL = getOperandList(); const Use *InOL = LP.getOperandList(); for (unsigned I = 0, E = ReservedSpace; I != E; ++I) OL[I] = InOL[I]; setCleanup(LP.isCleanup()); } LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, Instruction *InsertBefore) { return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertBefore); } LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertAtEnd); } void LandingPadInst::init(unsigned NumReservedValues, const Twine &NameStr) { ReservedSpace = NumReservedValues; setNumHungOffUseOperands(0); allocHungoffUses(ReservedSpace); setName(NameStr); setCleanup(false); } /// growOperands - grow operands - This grows the operand list in response to a /// push_back style of operation. This grows the number of ops by 2 times. void LandingPadInst::growOperands(unsigned Size) { unsigned e = getNumOperands(); if (ReservedSpace >= e + Size) return; ReservedSpace = (std::max(e, 1U) + Size / 2) * 2; growHungoffUses(ReservedSpace); } void LandingPadInst::addClause(Constant *Val) { unsigned OpNo = getNumOperands(); growOperands(1); assert(OpNo < ReservedSpace && "Growing didn't work!"); setNumHungOffUseOperands(getNumOperands() + 1); getOperandList()[OpNo] = Val; } //===----------------------------------------------------------------------===// // CallBase Implementation //===----------------------------------------------------------------------===// Function *CallBase::getCaller() { return getParent()->getParent(); } bool CallBase::isIndirectCall() const { const Value *V = getCalledValue(); if (isa(V) || isa(V)) return false; if (const CallInst *CI = dyn_cast(this)) if (CI->isInlineAsm()) return false; return true; } Intrinsic::ID CallBase::getIntrinsicID() const { if (auto *F = getCalledFunction()) return F->getIntrinsicID(); return Intrinsic::not_intrinsic; } bool CallBase::isReturnNonNull() const { if (hasRetAttr(Attribute::NonNull)) return true; if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 && !NullPointerIsDefined(getCaller(), getType()->getPointerAddressSpace())) return true; return false; } Value *CallBase::getReturnedArgOperand() const { unsigned Index; if (Attrs.hasAttrSomewhere(Attribute::Returned, &Index) && Index) return getArgOperand(Index - AttributeList::FirstArgIndex); if (const Function *F = getCalledFunction()) if (F->getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) && Index) return getArgOperand(Index - AttributeList::FirstArgIndex); return nullptr; } bool CallBase::hasRetAttr(Attribute::AttrKind Kind) const { if (Attrs.hasAttribute(AttributeList::ReturnIndex, Kind)) return true; // Look at the callee, if available. if (const Function *F = getCalledFunction()) return F->getAttributes().hasAttribute(AttributeList::ReturnIndex, Kind); return false; } /// Determine whether the argument or parameter has the given attribute. bool CallBase::paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { assert(ArgNo < getNumArgOperands() && "Param index out of bounds!"); if (Attrs.hasParamAttribute(ArgNo, Kind)) return true; if (const Function *F = getCalledFunction()) return F->getAttributes().hasParamAttribute(ArgNo, Kind); return false; } bool CallBase::hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const { if (const Function *F = getCalledFunction()) return F->getAttributes().hasAttribute(AttributeList::FunctionIndex, Kind); return false; } bool CallBase::hasFnAttrOnCalledFunction(StringRef Kind) const { if (const Function *F = getCalledFunction()) return F->getAttributes().hasAttribute(AttributeList::FunctionIndex, Kind); return false; } CallBase::op_iterator CallBase::populateBundleOperandInfos(ArrayRef Bundles, const unsigned BeginIndex) { auto It = op_begin() + BeginIndex; for (auto &B : Bundles) It = std::copy(B.input_begin(), B.input_end(), It); auto *ContextImpl = getContext().pImpl; auto BI = Bundles.begin(); unsigned CurrentIndex = BeginIndex; for (auto &BOI : bundle_op_infos()) { assert(BI != Bundles.end() && "Incorrect allocation?"); BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->getTag()); BOI.Begin = CurrentIndex; BOI.End = CurrentIndex + BI->input_size(); CurrentIndex = BOI.End; BI++; } assert(BI == Bundles.end() && "Incorrect allocation?"); return It; } //===----------------------------------------------------------------------===// // CallInst Implementation //===----------------------------------------------------------------------===// void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr) { this->FTy = FTy; assert(getNumOperands() == Args.size() + CountBundleInputs(Bundles) + 1 && "NumOperands not set up?"); setCalledOperand(Func); #ifndef NDEBUG assert((Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"); for (unsigned i = 0; i != Args.size(); ++i) assert((i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"); #endif llvm::copy(Args, op_begin()); auto It = populateBundleOperandInfos(Bundles, Args.size()); (void)It; assert(It + 1 == op_end() && "Should add up!"); setName(NameStr); } void CallInst::init(FunctionType *FTy, Value *Func, const Twine &NameStr) { this->FTy = FTy; assert(getNumOperands() == 1 && "NumOperands not set up?"); setCalledOperand(Func); assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); setName(NameStr); } CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name, Instruction *InsertBefore) : CallBase(Ty->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - 1, 1, InsertBefore) { init(Ty, Func, Name); } CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name, BasicBlock *InsertAtEnd) : CallBase(Ty->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - 1, 1, InsertAtEnd) { init(Ty, Func, Name); } CallInst::CallInst(const CallInst &CI) : CallBase(CI.Attrs, CI.FTy, CI.getType(), Instruction::Call, OperandTraits::op_end(this) - CI.getNumOperands(), CI.getNumOperands()) { setTailCallKind(CI.getTailCallKind()); setCallingConv(CI.getCallingConv()); std::copy(CI.op_begin(), CI.op_end(), op_begin()); std::copy(CI.bundle_op_info_begin(), CI.bundle_op_info_end(), bundle_op_info_begin()); SubclassOptionalData = CI.SubclassOptionalData; } CallInst *CallInst::Create(CallInst *CI, ArrayRef OpB, Instruction *InsertPt) { std::vector Args(CI->arg_begin(), CI->arg_end()); auto *NewCI = CallInst::Create(CI->getCalledValue(), Args, OpB, CI->getName(), InsertPt); NewCI->setTailCallKind(CI->getTailCallKind()); NewCI->setCallingConv(CI->getCallingConv()); NewCI->SubclassOptionalData = CI->SubclassOptionalData; NewCI->setAttributes(CI->getAttributes()); NewCI->setDebugLoc(CI->getDebugLoc()); return NewCI; } /// IsConstantOne - Return true only if val is constant int 1 static bool IsConstantOne(Value *val) { assert(val && "IsConstantOne does not work with nullptr val"); const ConstantInt *CVal = dyn_cast(val); return CVal && CVal->isOne(); } static Instruction *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, ArrayRef OpB, Function *MallocF, const Twine &Name) { assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && "createMalloc needs either InsertBefore or InsertAtEnd"); // malloc(type) becomes: // bitcast (i8* malloc(typeSize)) to type* // malloc(type, arraySize) becomes: // bitcast (i8* malloc(typeSize*arraySize)) to type* if (!ArraySize) ArraySize = ConstantInt::get(IntPtrTy, 1); else if (ArraySize->getType() != IntPtrTy) { if (InsertBefore) ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false, "", InsertBefore); else ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false, "", InsertAtEnd); } if (!IsConstantOne(ArraySize)) { if (IsConstantOne(AllocSize)) { AllocSize = ArraySize; // Operand * 1 = Operand } else if (Constant *CO = dyn_cast(ArraySize)) { Constant *Scale = ConstantExpr::getIntegerCast(CO, IntPtrTy, false /*ZExt*/); // Malloc arg is constant product of type size and array size AllocSize = ConstantExpr::getMul(Scale, cast(AllocSize)); } else { // Multiply type size by the array size... if (InsertBefore) AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, "mallocsize", InsertBefore); else AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, "mallocsize", InsertAtEnd); } } assert(AllocSize->getType() == IntPtrTy && "malloc arg is wrong size"); // Create the call to Malloc. BasicBlock *BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; Module *M = BB->getParent()->getParent(); Type *BPTy = Type::getInt8PtrTy(BB->getContext()); Value *MallocFunc = MallocF; if (!MallocFunc) // prototype malloc as "void *malloc(size_t)" MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy); PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); CallInst *MCall = nullptr; Instruction *Result = nullptr; if (InsertBefore) { MCall = CallInst::Create(MallocFunc, AllocSize, OpB, "malloccall", InsertBefore); Result = MCall; if (Result->getType() != AllocPtrType) // Create a cast instruction to convert to the right type... Result = new BitCastInst(MCall, AllocPtrType, Name, InsertBefore); } else { MCall = CallInst::Create(MallocFunc, AllocSize, OpB, "malloccall"); Result = MCall; if (Result->getType() != AllocPtrType) { InsertAtEnd->getInstList().push_back(MCall); // Create a cast instruction to convert to the right type... Result = new BitCastInst(MCall, AllocPtrType, Name); } } MCall->setTailCall(); if (Function *F = dyn_cast(MallocFunc)) { MCall->setCallingConv(F->getCallingConv()); if (!F->returnDoesNotAlias()) F->setReturnDoesNotAlias(); } assert(!MCall->getType()->isVoidTy() && "Malloc has void return type"); return Result; } /// CreateMalloc - Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not /// constant 1. /// 2. Call malloc with that argument. /// 3. Bitcast the result of the malloc call to the specified type. Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, Function *MallocF, const Twine &Name) { return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize, ArraySize, None, MallocF, Name); } Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, ArrayRef OpB, Function *MallocF, const Twine &Name) { return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize, ArraySize, OpB, MallocF, Name); } /// CreateMalloc - Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not /// constant 1. /// 2. Call malloc with that argument. /// 3. Bitcast the result of the malloc call to the specified type. /// Note: This function does not add the bitcast to the basic block, that is the /// responsibility of the caller. Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, Function *MallocF, const Twine &Name) { return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, ArraySize, None, MallocF, Name); } Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize, ArrayRef OpB, Function *MallocF, const Twine &Name) { return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, ArraySize, OpB, MallocF, Name); } static Instruction *createFree(Value *Source, ArrayRef Bundles, Instruction *InsertBefore, BasicBlock *InsertAtEnd) { assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && "createFree needs either InsertBefore or InsertAtEnd"); assert(Source->getType()->isPointerTy() && "Can not free something of nonpointer type!"); BasicBlock *BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; Module *M = BB->getParent()->getParent(); Type *VoidTy = Type::getVoidTy(M->getContext()); Type *IntPtrTy = Type::getInt8PtrTy(M->getContext()); // prototype free as "void free(void*)" Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy); CallInst *Result = nullptr; Value *PtrCast = Source; if (InsertBefore) { if (Source->getType() != IntPtrTy) PtrCast = new BitCastInst(Source, IntPtrTy, "", InsertBefore); Result = CallInst::Create(FreeFunc, PtrCast, Bundles, "", InsertBefore); } else { if (Source->getType() != IntPtrTy) PtrCast = new BitCastInst(Source, IntPtrTy, "", InsertAtEnd); Result = CallInst::Create(FreeFunc, PtrCast, Bundles, ""); } Result->setTailCall(); if (Function *F = dyn_cast(FreeFunc)) Result->setCallingConv(F->getCallingConv()); return Result; } /// CreateFree - Generate the IR for a call to the builtin free function. Instruction *CallInst::CreateFree(Value *Source, Instruction *InsertBefore) { return createFree(Source, None, InsertBefore, nullptr); } Instruction *CallInst::CreateFree(Value *Source, ArrayRef Bundles, Instruction *InsertBefore) { return createFree(Source, Bundles, InsertBefore, nullptr); } /// CreateFree - Generate the IR for a call to the builtin free function. /// Note: This function does not add the call to the basic block, that is the /// responsibility of the caller. Instruction *CallInst::CreateFree(Value *Source, BasicBlock *InsertAtEnd) { Instruction *FreeCall = createFree(Source, None, nullptr, InsertAtEnd); assert(FreeCall && "CreateFree did not create a CallInst"); return FreeCall; } Instruction *CallInst::CreateFree(Value *Source, ArrayRef Bundles, BasicBlock *InsertAtEnd) { Instruction *FreeCall = createFree(Source, Bundles, nullptr, InsertAtEnd); assert(FreeCall && "CreateFree did not create a CallInst"); return FreeCall; } //===----------------------------------------------------------------------===// // InvokeInst Implementation //===----------------------------------------------------------------------===// void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr) { this->FTy = FTy; assert((int)getNumOperands() == ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)) && "NumOperands not set up?"); setNormalDest(IfNormal); setUnwindDest(IfException); setCalledOperand(Fn); #ifndef NDEBUG assert(((Args.size() == FTy->getNumParams()) || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Invoking a function with bad signature"); for (unsigned i = 0, e = Args.size(); i != e; i++) assert((i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Invoking a function with a bad signature!"); #endif llvm::copy(Args, op_begin()); auto It = populateBundleOperandInfos(Bundles, Args.size()); (void)It; assert(It + 3 == op_end() && "Should add up!"); setName(NameStr); } InvokeInst::InvokeInst(const InvokeInst &II) : CallBase(II.Attrs, II.FTy, II.getType(), Instruction::Invoke, OperandTraits::op_end(this) - II.getNumOperands(), II.getNumOperands()) { setCallingConv(II.getCallingConv()); std::copy(II.op_begin(), II.op_end(), op_begin()); std::copy(II.bundle_op_info_begin(), II.bundle_op_info_end(), bundle_op_info_begin()); SubclassOptionalData = II.SubclassOptionalData; } InvokeInst *InvokeInst::Create(InvokeInst *II, ArrayRef OpB, Instruction *InsertPt) { std::vector Args(II->arg_begin(), II->arg_end()); auto *NewII = InvokeInst::Create(II->getCalledValue(), II->getNormalDest(), II->getUnwindDest(), Args, OpB, II->getName(), InsertPt); NewII->setCallingConv(II->getCallingConv()); NewII->SubclassOptionalData = II->SubclassOptionalData; NewII->setAttributes(II->getAttributes()); NewII->setDebugLoc(II->getDebugLoc()); return NewII; } LandingPadInst *InvokeInst::getLandingPadInst() const { return cast(getUnwindDest()->getFirstNonPHI()); } //===----------------------------------------------------------------------===// // ReturnInst Implementation //===----------------------------------------------------------------------===// ReturnInst::ReturnInst(const ReturnInst &RI) : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Ret, OperandTraits::op_end(this) - RI.getNumOperands(), RI.getNumOperands()) { if (RI.getNumOperands()) Op<0>() = RI.Op<0>(); SubclassOptionalData = RI.SubclassOptionalData; } ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, Instruction *InsertBefore) : Instruction(Type::getVoidTy(C), Instruction::Ret, OperandTraits::op_end(this) - !!retVal, !!retVal, InsertBefore) { if (retVal) Op<0>() = retVal; } ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(C), Instruction::Ret, OperandTraits::op_end(this) - !!retVal, !!retVal, InsertAtEnd) { if (retVal) Op<0>() = retVal; } ReturnInst::ReturnInst(LLVMContext &Context, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(Context), Instruction::Ret, OperandTraits::op_end(this), 0, InsertAtEnd) {} //===----------------------------------------------------------------------===// // ResumeInst Implementation //===----------------------------------------------------------------------===// ResumeInst::ResumeInst(const ResumeInst &RI) : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1) { Op<0>() = RI.Op<0>(); } ResumeInst::ResumeInst(Value *Exn, Instruction *InsertBefore) : Instruction(Type::getVoidTy(Exn->getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1, InsertBefore) { Op<0>() = Exn; } ResumeInst::ResumeInst(Value *Exn, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(Exn->getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1, InsertAtEnd) { Op<0>() = Exn; } //===----------------------------------------------------------------------===// // CleanupReturnInst Implementation //===----------------------------------------------------------------------===// CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI) : Instruction(CRI.getType(), Instruction::CleanupRet, OperandTraits::op_end(this) - CRI.getNumOperands(), CRI.getNumOperands()) { setInstructionSubclassData(CRI.getSubclassDataFromInstruction()); Op<0>() = CRI.Op<0>(); if (CRI.hasUnwindDest()) Op<1>() = CRI.Op<1>(); } void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) { if (UnwindBB) setInstructionSubclassData(getSubclassDataFromInstruction() | 1); Op<0>() = CleanupPad; if (UnwindBB) Op<1>() = UnwindBB; } CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, Instruction *InsertBefore) : Instruction(Type::getVoidTy(CleanupPad->getContext()), Instruction::CleanupRet, OperandTraits::op_end(this) - Values, Values, InsertBefore) { init(CleanupPad, UnwindBB); } CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(CleanupPad->getContext()), Instruction::CleanupRet, OperandTraits::op_end(this) - Values, Values, InsertAtEnd) { init(CleanupPad, UnwindBB); } //===----------------------------------------------------------------------===// // CatchReturnInst Implementation //===----------------------------------------------------------------------===// void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) { Op<0>() = CatchPad; Op<1>() = BB; } CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI) : Instruction(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet, OperandTraits::op_begin(this), 2) { Op<0>() = CRI.Op<0>(); Op<1>() = CRI.Op<1>(); } CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore) : Instruction(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, OperandTraits::op_begin(this), 2, InsertBefore) { init(CatchPad, BB); } CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(BB->getContext()), Instruction::CatchRet, OperandTraits::op_begin(this), 2, InsertAtEnd) { init(CatchPad, BB); } //===----------------------------------------------------------------------===// // CatchSwitchInst Implementation //===----------------------------------------------------------------------===// CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReservedValues, const Twine &NameStr, Instruction *InsertBefore) : Instruction(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0, InsertBefore) { if (UnwindDest) ++NumReservedValues; init(ParentPad, UnwindDest, NumReservedValues + 1); setName(NameStr); } CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0, InsertAtEnd) { if (UnwindDest) ++NumReservedValues; init(ParentPad, UnwindDest, NumReservedValues + 1); setName(NameStr); } CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI) : Instruction(CSI.getType(), Instruction::CatchSwitch, nullptr, CSI.getNumOperands()) { init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands()); setNumHungOffUseOperands(ReservedSpace); Use *OL = getOperandList(); const Use *InOL = CSI.getOperandList(); for (unsigned I = 1, E = ReservedSpace; I != E; ++I) OL[I] = InOL[I]; } void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReservedValues) { assert(ParentPad && NumReservedValues); ReservedSpace = NumReservedValues; setNumHungOffUseOperands(UnwindDest ? 2 : 1); allocHungoffUses(ReservedSpace); Op<0>() = ParentPad; if (UnwindDest) { setInstructionSubclassData(getSubclassDataFromInstruction() | 1); setUnwindDest(UnwindDest); } } /// growOperands - grow operands - This grows the operand list in response to a /// push_back style of operation. This grows the number of ops by 2 times. void CatchSwitchInst::growOperands(unsigned Size) { unsigned NumOperands = getNumOperands(); assert(NumOperands >= 1); if (ReservedSpace >= NumOperands + Size) return; ReservedSpace = (NumOperands + Size / 2) * 2; growHungoffUses(ReservedSpace); } void CatchSwitchInst::addHandler(BasicBlock *Handler) { unsigned OpNo = getNumOperands(); growOperands(1); assert(OpNo < ReservedSpace && "Growing didn't work!"); setNumHungOffUseOperands(getNumOperands() + 1); getOperandList()[OpNo] = Handler; } void CatchSwitchInst::removeHandler(handler_iterator HI) { // Move all subsequent handlers up one. Use *EndDst = op_end() - 1; for (Use *CurDst = HI.getCurrent(); CurDst != EndDst; ++CurDst) *CurDst = *(CurDst + 1); // Null out the last handler use. *EndDst = nullptr; setNumHungOffUseOperands(getNumOperands() - 1); } //===----------------------------------------------------------------------===// // FuncletPadInst Implementation //===----------------------------------------------------------------------===// void FuncletPadInst::init(Value *ParentPad, ArrayRef Args, const Twine &NameStr) { assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?"); llvm::copy(Args, op_begin()); setParentPad(ParentPad); setName(NameStr); } FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI) : Instruction(FPI.getType(), FPI.getOpcode(), OperandTraits::op_end(this) - FPI.getNumOperands(), FPI.getNumOperands()) { std::copy(FPI.op_begin(), FPI.op_end(), op_begin()); setParentPad(FPI.getParentPad()); } FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, ArrayRef Args, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : Instruction(ParentPad->getType(), Op, OperandTraits::op_end(this) - Values, Values, InsertBefore) { init(ParentPad, Args, NameStr); } FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, ArrayRef Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(ParentPad->getType(), Op, OperandTraits::op_end(this) - Values, Values, InsertAtEnd) { init(ParentPad, Args, NameStr); } //===----------------------------------------------------------------------===// // UnreachableInst Implementation //===----------------------------------------------------------------------===// UnreachableInst::UnreachableInst(LLVMContext &Context, Instruction *InsertBefore) : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr, 0, InsertBefore) {} UnreachableInst::UnreachableInst(LLVMContext &Context, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr, 0, InsertAtEnd) {} //===----------------------------------------------------------------------===// // BranchInst Implementation //===----------------------------------------------------------------------===// void BranchInst::AssertOK() { if (isConditional()) assert(getCondition()->getType()->isIntegerTy(1) && "May only branch on boolean predicates!"); } BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore) : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits::op_end(this) - 1, 1, InsertBefore) { assert(IfTrue && "Branch destination may not be null!"); Op<-1>() = IfTrue; } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore) : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits::op_end(this) - 3, 3, InsertBefore) { Op<-1>() = IfTrue; Op<-2>() = IfFalse; Op<-3>() = Cond; #ifndef NDEBUG AssertOK(); #endif } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits::op_end(this) - 1, 1, InsertAtEnd) { assert(IfTrue && "Branch destination may not be null!"); Op<-1>() = IfTrue; } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits::op_end(this) - 3, 3, InsertAtEnd) { Op<-1>() = IfTrue; Op<-2>() = IfFalse; Op<-3>() = Cond; #ifndef NDEBUG AssertOK(); #endif } BranchInst::BranchInst(const BranchInst &BI) : Instruction(Type::getVoidTy(BI.getContext()), Instruction::Br, OperandTraits::op_end(this) - BI.getNumOperands(), BI.getNumOperands()) { Op<-1>() = BI.Op<-1>(); if (BI.getNumOperands() != 1) { assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!"); Op<-3>() = BI.Op<-3>(); Op<-2>() = BI.Op<-2>(); } SubclassOptionalData = BI.SubclassOptionalData; } void BranchInst::swapSuccessors() { assert(isConditional() && "Cannot swap successors of an unconditional branch"); Op<-1>().swap(Op<-2>()); // Update profile metadata if present and it matches our structural // expectations. swapProfMetadata(); } //===----------------------------------------------------------------------===// // AllocaInst Implementation //===----------------------------------------------------------------------===// static Value *getAISize(LLVMContext &Context, Value *Amt) { if (!Amt) Amt = ConstantInt::get(Type::getInt32Ty(Context), 1); else { assert(!isa(Amt) && "Passed basic block into allocation size parameter! Use other ctor"); assert(Amt->getType()->isIntegerTy() && "Allocation array size is not an integer!"); } return Amt; } AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, Instruction *InsertBefore) : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertBefore) {} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, BasicBlock *InsertAtEnd) : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertAtEnd) {} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, Instruction *InsertBefore) : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertBefore) {} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, BasicBlock *InsertAtEnd) : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertAtEnd) {} AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name, Instruction *InsertBefore) : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, getAISize(Ty->getContext(), ArraySize), InsertBefore), AllocatedType(Ty) { setAlignment(Align); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); } AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd) : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, getAISize(Ty->getContext(), ArraySize), InsertAtEnd), AllocatedType(Ty) { setAlignment(Align); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); } void AllocaInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); setInstructionSubclassData((getSubclassDataFromInstruction() & ~31) | (Log2_32(Align) + 1)); assert(getAlignment() == Align && "Alignment representation error!"); } bool AllocaInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast(getOperand(0))) return !CI->isOne(); return true; } /// isStaticAlloca - Return true if this alloca is in the entry block of the /// function and is a constant size. If so, the code generator will fold it /// into the prolog/epilog code, so it is basically free. bool AllocaInst::isStaticAlloca() const { // Must be constant size. if (!isa(getArraySize())) return false; // Must be in the entry block. const BasicBlock *Parent = getParent(); return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca(); } //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// void LoadInst::AssertOK() { assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type."); assert(!(isAtomic() && getAlignment() == 0) && "Alignment required for atomic load"); } -LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef) - : LoadInst(Ptr, Name, /*isVolatile=*/false, InsertBef) {} +LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, + Instruction *InsertBef) + : LoadInst(Ty, Ptr, Name, /*isVolatile=*/false, InsertBef) {} -LoadInst::LoadInst(Value *Ptr, const Twine &Name, BasicBlock *InsertAE) - : LoadInst(Ptr, Name, /*isVolatile=*/false, InsertAE) {} +LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, + BasicBlock *InsertAE) + : LoadInst(Ty, Ptr, Name, /*isVolatile=*/false, InsertAE) {} LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, Instruction *InsertBef) : LoadInst(Ty, Ptr, Name, isVolatile, /*Align=*/0, InsertBef) {} -LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, +LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, BasicBlock *InsertAE) - : LoadInst(Ptr, Name, isVolatile, /*Align=*/0, InsertAE) {} + : LoadInst(Ty, Ptr, Name, isVolatile, /*Align=*/0, InsertAE) {} LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, unsigned Align, Instruction *InsertBef) : LoadInst(Ty, Ptr, Name, isVolatile, Align, AtomicOrdering::NotAtomic, SyncScope::System, InsertBef) {} -LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, +LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, unsigned Align, BasicBlock *InsertAE) - : LoadInst(Ptr, Name, isVolatile, Align, AtomicOrdering::NotAtomic, + : LoadInst(Ty, Ptr, Name, isVolatile, Align, AtomicOrdering::NotAtomic, SyncScope::System, InsertAE) {} LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, Instruction *InsertBef) : UnaryInstruction(Ty, Load, Ptr, InsertBef) { assert(Ty == cast(Ptr->getType())->getElementType()); setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SSID); AssertOK(); setName(Name); } -LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, - unsigned Align, AtomicOrdering Order, - SyncScope::ID SSID, +LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, + unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, InsertAE) { + : UnaryInstruction(Ty, Load, Ptr, InsertAE) { + assert(Ty == cast(Ptr->getType())->getElementType()); setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SSID); AssertOK(); setName(Name); } -LoadInst::LoadInst(Value *Ptr, const char *Name, Instruction *InsertBef) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, InsertBef) { - setVolatile(false); - setAlignment(0); - setAtomic(AtomicOrdering::NotAtomic); - AssertOK(); - if (Name && Name[0]) setName(Name); -} - -LoadInst::LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, InsertAE) { - setVolatile(false); - setAlignment(0); - setAtomic(AtomicOrdering::NotAtomic); - AssertOK(); - if (Name && Name[0]) setName(Name); -} - -LoadInst::LoadInst(Type *Ty, Value *Ptr, const char *Name, bool isVolatile, - Instruction *InsertBef) - : UnaryInstruction(Ty, Load, Ptr, InsertBef) { - assert(Ty == cast(Ptr->getType())->getElementType()); - setVolatile(isVolatile); - setAlignment(0); - setAtomic(AtomicOrdering::NotAtomic); - AssertOK(); - if (Name && Name[0]) setName(Name); -} - -LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile, - BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, InsertAE) { - setVolatile(isVolatile); - setAlignment(0); - setAtomic(AtomicOrdering::NotAtomic); - AssertOK(); - if (Name && Name[0]) setName(Name); -} - void LoadInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | ((Log2_32(Align)+1)<<1)); assert(getAlignment() == Align && "Alignment representation error!"); } //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// void StoreInst::AssertOK() { assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!"); assert(getOperand(1)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(0)->getType() == cast(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"); assert(!(isAtomic() && getAlignment() == 0) && "Alignment required for atomic store"); } StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) : StoreInst(val, addr, /*isVolatile=*/false, InsertBefore) {} StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd) : StoreInst(val, addr, /*isVolatile=*/false, InsertAtEnd) {} StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Instruction *InsertBefore) : StoreInst(val, addr, isVolatile, /*Align=*/0, InsertBefore) {} StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, BasicBlock *InsertAtEnd) : StoreInst(val, addr, isVolatile, /*Align=*/0, InsertAtEnd) {} StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, Instruction *InsertBefore) : StoreInst(val, addr, isVolatile, Align, AtomicOrdering::NotAtomic, SyncScope::System, InsertBefore) {} StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd) : StoreInst(val, addr, isVolatile, Align, AtomicOrdering::NotAtomic, SyncScope::System, InsertAtEnd) {} StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, Instruction *InsertBefore) : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { Op<0>() = val; Op<1>() = addr; setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SSID); AssertOK(); } StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { Op<0>() = val; Op<1>() = addr; setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SSID); AssertOK(); } void StoreInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | ((Log2_32(Align)+1) << 1)); assert(getAlignment() == Align && "Alignment representation error!"); } //===----------------------------------------------------------------------===// // AtomicCmpXchgInst Implementation //===----------------------------------------------------------------------===// void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID) { Op<0>() = Ptr; Op<1>() = Cmp; Op<2>() = NewVal; setSuccessOrdering(SuccessOrdering); setFailureOrdering(FailureOrdering); setSyncScopeID(SSID); assert(getOperand(0) && getOperand(1) && getOperand(2) && "All operands must be non-null!"); assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(1)->getType() == cast(getOperand(0)->getType())->getElementType() && "Ptr must be a pointer to Cmp type!"); assert(getOperand(2)->getType() == cast(getOperand(0)->getType())->getElementType() && "Ptr must be a pointer to NewVal type!"); assert(SuccessOrdering != AtomicOrdering::NotAtomic && "AtomicCmpXchg instructions must be atomic!"); assert(FailureOrdering != AtomicOrdering::NotAtomic && "AtomicCmpXchg instructions must be atomic!"); assert(!isStrongerThan(FailureOrdering, SuccessOrdering) && "AtomicCmpXchg failure argument shall be no stronger than the success " "argument"); assert(FailureOrdering != AtomicOrdering::Release && FailureOrdering != AtomicOrdering::AcquireRelease && "AtomicCmpXchg failure ordering cannot include release semantics"); } AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID, Instruction *InsertBefore) : Instruction( StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext())), AtomicCmpXchg, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SSID); } AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : Instruction( StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext())), AtomicCmpXchg, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { Init(Ptr, Cmp, NewVal, SuccessOrdering, FailureOrdering, SSID); } //===----------------------------------------------------------------------===// // AtomicRMWInst Implementation //===----------------------------------------------------------------------===// void AtomicRMWInst::Init(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SyncScope::ID SSID) { Op<0>() = Ptr; Op<1>() = Val; setOperation(Operation); setOrdering(Ordering); setSyncScopeID(SSID); assert(getOperand(0) && getOperand(1) && "All operands must be non-null!"); assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(1)->getType() == cast(getOperand(0)->getType())->getElementType() && "Ptr must be a pointer to Val type!"); assert(Ordering != AtomicOrdering::NotAtomic && "AtomicRMW instructions must be atomic!"); } AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SyncScope::ID SSID, Instruction *InsertBefore) : Instruction(Val->getType(), AtomicRMW, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { Init(Operation, Ptr, Val, Ordering, SSID); } AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, AtomicOrdering Ordering, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : Instruction(Val->getType(), AtomicRMW, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { Init(Operation, Ptr, Val, Ordering, SSID); } StringRef AtomicRMWInst::getOperationName(BinOp Op) { switch (Op) { case AtomicRMWInst::Xchg: return "xchg"; case AtomicRMWInst::Add: return "add"; case AtomicRMWInst::Sub: return "sub"; case AtomicRMWInst::And: return "and"; case AtomicRMWInst::Nand: return "nand"; case AtomicRMWInst::Or: return "or"; case AtomicRMWInst::Xor: return "xor"; case AtomicRMWInst::Max: return "max"; case AtomicRMWInst::Min: return "min"; case AtomicRMWInst::UMax: return "umax"; case AtomicRMWInst::UMin: return "umin"; case AtomicRMWInst::BAD_BINOP: return ""; } llvm_unreachable("invalid atomicrmw operation"); } //===----------------------------------------------------------------------===// // FenceInst Implementation //===----------------------------------------------------------------------===// FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, SyncScope::ID SSID, Instruction *InsertBefore) : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) { setOrdering(Ordering); setSyncScopeID(SSID); } FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertAtEnd) { setOrdering(Ordering); setSyncScopeID(SSID); } //===----------------------------------------------------------------------===// // GetElementPtrInst Implementation //===----------------------------------------------------------------------===// void GetElementPtrInst::init(Value *Ptr, ArrayRef IdxList, const Twine &Name) { assert(getNumOperands() == 1 + IdxList.size() && "NumOperands not initialized?"); Op<0>() = Ptr; llvm::copy(IdxList, op_begin() + 1); setName(Name); } GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) : Instruction(GEPI.getType(), GetElementPtr, OperandTraits::op_end(this) - GEPI.getNumOperands(), GEPI.getNumOperands()), SourceElementType(GEPI.SourceElementType), ResultElementType(GEPI.ResultElementType) { std::copy(GEPI.op_begin(), GEPI.op_end(), op_begin()); SubclassOptionalData = GEPI.SubclassOptionalData; } /// getIndexedType - Returns the type of the element that would be accessed with /// a gep instruction with the specified parameters. /// /// The Idxs pointer should point to a continuous piece of memory containing the /// indices, either as Value* or uint64_t. /// /// A null type is returned if the indices are invalid for the specified /// pointer type. /// template static Type *getIndexedTypeInternal(Type *Agg, ArrayRef IdxList) { // Handle the special case of the empty set index set, which is always valid. if (IdxList.empty()) return Agg; // If there is at least one index, the top level type must be sized, otherwise // it cannot be 'stepped over'. if (!Agg->isSized()) return nullptr; unsigned CurIdx = 1; for (; CurIdx != IdxList.size(); ++CurIdx) { CompositeType *CT = dyn_cast(Agg); if (!CT || CT->isPointerTy()) return nullptr; IndexTy Index = IdxList[CurIdx]; if (!CT->indexValid(Index)) return nullptr; Agg = CT->getTypeAtIndex(Index); } return CurIdx == IdxList.size() ? Agg : nullptr; } Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef IdxList) { return getIndexedTypeInternal(Ty, IdxList); } Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef IdxList) { return getIndexedTypeInternal(Ty, IdxList); } Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef IdxList) { return getIndexedTypeInternal(Ty, IdxList); } /// hasAllZeroIndices - Return true if all of the indices of this GEP are /// zeros. If so, the result pointer and the first operand have the same /// value, just potentially different types. bool GetElementPtrInst::hasAllZeroIndices() const { for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { if (ConstantInt *CI = dyn_cast(getOperand(i))) { if (!CI->isZero()) return false; } else { return false; } } return true; } /// hasAllConstantIndices - Return true if all of the indices of this GEP are /// constant integers. If so, the result pointer and the first operand have /// a constant offset between them. bool GetElementPtrInst::hasAllConstantIndices() const { for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { if (!isa(getOperand(i))) return false; } return true; } void GetElementPtrInst::setIsInBounds(bool B) { cast(this)->setIsInBounds(B); } bool GetElementPtrInst::isInBounds() const { return cast(this)->isInBounds(); } bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { // Delegate to the generic GEPOperator implementation. return cast(this)->accumulateConstantOffset(DL, Offset); } //===----------------------------------------------------------------------===// // ExtractElementInst Implementation //===----------------------------------------------------------------------===// ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, const Twine &Name, Instruction *InsertBef) : Instruction(cast(Val->getType())->getElementType(), ExtractElement, OperandTraits::op_begin(this), 2, InsertBef) { assert(isValidOperands(Val, Index) && "Invalid extractelement instruction operands!"); Op<0>() = Val; Op<1>() = Index; setName(Name); } ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, const Twine &Name, BasicBlock *InsertAE) : Instruction(cast(Val->getType())->getElementType(), ExtractElement, OperandTraits::op_begin(this), 2, InsertAE) { assert(isValidOperands(Val, Index) && "Invalid extractelement instruction operands!"); Op<0>() = Val; Op<1>() = Index; setName(Name); } bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) { if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy()) return false; return true; } //===----------------------------------------------------------------------===// // InsertElementInst Implementation //===----------------------------------------------------------------------===// InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, const Twine &Name, Instruction *InsertBef) : Instruction(Vec->getType(), InsertElement, OperandTraits::op_begin(this), 3, InsertBef) { assert(isValidOperands(Vec, Elt, Index) && "Invalid insertelement instruction operands!"); Op<0>() = Vec; Op<1>() = Elt; Op<2>() = Index; setName(Name); } InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, const Twine &Name, BasicBlock *InsertAE) : Instruction(Vec->getType(), InsertElement, OperandTraits::op_begin(this), 3, InsertAE) { assert(isValidOperands(Vec, Elt, Index) && "Invalid insertelement instruction operands!"); Op<0>() = Vec; Op<1>() = Elt; Op<2>() = Index; setName(Name); } bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, const Value *Index) { if (!Vec->getType()->isVectorTy()) return false; // First operand of insertelement must be vector type. if (Elt->getType() != cast(Vec->getType())->getElementType()) return false;// Second operand of insertelement must be vector element type. if (!Index->getType()->isIntegerTy()) return false; // Third operand of insertelement must be i32. return true; } //===----------------------------------------------------------------------===// // ShuffleVectorInst Implementation //===----------------------------------------------------------------------===// ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &Name, Instruction *InsertBefore) : Instruction(VectorType::get(cast(V1->getType())->getElementType(), cast(Mask->getType())->getNumElements()), ShuffleVector, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); Op<0>() = V1; Op<1>() = V2; Op<2>() = Mask; setName(Name); } ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(VectorType::get(cast(V1->getType())->getElementType(), cast(Mask->getType())->getNumElements()), ShuffleVector, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); Op<0>() = V1; Op<1>() = V2; Op<2>() = Mask; setName(Name); } bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, const Value *Mask) { // V1 and V2 must be vectors of the same type. if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType()) return false; // Mask must be vector of i32. auto *MaskTy = dyn_cast(Mask->getType()); if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32)) return false; // Check to see if Mask is valid. if (isa(Mask) || isa(Mask)) return true; if (const auto *MV = dyn_cast(Mask)) { unsigned V1Size = cast(V1->getType())->getNumElements(); for (Value *Op : MV->operands()) { if (auto *CI = dyn_cast(Op)) { if (CI->uge(V1Size*2)) return false; } else if (!isa(Op)) { return false; } } return true; } if (const auto *CDS = dyn_cast(Mask)) { unsigned V1Size = cast(V1->getType())->getNumElements(); for (unsigned i = 0, e = MaskTy->getNumElements(); i != e; ++i) if (CDS->getElementAsInteger(i) >= V1Size*2) return false; return true; } // The bitcode reader can create a place holder for a forward reference // used as the shuffle mask. When this occurs, the shuffle mask will // fall into this case and fail. To avoid this error, do this bit of // ugliness to allow such a mask pass. if (const auto *CE = dyn_cast(Mask)) if (CE->getOpcode() == Instruction::UserOp1) return true; return false; } int ShuffleVectorInst::getMaskValue(const Constant *Mask, unsigned i) { assert(i < Mask->getType()->getVectorNumElements() && "Index out of range"); if (auto *CDS = dyn_cast(Mask)) return CDS->getElementAsInteger(i); Constant *C = Mask->getAggregateElement(i); if (isa(C)) return -1; return cast(C)->getZExtValue(); } void ShuffleVectorInst::getShuffleMask(const Constant *Mask, SmallVectorImpl &Result) { unsigned NumElts = Mask->getType()->getVectorNumElements(); if (auto *CDS = dyn_cast(Mask)) { for (unsigned i = 0; i != NumElts; ++i) Result.push_back(CDS->getElementAsInteger(i)); return; } for (unsigned i = 0; i != NumElts; ++i) { Constant *C = Mask->getAggregateElement(i); Result.push_back(isa(C) ? -1 : cast(C)->getZExtValue()); } } static bool isSingleSourceMaskImpl(ArrayRef Mask, int NumOpElts) { assert(!Mask.empty() && "Shuffle mask must contain elements"); bool UsesLHS = false; bool UsesRHS = false; for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) { if (Mask[i] == -1) continue; assert(Mask[i] >= 0 && Mask[i] < (NumOpElts * 2) && "Out-of-bounds shuffle mask element"); UsesLHS |= (Mask[i] < NumOpElts); UsesRHS |= (Mask[i] >= NumOpElts); if (UsesLHS && UsesRHS) return false; } assert((UsesLHS ^ UsesRHS) && "Should have selected from exactly 1 source"); return true; } bool ShuffleVectorInst::isSingleSourceMask(ArrayRef Mask) { // We don't have vector operand size information, so assume operands are the // same size as the mask. return isSingleSourceMaskImpl(Mask, Mask.size()); } static bool isIdentityMaskImpl(ArrayRef Mask, int NumOpElts) { if (!isSingleSourceMaskImpl(Mask, NumOpElts)) return false; for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) { if (Mask[i] == -1) continue; if (Mask[i] != i && Mask[i] != (NumOpElts + i)) return false; } return true; } bool ShuffleVectorInst::isIdentityMask(ArrayRef Mask) { // We don't have vector operand size information, so assume operands are the // same size as the mask. return isIdentityMaskImpl(Mask, Mask.size()); } bool ShuffleVectorInst::isReverseMask(ArrayRef Mask) { if (!isSingleSourceMask(Mask)) return false; for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) { if (Mask[i] == -1) continue; if (Mask[i] != (NumElts - 1 - i) && Mask[i] != (NumElts + NumElts - 1 - i)) return false; } return true; } bool ShuffleVectorInst::isZeroEltSplatMask(ArrayRef Mask) { if (!isSingleSourceMask(Mask)) return false; for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) { if (Mask[i] == -1) continue; if (Mask[i] != 0 && Mask[i] != NumElts) return false; } return true; } bool ShuffleVectorInst::isSelectMask(ArrayRef Mask) { // Select is differentiated from identity. It requires using both sources. if (isSingleSourceMask(Mask)) return false; for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) { if (Mask[i] == -1) continue; if (Mask[i] != i && Mask[i] != (NumElts + i)) return false; } return true; } bool ShuffleVectorInst::isTransposeMask(ArrayRef Mask) { // Example masks that will return true: // v1 = // v2 = // trn1 = shufflevector v1, v2 <0, 4, 2, 6> = // trn2 = shufflevector v1, v2 <1, 5, 3, 7> = // 1. The number of elements in the mask must be a power-of-2 and at least 2. int NumElts = Mask.size(); if (NumElts < 2 || !isPowerOf2_32(NumElts)) return false; // 2. The first element of the mask must be either a 0 or a 1. if (Mask[0] != 0 && Mask[0] != 1) return false; // 3. The difference between the first 2 elements must be equal to the // number of elements in the mask. if ((Mask[1] - Mask[0]) != NumElts) return false; // 4. The difference between consecutive even-numbered and odd-numbered // elements must be equal to 2. for (int i = 2; i < NumElts; ++i) { int MaskEltVal = Mask[i]; if (MaskEltVal == -1) return false; int MaskEltPrevVal = Mask[i - 2]; if (MaskEltVal - MaskEltPrevVal != 2) return false; } return true; } bool ShuffleVectorInst::isExtractSubvectorMask(ArrayRef Mask, int NumSrcElts, int &Index) { // Must extract from a single source. if (!isSingleSourceMaskImpl(Mask, NumSrcElts)) return false; // Must be smaller (else this is an Identity shuffle). if (NumSrcElts <= (int)Mask.size()) return false; // Find start of extraction, accounting that we may start with an UNDEF. int SubIndex = -1; for (int i = 0, e = Mask.size(); i != e; ++i) { int M = Mask[i]; if (M < 0) continue; int Offset = (M % NumSrcElts) - i; if (0 <= SubIndex && SubIndex != Offset) return false; SubIndex = Offset; } if (0 <= SubIndex) { Index = SubIndex; return true; } return false; } bool ShuffleVectorInst::isIdentityWithPadding() const { int NumOpElts = Op<0>()->getType()->getVectorNumElements(); int NumMaskElts = getType()->getVectorNumElements(); if (NumMaskElts <= NumOpElts) return false; // The first part of the mask must choose elements from exactly 1 source op. SmallVector Mask = getShuffleMask(); if (!isIdentityMaskImpl(Mask, NumOpElts)) return false; // All extending must be with undef elements. for (int i = NumOpElts; i < NumMaskElts; ++i) if (Mask[i] != -1) return false; return true; } bool ShuffleVectorInst::isIdentityWithExtract() const { int NumOpElts = Op<0>()->getType()->getVectorNumElements(); int NumMaskElts = getType()->getVectorNumElements(); if (NumMaskElts >= NumOpElts) return false; return isIdentityMaskImpl(getShuffleMask(), NumOpElts); } bool ShuffleVectorInst::isConcat() const { // Vector concatenation is differentiated from identity with padding. if (isa(Op<0>()) || isa(Op<1>())) return false; int NumOpElts = Op<0>()->getType()->getVectorNumElements(); int NumMaskElts = getType()->getVectorNumElements(); if (NumMaskElts != NumOpElts * 2) return false; // Use the mask length rather than the operands' vector lengths here. We // already know that the shuffle returns a vector twice as long as the inputs, // and neither of the inputs are undef vectors. If the mask picks consecutive // elements from both inputs, then this is a concatenation of the inputs. return isIdentityMaskImpl(getShuffleMask(), NumMaskElts); } //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef Idxs, const Twine &Name) { assert(getNumOperands() == 2 && "NumOperands not initialized?"); // There's no fundamental reason why we require at least one index // (other than weirdness with &*IdxBegin being invalid; see // getelementptr's init routine for example). But there's no // present need to support it. assert(!Idxs.empty() && "InsertValueInst must have at least one index"); assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == Val->getType() && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; Indices.append(Idxs.begin(), Idxs.end()); setName(Name); } InsertValueInst::InsertValueInst(const InsertValueInst &IVI) : Instruction(IVI.getType(), InsertValue, OperandTraits::op_begin(this), 2), Indices(IVI.Indices) { Op<0>() = IVI.getOperand(0); Op<1>() = IVI.getOperand(1); SubclassOptionalData = IVI.SubclassOptionalData; } //===----------------------------------------------------------------------===// // ExtractValueInst Class //===----------------------------------------------------------------------===// void ExtractValueInst::init(ArrayRef Idxs, const Twine &Name) { assert(getNumOperands() == 1 && "NumOperands not initialized?"); // There's no fundamental reason why we require at least one index. // But there's no present need to support it. assert(!Idxs.empty() && "ExtractValueInst must have at least one index"); Indices.append(Idxs.begin(), Idxs.end()); setName(Name); } ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)), Indices(EVI.Indices) { SubclassOptionalData = EVI.SubclassOptionalData; } // getIndexedType - Returns the type of the element that would be extracted // with an extractvalue instruction with the specified parameters. // // A null type is returned if the indices are invalid for the specified // pointer type. // Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef Idxs) { for (unsigned Index : Idxs) { // We can't use CompositeType::indexValid(Index) here. // indexValid() always returns true for arrays because getelementptr allows // out-of-bounds indices. Since we don't allow those for extractvalue and // insertvalue we need to check array indexing manually. // Since the only other types we can index into are struct types it's just // as easy to check those manually as well. if (ArrayType *AT = dyn_cast(Agg)) { if (Index >= AT->getNumElements()) return nullptr; } else if (StructType *ST = dyn_cast(Agg)) { if (Index >= ST->getNumElements()) return nullptr; } else { // Not a valid type to index into. return nullptr; } Agg = cast(Agg)->getTypeAtIndex(Index); } return const_cast(Agg); } //===----------------------------------------------------------------------===// // UnaryOperator Class //===----------------------------------------------------------------------===// UnaryOperator::UnaryOperator(UnaryOps iType, Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) : UnaryInstruction(Ty, iType, S, InsertBefore) { Op<0>() = S; setName(Name); AssertOK(); } UnaryOperator::UnaryOperator(UnaryOps iType, Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, iType, S, InsertAtEnd) { Op<0>() = S; setName(Name); AssertOK(); } UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S, const Twine &Name, Instruction *InsertBefore) { return new UnaryOperator(Op, S, S->getType(), Name, InsertBefore); } UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S, const Twine &Name, BasicBlock *InsertAtEnd) { UnaryOperator *Res = Create(Op, S, Name); InsertAtEnd->getInstList().push_back(Res); return Res; } void UnaryOperator::AssertOK() { Value *LHS = getOperand(0); (void)LHS; // Silence warnings. #ifndef NDEBUG switch (getOpcode()) { case FNeg: assert(getType() == LHS->getType() && "Unary operation should return same type as operand!"); assert(getType()->isFPOrFPVectorTy() && "Tried to create a floating-point operation on a " "non-floating-point type!"); break; default: llvm_unreachable("Invalid opcode provided"); } #endif } //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, Instruction *InsertBefore) : Instruction(Ty, iType, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { Op<0>() = S1; Op<1>() = S2; setName(Name); AssertOK(); } BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { Op<0>() = S1; Op<1>() = S2; setName(Name); AssertOK(); } void BinaryOperator::AssertOK() { Value *LHS = getOperand(0), *RHS = getOperand(1); (void)LHS; (void)RHS; // Silence warnings. assert(LHS->getType() == RHS->getType() && "Binary operator operand types must match!"); #ifndef NDEBUG switch (getOpcode()) { case Add: case Sub: case Mul: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isIntOrIntVectorTy() && "Tried to create an integer operation on a non-integer type!"); break; case FAdd: case FSub: case FMul: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isFPOrFPVectorTy() && "Tried to create a floating-point operation on a " "non-floating-point type!"); break; case UDiv: case SDiv: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isIntOrIntVectorTy() && "Incorrect operand type (not integer) for S/UDIV"); break; case FDiv: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isFPOrFPVectorTy() && "Incorrect operand type (not floating point) for FDIV"); break; case URem: case SRem: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isIntOrIntVectorTy() && "Incorrect operand type (not integer) for S/UREM"); break; case FRem: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert(getType()->isFPOrFPVectorTy() && "Incorrect operand type (not floating point) for FREM"); break; case Shl: case LShr: case AShr: assert(getType() == LHS->getType() && "Shift operation should return same type as operands!"); assert(getType()->isIntOrIntVectorTy() && "Tried to create a shift operation on a non-integral type!"); break; case And: case Or: case Xor: assert(getType() == LHS->getType() && "Logical operation should return same type as operands!"); assert(getType()->isIntOrIntVectorTy() && "Tried to create a logical operation on a non-integral type!"); break; default: llvm_unreachable("Invalid opcode provided"); } #endif } BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore) { assert(S1->getType() == S2->getType() && "Cannot create binary operator with two operands of differing type!"); return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd) { BinaryOperator *Res = Create(Op, S1, S2, Name); InsertAtEnd->getInstList().push_back(Res); return Res; } BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::Sub, zero, Op, Op->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::Sub, zero, Op, Op->getType(), Name, InsertAtEnd); } BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return BinaryOperator::CreateNSWSub(zero, Op, Name, InsertAtEnd); } BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return BinaryOperator::CreateNUWSub(zero, Op, Name, InsertAtEnd); } BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertAtEnd); } BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, Instruction *InsertBefore) { Constant *C = Constant::getAllOnesValue(Op->getType()); return new BinaryOperator(Instruction::Xor, Op, C, Op->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Constant *AllOnes = Constant::getAllOnesValue(Op->getType()); return new BinaryOperator(Instruction::Xor, Op, AllOnes, Op->getType(), Name, InsertAtEnd); } // Exchange the two operands to this instruction. This instruction is safe to // use on any binary instruction and does not modify the semantics of the // instruction. If the instruction is order-dependent (SetLT f.e.), the opcode // is changed. bool BinaryOperator::swapOperands() { if (!isCommutative()) return true; // Can't commute operands Op<0>().swap(Op<1>()); return false; } //===----------------------------------------------------------------------===// // FPMathOperator Class //===----------------------------------------------------------------------===// float FPMathOperator::getFPAccuracy() const { const MDNode *MD = cast(this)->getMetadata(LLVMContext::MD_fpmath); if (!MD) return 0.0; ConstantFP *Accuracy = mdconst::extract(MD->getOperand(0)); return Accuracy->getValueAPF().convertToFloat(); } //===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// // Just determine if this cast only deals with integral->integral conversion. bool CastInst::isIntegerCast() const { switch (getOpcode()) { default: return false; case Instruction::ZExt: case Instruction::SExt: case Instruction::Trunc: return true; case Instruction::BitCast: return getOperand(0)->getType()->isIntegerTy() && getType()->isIntegerTy(); } } bool CastInst::isLosslessCast() const { // Only BitCast can be lossless, exit fast if we're not BitCast if (getOpcode() != Instruction::BitCast) return false; // Identity cast is always lossless Type *SrcTy = getOperand(0)->getType(); Type *DstTy = getType(); if (SrcTy == DstTy) return true; // Pointer to pointer is always lossless. if (SrcTy->isPointerTy()) return DstTy->isPointerTy(); return false; // Other types have no identity values } /// This function determines if the CastInst does not require any bits to be /// changed in order to effect the cast. Essentially, it identifies cases where /// no code gen is necessary for the cast, hence the name no-op cast. For /// example, the following are all no-op casts: /// # bitcast i32* %x to i8* /// # bitcast <2 x i32> %x to <4 x i16> /// # ptrtoint i32* %x to i32 ; on 32-bit plaforms only /// Determine if the described cast is a no-op. bool CastInst::isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DestTy, const DataLayout &DL) { switch (Opcode) { default: llvm_unreachable("Invalid CastOp"); case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: case Instruction::AddrSpaceCast: // TODO: Target informations may give a more accurate answer here. return false; case Instruction::BitCast: return true; // BitCast never modifies bits. case Instruction::PtrToInt: return DL.getIntPtrType(SrcTy)->getScalarSizeInBits() == DestTy->getScalarSizeInBits(); case Instruction::IntToPtr: return DL.getIntPtrType(DestTy)->getScalarSizeInBits() == SrcTy->getScalarSizeInBits(); } } bool CastInst::isNoopCast(const DataLayout &DL) const { return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), DL); } /// This function determines if a pair of casts can be eliminated and what /// opcode should be used in the elimination. This assumes that there are two /// instructions like this: /// * %F = firstOpcode SrcTy %x to MidTy /// * %S = secondOpcode MidTy %F to DstTy /// The function returns a resultOpcode so these two casts can be replaced with: /// * %Replacement = resultOpcode %SrcTy %x to DstTy /// If no such cast is permitted, the function returns 0. unsigned CastInst::isEliminableCastPair( Instruction::CastOps firstOp, Instruction::CastOps secondOp, Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, Type *DstIntPtrTy) { // Define the 144 possibilities for these two cast instructions. The values // in this matrix determine what to do in a given situation and select the // case in the switch below. The rows correspond to firstOp, the columns // correspond to secondOp. In looking at the table below, keep in mind // the following cast properties: // // Size Compare Source Destination // Operator Src ? Size Type Sign Type Sign // -------- ------------ ------------------- --------------------- // TRUNC > Integer Any Integral Any // ZEXT < Integral Unsigned Integer Any // SEXT < Integral Signed Integer Any // FPTOUI n/a FloatPt n/a Integral Unsigned // FPTOSI n/a FloatPt n/a Integral Signed // UITOFP n/a Integral Unsigned FloatPt n/a // SITOFP n/a Integral Signed FloatPt n/a // FPTRUNC > FloatPt n/a FloatPt n/a // FPEXT < FloatPt n/a FloatPt n/a // PTRTOINT n/a Pointer n/a Integral Unsigned // INTTOPTR n/a Integral Unsigned Pointer n/a // BITCAST = FirstClass n/a FirstClass n/a // ADDRSPCST n/a Pointer n/a Pointer n/a // // NOTE: some transforms are safe, but we consider them to be non-profitable. // For example, we could merge "fptoui double to i32" + "zext i32 to i64", // into "fptoui double to i64", but this loses information about the range // of the produced value (we no longer know the top-part is all zeros). // Further this conversion is often much more expensive for typical hardware, // and causes issues when building libgcc. We disallow fptosi+sext for the // same reason. const unsigned numCastOps = Instruction::CastOpsEnd - Instruction::CastOpsBegin; static const uint8_t CastResults[numCastOps][numCastOps] = { // T F F U S F F P I B A -+ // R Z S P P I I T P 2 N T S | // U E E 2 2 2 2 R E I T C C +- secondOp // N X X U S F F N X N 2 V V | // C T T I I P P C T T P T T -+ { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+ { 8, 1, 9,99,99, 2,17,99,99,99, 2, 3, 0}, // ZExt | { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt | { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI | { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI | { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP | { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // FPTrunc | { 99,99,99, 2, 2,99,99, 8, 2,99,99, 4, 0}, // FPExt | { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt | { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr | { 5, 5, 5, 6, 6, 5, 5, 6, 6,16, 5, 1,14}, // BitCast | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+ }; // TODO: This logic could be encoded into the table above and handled in the // switch below. // If either of the casts are a bitcast from scalar to vector, disallow the // merging. However, any pair of bitcasts are allowed. bool IsFirstBitcast = (firstOp == Instruction::BitCast); bool IsSecondBitcast = (secondOp == Instruction::BitCast); bool AreBothBitcasts = IsFirstBitcast && IsSecondBitcast; // Check if any of the casts convert scalars <-> vectors. if ((IsFirstBitcast && isa(SrcTy) != isa(MidTy)) || (IsSecondBitcast && isa(MidTy) != isa(DstTy))) if (!AreBothBitcasts) return 0; int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin] [secondOp-Instruction::CastOpsBegin]; switch (ElimCase) { case 0: // Categorically disallowed. return 0; case 1: // Allowed, use first cast's opcode. return firstOp; case 2: // Allowed, use second cast's opcode. return secondOp; case 3: // No-op cast in second op implies firstOp as long as the DestTy // is integer and we are not converting between a vector and a // non-vector type. if (!SrcTy->isVectorTy() && DstTy->isIntegerTy()) return firstOp; return 0; case 4: // No-op cast in second op implies firstOp as long as the DestTy // is floating point. if (DstTy->isFloatingPointTy()) return firstOp; return 0; case 5: // No-op cast in first op implies secondOp as long as the SrcTy // is an integer. if (SrcTy->isIntegerTy()) return secondOp; return 0; case 6: // No-op cast in first op implies secondOp as long as the SrcTy // is a floating point. if (SrcTy->isFloatingPointTy()) return secondOp; return 0; case 7: { // Cannot simplify if address spaces are different! if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) return 0; unsigned MidSize = MidTy->getScalarSizeInBits(); // We can still fold this without knowing the actual sizes as long we // know that the intermediate pointer is the largest possible // pointer size. // FIXME: Is this always true? if (MidSize == 64) return Instruction::BitCast; // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size. if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy) return 0; unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits(); if (MidSize >= PtrSize) return Instruction::BitCast; return 0; } case 8: { // ext, trunc -> bitcast, if the SrcTy and DstTy are same size // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy) // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy) unsigned SrcSize = SrcTy->getScalarSizeInBits(); unsigned DstSize = DstTy->getScalarSizeInBits(); if (SrcSize == DstSize) return Instruction::BitCast; else if (SrcSize < DstSize) return firstOp; return secondOp; } case 9: // zext, sext -> zext, because sext can't sign extend after zext return Instruction::ZExt; case 11: { // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize if (!MidIntPtrTy) return 0; unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits(); unsigned SrcSize = SrcTy->getScalarSizeInBits(); unsigned DstSize = DstTy->getScalarSizeInBits(); if (SrcSize <= PtrSize && SrcSize == DstSize) return Instruction::BitCast; return 0; } case 12: // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) return Instruction::AddrSpaceCast; return Instruction::BitCast; case 13: // FIXME: this state can be merged with (1), but the following assert // is useful to check the correcteness of the sequence due to semantic // change of bitcast. assert( SrcTy->isPtrOrPtrVectorTy() && MidTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() && MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && "Illegal addrspacecast, bitcast sequence!"); // Allowed, use first cast's opcode return firstOp; case 14: // bitcast, addrspacecast -> addrspacecast if the element type of // bitcast's source is the same as that of addrspacecast's destination. if (SrcTy->getScalarType()->getPointerElementType() == DstTy->getScalarType()->getPointerElementType()) return Instruction::AddrSpaceCast; return 0; case 15: // FIXME: this state can be merged with (1), but the following assert // is useful to check the correcteness of the sequence due to semantic // change of bitcast. assert( SrcTy->isIntOrIntVectorTy() && MidTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() && "Illegal inttoptr, bitcast sequence!"); // Allowed, use first cast's opcode return firstOp; case 16: // FIXME: this state can be merged with (2), but the following assert // is useful to check the correcteness of the sequence due to semantic // change of bitcast. assert( SrcTy->isPtrOrPtrVectorTy() && MidTy->isPtrOrPtrVectorTy() && DstTy->isIntOrIntVectorTy() && SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() && "Illegal bitcast, ptrtoint sequence!"); // Allowed, use second cast's opcode return secondOp; case 17: // (sitofp (zext x)) -> (uitofp x) return Instruction::UIToFP; case 99: // Cast combination can't happen (error in input). This is for all cases // where the MidTy is not the same for the two cast instructions. llvm_unreachable("Invalid Cast Combination"); default: llvm_unreachable("Error in CastResults table!!!"); } } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); case SExt: return new SExtInst (S, Ty, Name, InsertBefore); case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertBefore); default: llvm_unreachable("Invalid opcode provided"); } } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { assert(castIsValid(op, S, Ty) && "Invalid cast!"); // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); case AddrSpaceCast: return new AddrSpaceCastInst (S, Ty, Name, InsertAtEnd); default: llvm_unreachable("Invalid opcode provided"); } } CastInst *CastInst::CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::ZExt, S, Ty, Name, InsertBefore); } CastInst *CastInst::CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd); } CastInst *CastInst::CreateSExtOrBitCast(Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::SExt, S, Ty, Name, InsertBefore); } CastInst *CastInst::CreateSExtOrBitCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd); } CastInst *CastInst::CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); return Create(Instruction::Trunc, S, Ty, Name, InsertBefore); } CastInst *CastInst::CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd); } CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && "Invalid cast"); assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast"); assert((!Ty->isVectorTy() || Ty->getVectorNumElements() == S->getType()->getVectorNumElements()) && "Invalid cast"); if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd); return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertAtEnd); } /// Create a BitCast or a PtrToInt cast instruction CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) && "Invalid cast"); assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast"); assert((!Ty->isVectorTy() || Ty->getVectorNumElements() == S->getType()->getVectorNumElements()) && "Invalid cast"); if (Ty->isIntOrIntVectorTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore); } CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertAtEnd); return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); } CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast"); assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast"); if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace()) return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore); return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } CastInst *CastInst::CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore) { if (S->getType()->isPointerTy() && Ty->isIntegerTy()) return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore); if (S->getType()->isIntegerTy() && Ty->isPointerTy()) return Create(Instruction::IntToPtr, S, Ty, Name, InsertBefore); return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); } CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned, const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid integer cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::Trunc : (isSigned ? Instruction::SExt : Instruction::ZExt))); return Create(opcode, C, Ty, Name, InsertBefore); } CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned, const Twine &Name, BasicBlock *InsertAtEnd) { assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::Trunc : (isSigned ? Instruction::SExt : Instruction::ZExt))); return Create(opcode, C, Ty, Name, InsertAtEnd); } CastInst *CastInst::CreateFPCast(Value *C, Type *Ty, const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); return Create(opcode, C, Ty, Name, InsertBefore); } CastInst *CastInst::CreateFPCast(Value *C, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) { assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); unsigned DstBits = Ty->getScalarSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt)); return Create(opcode, C, Ty, Name, InsertAtEnd); } // Check whether it is valid to call getCastOpcode for these types. // This routine must be kept in sync with getCastOpcode. bool CastInst::isCastable(Type *SrcTy, Type *DestTy) { if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType()) return false; if (SrcTy == DestTy) return true; if (VectorType *SrcVecTy = dyn_cast(SrcTy)) if (VectorType *DestVecTy = dyn_cast(DestTy)) if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { // An element by element cast. Valid if casting the elements is valid. SrcTy = SrcVecTy->getElementType(); DestTy = DestVecTy->getElementType(); } // Get the bit sizes, we'll need these unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr // Run through the possibilities ... if (DestTy->isIntegerTy()) { // Casting to integral if (SrcTy->isIntegerTy()) // Casting from integral return true; if (SrcTy->isFloatingPointTy()) // Casting from floating pt return true; if (SrcTy->isVectorTy()) // Casting from vector return DestBits == SrcBits; // Casting from something else return SrcTy->isPointerTy(); } if (DestTy->isFloatingPointTy()) { // Casting to floating pt if (SrcTy->isIntegerTy()) // Casting from integral return true; if (SrcTy->isFloatingPointTy()) // Casting from floating pt return true; if (SrcTy->isVectorTy()) // Casting from vector return DestBits == SrcBits; // Casting from something else return false; } if (DestTy->isVectorTy()) // Casting to vector return DestBits == SrcBits; if (DestTy->isPointerTy()) { // Casting to pointer if (SrcTy->isPointerTy()) // Casting from pointer return true; return SrcTy->isIntegerTy(); // Casting from integral } if (DestTy->isX86_MMXTy()) { if (SrcTy->isVectorTy()) return DestBits == SrcBits; // 64-bit vector to MMX return false; } // Casting to something else return false; } bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) { if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType()) return false; if (SrcTy == DestTy) return true; if (VectorType *SrcVecTy = dyn_cast(SrcTy)) { if (VectorType *DestVecTy = dyn_cast(DestTy)) { if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { // An element by element cast. Valid if casting the elements is valid. SrcTy = SrcVecTy->getElementType(); DestTy = DestVecTy->getElementType(); } } } if (PointerType *DestPtrTy = dyn_cast(DestTy)) { if (PointerType *SrcPtrTy = dyn_cast(SrcTy)) { return SrcPtrTy->getAddressSpace() == DestPtrTy->getAddressSpace(); } } unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr // Could still have vectors of pointers if the number of elements doesn't // match if (SrcBits == 0 || DestBits == 0) return false; if (SrcBits != DestBits) return false; if (DestTy->isX86_MMXTy() || SrcTy->isX86_MMXTy()) return false; return true; } bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL) { // ptrtoint and inttoptr are not allowed on non-integral pointers if (auto *PtrTy = dyn_cast(SrcTy)) if (auto *IntTy = dyn_cast(DestTy)) return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) && !DL.isNonIntegralPointerType(PtrTy)); if (auto *PtrTy = dyn_cast(DestTy)) if (auto *IntTy = dyn_cast(SrcTy)) return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) && !DL.isNonIntegralPointerType(PtrTy)); return isBitCastable(SrcTy, DestTy); } // Provide a way to get a "cast" where the cast opcode is inferred from the // types and size of the operand. This, basically, is a parallel of the // logic in the castIsValid function below. This axiom should hold: // castIsValid( getCastOpcode(Val, Ty), Val, Ty) // should not assert in castIsValid. In other words, this produces a "correct" // casting opcode for the arguments passed to it. // This routine must be kept in sync with isCastable. Instruction::CastOps CastInst::getCastOpcode( const Value *Src, bool SrcIsSigned, Type *DestTy, bool DestIsSigned) { Type *SrcTy = Src->getType(); assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() && "Only first class types are castable!"); if (SrcTy == DestTy) return BitCast; // FIXME: Check address space sizes here if (VectorType *SrcVecTy = dyn_cast(SrcTy)) if (VectorType *DestVecTy = dyn_cast(DestTy)) if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) { // An element by element cast. Find the appropriate opcode based on the // element types. SrcTy = SrcVecTy->getElementType(); DestTy = DestVecTy->getElementType(); } // Get the bit sizes, we'll need these unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr // Run through the possibilities ... if (DestTy->isIntegerTy()) { // Casting to integral if (SrcTy->isIntegerTy()) { // Casting from integral if (DestBits < SrcBits) return Trunc; // int -> smaller int else if (DestBits > SrcBits) { // its an extension if (SrcIsSigned) return SExt; // signed -> SEXT else return ZExt; // unsigned -> ZEXT } else { return BitCast; // Same size, No-op cast } } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt if (DestIsSigned) return FPToSI; // FP -> sint else return FPToUI; // FP -> uint } else if (SrcTy->isVectorTy()) { assert(DestBits == SrcBits && "Casting vector to integer of different width"); return BitCast; // Same size, no-op cast } else { assert(SrcTy->isPointerTy() && "Casting from a value that is not first-class type"); return PtrToInt; // ptr -> int } } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt if (SrcTy->isIntegerTy()) { // Casting from integral if (SrcIsSigned) return SIToFP; // sint -> FP else return UIToFP; // uint -> FP } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt if (DestBits < SrcBits) { return FPTrunc; // FP -> smaller FP } else if (DestBits > SrcBits) { return FPExt; // FP -> larger FP } else { return BitCast; // same size, no-op cast } } else if (SrcTy->isVectorTy()) { assert(DestBits == SrcBits && "Casting vector to floating point of different width"); return BitCast; // same size, no-op cast } llvm_unreachable("Casting pointer or non-first class to float"); } else if (DestTy->isVectorTy()) { assert(DestBits == SrcBits && "Illegal cast to vector (wrong type or size)"); return BitCast; } else if (DestTy->isPointerTy()) { if (SrcTy->isPointerTy()) { if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace()) return AddrSpaceCast; return BitCast; // ptr -> ptr } else if (SrcTy->isIntegerTy()) { return IntToPtr; // int -> ptr } llvm_unreachable("Casting pointer to other than pointer or int"); } else if (DestTy->isX86_MMXTy()) { if (SrcTy->isVectorTy()) { assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); return BitCast; // 64-bit vector to MMX } llvm_unreachable("Illegal cast to X86_MMX"); } llvm_unreachable("Casting to type that is not first-class"); } //===----------------------------------------------------------------------===// // CastInst SubClass Constructors //===----------------------------------------------------------------------===// /// Check that the construction parameters for a CastInst are correct. This /// could be broken out into the separate constructors but it is useful to have /// it in one place and to eliminate the redundant code for getting the sizes /// of the types involved. bool CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) { // Check for type sanity on the arguments Type *SrcTy = S->getType(); if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() || SrcTy->isAggregateType() || DstTy->isAggregateType()) return false; // Get the size of the types in bits, we'll need this later unsigned SrcBitSize = SrcTy->getScalarSizeInBits(); unsigned DstBitSize = DstTy->getScalarSizeInBits(); // If these are vector types, get the lengths of the vectors (using zero for // scalar types means that checking that vector lengths match also checks that // scalars are not being converted to vectors or vectors to scalars). unsigned SrcLength = SrcTy->isVectorTy() ? cast(SrcTy)->getNumElements() : 0; unsigned DstLength = DstTy->isVectorTy() ? cast(DstTy)->getNumElements() : 0; // Switch on the opcode provided switch (op) { default: return false; // This is an input error case Instruction::Trunc: return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::ZExt: return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::SExt: return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() && SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::FPTrunc: return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && SrcLength == DstLength && SrcBitSize > DstBitSize; case Instruction::FPExt: return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() && SrcLength == DstLength && SrcBitSize < DstBitSize; case Instruction::UIToFP: case Instruction::SIToFP: return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() && SrcLength == DstLength; case Instruction::FPToUI: case Instruction::FPToSI: return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && SrcLength == DstLength; case Instruction::PtrToInt: if (isa(SrcTy) != isa(DstTy)) return false; if (VectorType *VT = dyn_cast(SrcTy)) if (VT->getNumElements() != cast(DstTy)->getNumElements()) return false; return SrcTy->isPtrOrPtrVectorTy() && DstTy->isIntOrIntVectorTy(); case Instruction::IntToPtr: if (isa(SrcTy) != isa(DstTy)) return false; if (VectorType *VT = dyn_cast(SrcTy)) if (VT->getNumElements() != cast(DstTy)->getNumElements()) return false; return SrcTy->isIntOrIntVectorTy() && DstTy->isPtrOrPtrVectorTy(); case Instruction::BitCast: { PointerType *SrcPtrTy = dyn_cast(SrcTy->getScalarType()); PointerType *DstPtrTy = dyn_cast(DstTy->getScalarType()); // BitCast implies a no-op cast of type only. No bits change. // However, you can't cast pointers to anything but pointers. if (!SrcPtrTy != !DstPtrTy) return false; // For non-pointer cases, the cast is okay if the source and destination bit // widths are identical. if (!SrcPtrTy) return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits(); // If both are pointers then the address spaces must match. if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) return false; // A vector of pointers must have the same number of elements. VectorType *SrcVecTy = dyn_cast(SrcTy); VectorType *DstVecTy = dyn_cast(DstTy); if (SrcVecTy && DstVecTy) return (SrcVecTy->getNumElements() == DstVecTy->getNumElements()); if (SrcVecTy) return SrcVecTy->getNumElements() == 1; if (DstVecTy) return DstVecTy->getNumElements() == 1; return true; } case Instruction::AddrSpaceCast: { PointerType *SrcPtrTy = dyn_cast(SrcTy->getScalarType()); if (!SrcPtrTy) return false; PointerType *DstPtrTy = dyn_cast(DstTy->getScalarType()); if (!DstPtrTy) return false; if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) return false; if (VectorType *SrcVecTy = dyn_cast(SrcTy)) { if (VectorType *DstVecTy = dyn_cast(DstTy)) return (SrcVecTy->getNumElements() == DstVecTy->getNumElements()); return false; } return true; } } } TruncInst::TruncInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, Trunc, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); } TruncInst::TruncInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, Trunc, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); } ZExtInst::ZExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, ZExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } ZExtInst::ZExtInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } SExtInst::SExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } SExtInst::SExtInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, SExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } FPTruncInst::FPTruncInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } FPTruncInst::FPTruncInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } FPExtInst::FPExtInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } FPExtInst::FPExtInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } UIToFPInst::UIToFPInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } UIToFPInst::UIToFPInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } SIToFPInst::SIToFPInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } SIToFPInst::SIToFPInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, SIToFP, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } FPToUIInst::FPToUIInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } FPToUIInst::FPToUIInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPToUI, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } FPToSIInst::FPToSIInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } FPToSIInst::FPToSIInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPToSI, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } PtrToIntInst::PtrToIntInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } PtrToIntInst::PtrToIntInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, PtrToInt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } IntToPtrInst::IntToPtrInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); } IntToPtrInst::IntToPtrInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, IntToPtr, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); } BitCastInst::BitCastInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, BitCast, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } BitCastInst::BitCastInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, BitCast, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } AddrSpaceCastInst::AddrSpaceCastInst( Value *S, Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); } AddrSpaceCastInst::AddrSpaceCastInst( Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, AddrSpaceCast, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast"); } //===----------------------------------------------------------------------===// // CmpInst Classes //===----------------------------------------------------------------------===// CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS, Value *RHS, const Twine &Name, Instruction *InsertBefore, Instruction *FlagsSource) : Instruction(ty, op, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertBefore) { Op<0>() = LHS; Op<1>() = RHS; setPredicate((Predicate)predicate); setName(Name); if (FlagsSource) copyIRFlags(FlagsSource); } CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(ty, op, OperandTraits::op_begin(this), OperandTraits::operands(this), InsertAtEnd) { Op<0>() = LHS; Op<1>() = RHS; setPredicate((Predicate)predicate); setName(Name); } CmpInst * CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore) { if (Op == Instruction::ICmp) { if (InsertBefore) return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate), S1, S2, Name); else return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name); } if (InsertBefore) return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate), S1, S2, Name); else return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name); } CmpInst * CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd) { if (Op == Instruction::ICmp) { return new ICmpInst(*InsertAtEnd, CmpInst::Predicate(predicate), S1, S2, Name); } return new FCmpInst(*InsertAtEnd, CmpInst::Predicate(predicate), S1, S2, Name); } void CmpInst::swapOperands() { if (ICmpInst *IC = dyn_cast(this)) IC->swapOperands(); else cast(this)->swapOperands(); } bool CmpInst::isCommutative() const { if (const ICmpInst *IC = dyn_cast(this)) return IC->isCommutative(); return cast(this)->isCommutative(); } bool CmpInst::isEquality() const { if (const ICmpInst *IC = dyn_cast(this)) return IC->isEquality(); return cast(this)->isEquality(); } CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) { switch (pred) { default: llvm_unreachable("Unknown cmp predicate!"); case ICMP_EQ: return ICMP_NE; case ICMP_NE: return ICMP_EQ; case ICMP_UGT: return ICMP_ULE; case ICMP_ULT: return ICMP_UGE; case ICMP_UGE: return ICMP_ULT; case ICMP_ULE: return ICMP_UGT; case ICMP_SGT: return ICMP_SLE; case ICMP_SLT: return ICMP_SGE; case ICMP_SGE: return ICMP_SLT; case ICMP_SLE: return ICMP_SGT; case FCMP_OEQ: return FCMP_UNE; case FCMP_ONE: return FCMP_UEQ; case FCMP_OGT: return FCMP_ULE; case FCMP_OLT: return FCMP_UGE; case FCMP_OGE: return FCMP_ULT; case FCMP_OLE: return FCMP_UGT; case FCMP_UEQ: return FCMP_ONE; case FCMP_UNE: return FCMP_OEQ; case FCMP_UGT: return FCMP_OLE; case FCMP_ULT: return FCMP_OGE; case FCMP_UGE: return FCMP_OLT; case FCMP_ULE: return FCMP_OGT; case FCMP_ORD: return FCMP_UNO; case FCMP_UNO: return FCMP_ORD; case FCMP_TRUE: return FCMP_FALSE; case FCMP_FALSE: return FCMP_TRUE; } } StringRef CmpInst::getPredicateName(Predicate Pred) { switch (Pred) { default: return "unknown"; case FCmpInst::FCMP_FALSE: return "false"; case FCmpInst::FCMP_OEQ: return "oeq"; case FCmpInst::FCMP_OGT: return "ogt"; case FCmpInst::FCMP_OGE: return "oge"; case FCmpInst::FCMP_OLT: return "olt"; case FCmpInst::FCMP_OLE: return "ole"; case FCmpInst::FCMP_ONE: return "one"; case FCmpInst::FCMP_ORD: return "ord"; case FCmpInst::FCMP_UNO: return "uno"; case FCmpInst::FCMP_UEQ: return "ueq"; case FCmpInst::FCMP_UGT: return "ugt"; case FCmpInst::FCMP_UGE: return "uge"; case FCmpInst::FCMP_ULT: return "ult"; case FCmpInst::FCMP_ULE: return "ule"; case FCmpInst::FCMP_UNE: return "une"; case FCmpInst::FCMP_TRUE: return "true"; case ICmpInst::ICMP_EQ: return "eq"; case ICmpInst::ICMP_NE: return "ne"; case ICmpInst::ICMP_SGT: return "sgt"; case ICmpInst::ICMP_SGE: return "sge"; case ICmpInst::ICMP_SLT: return "slt"; case ICmpInst::ICMP_SLE: return "sle"; case ICmpInst::ICMP_UGT: return "ugt"; case ICmpInst::ICMP_UGE: return "uge"; case ICmpInst::ICMP_ULT: return "ult"; case ICmpInst::ICMP_ULE: return "ule"; } } ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) { switch (pred) { default: llvm_unreachable("Unknown icmp predicate!"); case ICMP_EQ: case ICMP_NE: case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE: return pred; case ICMP_UGT: return ICMP_SGT; case ICMP_ULT: return ICMP_SLT; case ICMP_UGE: return ICMP_SGE; case ICMP_ULE: return ICMP_SLE; } } ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) { switch (pred) { default: llvm_unreachable("Unknown icmp predicate!"); case ICMP_EQ: case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE: return pred; case ICMP_SGT: return ICMP_UGT; case ICMP_SLT: return ICMP_ULT; case ICMP_SGE: return ICMP_UGE; case ICMP_SLE: return ICMP_ULE; } } CmpInst::Predicate CmpInst::getFlippedStrictnessPredicate(Predicate pred) { switch (pred) { default: llvm_unreachable("Unknown or unsupported cmp predicate!"); case ICMP_SGT: return ICMP_SGE; case ICMP_SLT: return ICMP_SLE; case ICMP_SGE: return ICMP_SGT; case ICMP_SLE: return ICMP_SLT; case ICMP_UGT: return ICMP_UGE; case ICMP_ULT: return ICMP_ULE; case ICMP_UGE: return ICMP_UGT; case ICMP_ULE: return ICMP_ULT; case FCMP_OGT: return FCMP_OGE; case FCMP_OLT: return FCMP_OLE; case FCMP_OGE: return FCMP_OGT; case FCMP_OLE: return FCMP_OLT; case FCMP_UGT: return FCMP_UGE; case FCMP_ULT: return FCMP_ULE; case FCMP_UGE: return FCMP_UGT; case FCMP_ULE: return FCMP_ULT; } } CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { switch (pred) { default: llvm_unreachable("Unknown cmp predicate!"); case ICMP_EQ: case ICMP_NE: return pred; case ICMP_SGT: return ICMP_SLT; case ICMP_SLT: return ICMP_SGT; case ICMP_SGE: return ICMP_SLE; case ICMP_SLE: return ICMP_SGE; case ICMP_UGT: return ICMP_ULT; case ICMP_ULT: return ICMP_UGT; case ICMP_UGE: return ICMP_ULE; case ICMP_ULE: return ICMP_UGE; case FCMP_FALSE: case FCMP_TRUE: case FCMP_OEQ: case FCMP_ONE: case FCMP_UEQ: case FCMP_UNE: case FCMP_ORD: case FCMP_UNO: return pred; case FCMP_OGT: return FCMP_OLT; case FCMP_OLT: return FCMP_OGT; case FCMP_OGE: return FCMP_OLE; case FCMP_OLE: return FCMP_OGE; case FCMP_UGT: return FCMP_ULT; case FCMP_ULT: return FCMP_UGT; case FCMP_UGE: return FCMP_ULE; case FCMP_ULE: return FCMP_UGE; } } CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) { switch (pred) { case ICMP_SGT: return ICMP_SGE; case ICMP_SLT: return ICMP_SLE; case ICMP_UGT: return ICMP_UGE; case ICMP_ULT: return ICMP_ULE; case FCMP_OGT: return FCMP_OGE; case FCMP_OLT: return FCMP_OLE; case FCMP_UGT: return FCMP_UGE; case FCMP_ULT: return FCMP_ULE; default: return pred; } } CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) { assert(CmpInst::isUnsigned(pred) && "Call only with signed predicates!"); switch (pred) { default: llvm_unreachable("Unknown predicate!"); case CmpInst::ICMP_ULT: return CmpInst::ICMP_SLT; case CmpInst::ICMP_ULE: return CmpInst::ICMP_SLE; case CmpInst::ICMP_UGT: return CmpInst::ICMP_SGT; case CmpInst::ICMP_UGE: return CmpInst::ICMP_SGE; } } bool CmpInst::isUnsigned(Predicate predicate) { switch (predicate) { default: return false; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return true; } } bool CmpInst::isSigned(Predicate predicate) { switch (predicate) { default: return false; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return true; } } bool CmpInst::isOrdered(Predicate predicate) { switch (predicate) { default: return false; case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_OGT: case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLE: case FCmpInst::FCMP_ORD: return true; } } bool CmpInst::isUnordered(Predicate predicate) { switch (predicate) { default: return false; case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_UGT: case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_ULE: case FCmpInst::FCMP_UNO: return true; } } bool CmpInst::isTrueWhenEqual(Predicate predicate) { switch(predicate) { default: return false; case ICMP_EQ: case ICMP_UGE: case ICMP_ULE: case ICMP_SGE: case ICMP_SLE: case FCMP_TRUE: case FCMP_UEQ: case FCMP_UGE: case FCMP_ULE: return true; } } bool CmpInst::isFalseWhenEqual(Predicate predicate) { switch(predicate) { case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_SGT: case ICMP_SLT: case FCMP_FALSE: case FCMP_ONE: case FCMP_OGT: case FCMP_OLT: return true; default: return false; } } bool CmpInst::isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) { // If the predicates match, then we know the first condition implies the // second is true. if (Pred1 == Pred2) return true; switch (Pred1) { default: break; case ICMP_EQ: // A == B implies A >=u B, A <=u B, A >=s B, and A <=s B are true. return Pred2 == ICMP_UGE || Pred2 == ICMP_ULE || Pred2 == ICMP_SGE || Pred2 == ICMP_SLE; case ICMP_UGT: // A >u B implies A != B and A >=u B are true. return Pred2 == ICMP_NE || Pred2 == ICMP_UGE; case ICMP_ULT: // A s B implies A != B and A >=s B are true. return Pred2 == ICMP_NE || Pred2 == ICMP_SGE; case ICMP_SLT: // A () = Value; Op<1>() = Default; } /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can /// be specified here to make memory allocation more efficient. This /// constructor can also autoinsert before another instruction. SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore) : Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch, nullptr, 0, InsertBefore) { init(Value, Default, 2+NumCases*2); } /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can /// be specified here to make memory allocation more efficient. This /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch, nullptr, 0, InsertAtEnd) { init(Value, Default, 2+NumCases*2); } SwitchInst::SwitchInst(const SwitchInst &SI) : Instruction(SI.getType(), Instruction::Switch, nullptr, 0) { init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands()); setNumHungOffUseOperands(SI.getNumOperands()); Use *OL = getOperandList(); const Use *InOL = SI.getOperandList(); for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) { OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } SubclassOptionalData = SI.SubclassOptionalData; } /// addCase - Add an entry to the switch instruction... /// void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { unsigned NewCaseIdx = getNumCases(); unsigned OpNo = getNumOperands(); if (OpNo+2 > ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); setNumHungOffUseOperands(OpNo+2); CaseHandle Case(this, NewCaseIdx); Case.setValue(OnVal); Case.setSuccessor(Dest); } /// removeCase - This method removes the specified case and its successor /// from the switch instruction. SwitchInst::CaseIt SwitchInst::removeCase(CaseIt I) { unsigned idx = I->getCaseIndex(); assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!"); unsigned NumOps = getNumOperands(); Use *OL = getOperandList(); // Overwrite this case with the end of the list. if (2 + (idx + 1) * 2 != NumOps) { OL[2 + idx * 2] = OL[NumOps - 2]; OL[2 + idx * 2 + 1] = OL[NumOps - 1]; } // Nuke the last value. OL[NumOps-2].set(nullptr); OL[NumOps-2+1].set(nullptr); setNumHungOffUseOperands(NumOps-2); return CaseIt(this, idx); } /// growOperands - grow operands - This grows the operand list in response /// to a push_back style of operation. This grows the number of ops by 3 times. /// void SwitchInst::growOperands() { unsigned e = getNumOperands(); unsigned NumOps = e*3; ReservedSpace = NumOps; growHungoffUses(ReservedSpace); } //===----------------------------------------------------------------------===// // IndirectBrInst Implementation //===----------------------------------------------------------------------===// void IndirectBrInst::init(Value *Address, unsigned NumDests) { assert(Address && Address->getType()->isPointerTy() && "Address of indirectbr must be a pointer"); ReservedSpace = 1+NumDests; setNumHungOffUseOperands(1); allocHungoffUses(ReservedSpace); Op<0>() = Address; } /// growOperands - grow operands - This grows the operand list in response /// to a push_back style of operation. This grows the number of ops by 2 times. /// void IndirectBrInst::growOperands() { unsigned e = getNumOperands(); unsigned NumOps = e*2; ReservedSpace = NumOps; growHungoffUses(ReservedSpace); } IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, Instruction *InsertBefore) : Instruction(Type::getVoidTy(Address->getContext()), Instruction::IndirectBr, nullptr, 0, InsertBefore) { init(Address, NumCases); } IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(Address->getContext()), Instruction::IndirectBr, nullptr, 0, InsertAtEnd) { init(Address, NumCases); } IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI) : Instruction(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr, nullptr, IBI.getNumOperands()) { allocHungoffUses(IBI.getNumOperands()); Use *OL = getOperandList(); const Use *InOL = IBI.getOperandList(); for (unsigned i = 0, E = IBI.getNumOperands(); i != E; ++i) OL[i] = InOL[i]; SubclassOptionalData = IBI.SubclassOptionalData; } /// addDestination - Add a destination. /// void IndirectBrInst::addDestination(BasicBlock *DestBB) { unsigned OpNo = getNumOperands(); if (OpNo+1 > ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. assert(OpNo < ReservedSpace && "Growing didn't work!"); setNumHungOffUseOperands(OpNo+1); getOperandList()[OpNo] = DestBB; } /// removeDestination - This method removes the specified successor from the /// indirectbr instruction. void IndirectBrInst::removeDestination(unsigned idx) { assert(idx < getNumOperands()-1 && "Successor index out of range!"); unsigned NumOps = getNumOperands(); Use *OL = getOperandList(); // Replace this value with the last one. OL[idx+1] = OL[NumOps-1]; // Nuke the last value. OL[NumOps-1].set(nullptr); setNumHungOffUseOperands(NumOps-1); } //===----------------------------------------------------------------------===// // cloneImpl() implementations //===----------------------------------------------------------------------===// // Define these methods here so vtables don't get emitted into every translation // unit that uses these classes. GetElementPtrInst *GetElementPtrInst::cloneImpl() const { return new (getNumOperands()) GetElementPtrInst(*this); } UnaryOperator *UnaryOperator::cloneImpl() const { return Create(getOpcode(), Op<0>()); } BinaryOperator *BinaryOperator::cloneImpl() const { return Create(getOpcode(), Op<0>(), Op<1>()); } FCmpInst *FCmpInst::cloneImpl() const { return new FCmpInst(getPredicate(), Op<0>(), Op<1>()); } ICmpInst *ICmpInst::cloneImpl() const { return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); } ExtractValueInst *ExtractValueInst::cloneImpl() const { return new ExtractValueInst(*this); } InsertValueInst *InsertValueInst::cloneImpl() const { return new InsertValueInst(*this); } AllocaInst *AllocaInst::cloneImpl() const { AllocaInst *Result = new AllocaInst(getAllocatedType(), getType()->getAddressSpace(), (Value *)getOperand(0), getAlignment()); Result->setUsedWithInAlloca(isUsedWithInAlloca()); Result->setSwiftError(isSwiftError()); return Result; } LoadInst *LoadInst::cloneImpl() const { - return new LoadInst(getOperand(0), Twine(), isVolatile(), + return new LoadInst(getType(), getOperand(0), Twine(), isVolatile(), getAlignment(), getOrdering(), getSyncScopeID()); } StoreInst *StoreInst::cloneImpl() const { return new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlignment(), getOrdering(), getSyncScopeID()); } AtomicCmpXchgInst *AtomicCmpXchgInst::cloneImpl() const { AtomicCmpXchgInst *Result = new AtomicCmpXchgInst(getOperand(0), getOperand(1), getOperand(2), getSuccessOrdering(), getFailureOrdering(), getSyncScopeID()); Result->setVolatile(isVolatile()); Result->setWeak(isWeak()); return Result; } AtomicRMWInst *AtomicRMWInst::cloneImpl() const { AtomicRMWInst *Result = new AtomicRMWInst(getOperation(), getOperand(0), getOperand(1), getOrdering(), getSyncScopeID()); Result->setVolatile(isVolatile()); return Result; } FenceInst *FenceInst::cloneImpl() const { return new FenceInst(getContext(), getOrdering(), getSyncScopeID()); } TruncInst *TruncInst::cloneImpl() const { return new TruncInst(getOperand(0), getType()); } ZExtInst *ZExtInst::cloneImpl() const { return new ZExtInst(getOperand(0), getType()); } SExtInst *SExtInst::cloneImpl() const { return new SExtInst(getOperand(0), getType()); } FPTruncInst *FPTruncInst::cloneImpl() const { return new FPTruncInst(getOperand(0), getType()); } FPExtInst *FPExtInst::cloneImpl() const { return new FPExtInst(getOperand(0), getType()); } UIToFPInst *UIToFPInst::cloneImpl() const { return new UIToFPInst(getOperand(0), getType()); } SIToFPInst *SIToFPInst::cloneImpl() const { return new SIToFPInst(getOperand(0), getType()); } FPToUIInst *FPToUIInst::cloneImpl() const { return new FPToUIInst(getOperand(0), getType()); } FPToSIInst *FPToSIInst::cloneImpl() const { return new FPToSIInst(getOperand(0), getType()); } PtrToIntInst *PtrToIntInst::cloneImpl() const { return new PtrToIntInst(getOperand(0), getType()); } IntToPtrInst *IntToPtrInst::cloneImpl() const { return new IntToPtrInst(getOperand(0), getType()); } BitCastInst *BitCastInst::cloneImpl() const { return new BitCastInst(getOperand(0), getType()); } AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const { return new AddrSpaceCastInst(getOperand(0), getType()); } CallInst *CallInst::cloneImpl() const { if (hasOperandBundles()) { unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo); return new(getNumOperands(), DescriptorBytes) CallInst(*this); } return new(getNumOperands()) CallInst(*this); } SelectInst *SelectInst::cloneImpl() const { return SelectInst::Create(getOperand(0), getOperand(1), getOperand(2)); } VAArgInst *VAArgInst::cloneImpl() const { return new VAArgInst(getOperand(0), getType()); } ExtractElementInst *ExtractElementInst::cloneImpl() const { return ExtractElementInst::Create(getOperand(0), getOperand(1)); } InsertElementInst *InsertElementInst::cloneImpl() const { return InsertElementInst::Create(getOperand(0), getOperand(1), getOperand(2)); } ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const { return new ShuffleVectorInst(getOperand(0), getOperand(1), getOperand(2)); } PHINode *PHINode::cloneImpl() const { return new PHINode(*this); } LandingPadInst *LandingPadInst::cloneImpl() const { return new LandingPadInst(*this); } ReturnInst *ReturnInst::cloneImpl() const { return new(getNumOperands()) ReturnInst(*this); } BranchInst *BranchInst::cloneImpl() const { return new(getNumOperands()) BranchInst(*this); } SwitchInst *SwitchInst::cloneImpl() const { return new SwitchInst(*this); } IndirectBrInst *IndirectBrInst::cloneImpl() const { return new IndirectBrInst(*this); } InvokeInst *InvokeInst::cloneImpl() const { if (hasOperandBundles()) { unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo); return new(getNumOperands(), DescriptorBytes) InvokeInst(*this); } return new(getNumOperands()) InvokeInst(*this); } ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); } CleanupReturnInst *CleanupReturnInst::cloneImpl() const { return new (getNumOperands()) CleanupReturnInst(*this); } CatchReturnInst *CatchReturnInst::cloneImpl() const { return new (getNumOperands()) CatchReturnInst(*this); } CatchSwitchInst *CatchSwitchInst::cloneImpl() const { return new CatchSwitchInst(*this); } FuncletPadInst *FuncletPadInst::cloneImpl() const { return new (getNumOperands()) FuncletPadInst(*this); } UnreachableInst *UnreachableInst::cloneImpl() const { LLVMContext &Context = getContext(); return new UnreachableInst(Context); }