diff --git a/.travis.yml b/.travis.yml index 0d92c954..1a713bff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,40 +5,43 @@ matrix: include: - os: osx language: objective-c - osx_image: xcode10.2 + osx_image: xcode11.5 before_install: - export PATH=/usr/local/opt/llvm/bin:"${PATH}" - brew update - - brew install llvm + - brew install llvm@9 + - echo 'export PATH="/usr/local/opt/llvm@9/bin:$PATH"' >> /Users/travis/.bash_profile + - source /Users/travis/.bash_profile - sudo swift utils/make-pkgconfig.swift script: - swift test -Xlinker -w - os: linux language: generic sudo: required - dist: trusty + dist: focal env: - - LLVM_API_VERSION=8 + - LLVM_API_VERSION=9 before_install: - export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:"${PKG_CONFIG_PATH}" - wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - - sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-${LLVM_API_VERSION} main" + - sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_API_VERSION} main" - sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - sudo apt-get update - - sudo apt-get install -y llvm-${LLVM_API_VERSION} libc++1 + - sudo apt-get install -y binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev pkg-config tzdata zlib1g-dev + - sudo apt-get install -y llvm-${LLVM_API_VERSION} llvm-${LLVM_API_VERSION}-dev libc++1 libtinfo5 libncurses5 - sudo cp /usr/lib/x86_64-linux-gnu/libc++.so.1.0 /usr/lib/ - sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so - sudo rm -rf /usr/local/clang-*/bin/llvm-config - - ls -l /usr/bin/llvm-config* - sudo rm -f /usr/bin/llvm-config - sudo ln -s /usr/bin/llvm-config-${LLVM_API_VERSION} /usr/bin/llvm-config + - ls /usr/lib/llvm-9/include/llvm-c - wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - - - wget https://swift.org/builds/swift-5.0-release/ubuntu1404/swift-5.0-RELEASE/swift-5.0-RELEASE-ubuntu14.04.tar.gz - - tar xzf swift-5.0-RELEASE-ubuntu14.04.tar.gz - - export PATH=${PWD}/swift-5.0-RELEASE-ubuntu14.04/usr/bin:"${PATH}" - - sudo ./swift-5.0-RELEASE-ubuntu14.04/usr/bin/swift utils/make-pkgconfig.swift + - wget https://swift.org/builds/swift-5.2.5-release/ubuntu1804/swift-5.2.5-RELEASE/swift-5.2.5-RELEASE-ubuntu18.04.tar.gz + - tar xzf swift-5.2.5-RELEASE-ubuntu18.04.tar.gz + - export PATH=${PWD}/swift-5.2.5-RELEASE-ubuntu18.04/usr/bin:"${PATH}" + - sudo ./swift-5.2.5-RELEASE-ubuntu18.04/usr/bin/swift utils/make-pkgconfig.swift script: - - ./swift-5.0-RELEASE-ubuntu14.04/usr/bin/swift test + - sudo ./swift-5.2.5-RELEASE-ubuntu18.04/usr/bin/swift test notifications: slack: secure: ek/+U+e44bqP8+QCHojy2LhrN9iwY3N/TNNqNG5FZrp09Vidrd5KXWJOXFxlGrpeWdgTpi089YbEdTfxpcDIudUqDqLwPzS7wePiG2cEC1OT6l3yrhI4AvOe7EsNSOX8gzkuEnmrZVHwLLGe7JeR7JIQKoHMZsBcPYDnO8kRP0Ei3zOh47YUn75SE87egAgZOVBDbZYO3GWRa4WX64s8gaQYQ9a7EoUY0oX9rQ48FJs3rmEIhvIXdcOj9bGX7+o0j7l+IFial/Qh+B6bp4XkZU/tUVP6cuNVI1vxE1weVGCBhgt5wLhXTMewzoE5D1IgMZHVuzIBcDbBthSzQRttLSlYar6xTjXtRtOnb8tqZMWfUj3HBYCFYqtz7PGnZ3IflEVsPJW6tgSsoeB6egjzb8APP9mvhm8+zb1jQG1dqXLWErMjWqhlyPVPmHrxU2w/OLWLAJPY94GVmLnSuOw2pSz41spuEY80JcVVzoRbAOQWrwAujq2S3k93yvKpGq4eaT72Mt8g1CyZesByvzcLk99LEJSpqOIxUqXBd4RwHhay/sq8LllyyqY8ORsxEgwQluOAjEhATO/t/HUsu2ndn1k38U1c4HqXW7FDs1hffYEzZ/PGxciCS6Vt1bfST+iq34pzqpanENQCnX6mSR+D+M7mHlCWdsUihmxEcs5knuM= diff --git a/Sources/LLVM/AddressSpace.swift b/Sources/LLVM/AddressSpace.swift new file mode 100644 index 00000000..b0d36ee7 --- /dev/null +++ b/Sources/LLVM/AddressSpace.swift @@ -0,0 +1,66 @@ +#if SWIFT_PACKAGE +import cllvm +#endif + +/// An address space is an identifier for a target-specific range of address values. An address space is a +/// fundamental part of the type of a pointer value and the type of operations that manipulate memory. +/// +/// LLVM affords a default address space (numbered zero) and places a number of assumptions on pointer +/// values within that address space: +/// - The pointer must have a fixed integral value +/// - The null pointer has a bit-value of 0 +/// +/// These assumptions are not guaranteed to hold in any other address space. In particular, a target may +/// allow pointers in non-default address spaces to have *non-integral* types. Non-integral pointer types +/// represent pointers that have an unspecified bitwise representation; that is, the integral representation may +/// be target dependent or have an unstable value. Further, outside of the default address space, it is not +/// always the case that the `null` pointer value, especially as returned by +/// `IRType.constPointerNull()` has a bit value of 0. e.g. A non-default address space may use +/// an offset-based or segment-based addressing mode in which 0 is a valid, addressable pointer value. +/// +/// Target-Level Address Space Overrides +/// ==================================== +/// +/// A target may choose to override the default address space for code, data, and local allocations through the +/// data layout string. This has multiple uses. For example, the address space of an `alloca` is *only* +/// configurable via the data layout string, because it is a target-dependent property. There are also +/// use-cases for overriding language standards e.g. the C standard requires the address-of operator applied +/// to values on the stack to result in a pointer in the default address space. However, many OpenCL-based +/// targets consider the stack to be a private region, and place such pointers in a non-default address space. +/// +/// Care must be taken when interacting with these non-standard targets. The IR printer currently does not +/// print anything when the default address space is attached to an instruction or value, and values will still +/// report being assigned to that space. However, these values are still subject to the backend's interpretation +/// of the data layout string overrides and as such may not always reside in the default address space when +/// it comes time to codegen them. +/// +/// Restrictions +/// ============ +/// +/// There are currently a number of artificial restrictions on values and operations that have non-default +/// address spaces: +/// - A `bitcast` between two pointer values residing in different address spaces, even if those two +/// values have the same size, is always an illegal operation. Use an `addrspacecast` instead or +/// always use `IRBuilder.buildPointerCast(of:to:name:)` to get the correct operation. +/// - The so-called "null pointer" has a bit value that may differ from address space to address space. This +/// exposes bugs in optimizer passes and lowerings that did not consider this possibility. +/// - A pointer value may not necessarily "round-trip" when converted between address spaces, even if +/// annotated `nonnull` and `dereferenceable`. This is especially true of non-integral pointer types. +/// - Though the zero address space is the default, many backends and some errant passes interpret this to +/// mean a "lack of address space" and may miscompile code with pointers in mixed address spaces. +/// - A number of intriniscs that operate on memory currently do not support a non-default address space. +/// - The address space is ultimately an integer value and in theory an address space identifier may take on +/// any value. In practice, LLVM guarantees only 24 bits of precision, though higher address space +/// identifiers may succeed in being properly represented. +public struct AddressSpace: Equatable { + let rawValue: Int + + /// LLVM's default address space. + public static let zero = AddressSpace(0) + + /// Creates and initializes an address space with the given identifier. + /// - Parameter identifier: The raw, integral address space identifier. + public init(_ identifier: Int) { + self.rawValue = identifier + } +} diff --git a/Sources/LLVM/AttachedMetadata.swift b/Sources/LLVM/AttachedMetadata.swift index d9404c53..75b1f04e 100644 --- a/Sources/LLVM/AttachedMetadata.swift +++ b/Sources/LLVM/AttachedMetadata.swift @@ -336,6 +336,9 @@ public class AttachedMetadata { /// attribute may only be applied to pointer typed parameters. This is not /// checked or enforced by LLVM; if the parameter or return pointer is null, /// the behavior is undefined. + /// + /// Note that the concept of a "null" pointer is address space dependent. it is + /// not necessarily the 0 bit-pattern. case nonnull = 11 /// Dereferenceable metadata. /// diff --git a/Sources/LLVM/DIBuilder.swift b/Sources/LLVM/DIBuilder.swift index 7a3e28f9..b61a35b9 100644 --- a/Sources/LLVM/DIBuilder.swift +++ b/Sources/LLVM/DIBuilder.swift @@ -664,17 +664,17 @@ extension DIBuilder { /// - pointee: Type pointed by this pointer. /// - size: The size of the pointer value. /// - alignment: The alignment of the pointer. - /// - addressSpace: DWARF address space. + /// - addressSpace: The address space the pointer type reside in. /// - name: The name of the pointer type. public func buildPointerType( pointee: DIType, size: Size, alignment: Alignment = .zero, - addressSpace: UInt32 = 0, name: String = "" + addressSpace: AddressSpace = .zero, name: String = "" ) -> DIType { let radix = UInt32(self.module.dataLayout.intPointerType().width) guard let ty = LLVMDIBuilderCreatePointerType( self.llvm, pointee.asMetadata(), size.valueInBits(radix: UInt64(radix)), alignment.rawValue * radix, - addressSpace, name, name.count) + UInt32(addressSpace.rawValue), name, name.count) else { fatalError("Failed to allocate metadata") } diff --git a/Sources/LLVM/IRBuilder.swift b/Sources/LLVM/IRBuilder.swift index eae8b515..507ebf9a 100644 --- a/Sources/LLVM/IRBuilder.swift +++ b/Sources/LLVM/IRBuilder.swift @@ -1038,6 +1038,9 @@ extension IRBuilder { /// choose to align the allocation on any convenient boundary compatible with /// the type. /// + /// The returned value is allocated in the address space specified in the data layout string for the target. If + /// no such value is specified, the value is allocated in the default address space. + /// /// - parameter type: The sized type used to determine the amount of stack /// memory to allocate. /// - parameter count: An optional number of slots to allocate, to simulate a @@ -1277,6 +1280,9 @@ extension IRBuilder { /// `bitcast` instruction. Note that if the address space conversion is legal /// then both result and operand refer to the same memory location. /// + /// This instruction must be used in lieu of a `bitcast` even if the cast is between + /// types of the same size. + /// /// The address spaces of the value and the destination pointer types must /// be distinct. public func buildAddrSpaceCast(_ val: IRValue, type: IRType, name: String = "") -> IRValue { @@ -1791,7 +1797,7 @@ extension IRBuilder { /// variable resides. /// /// - returns: A value representing the newly inserted global variable. - public func addGlobal(_ name: String, type: IRType, addressSpace: Int? = nil) -> Global { + public func addGlobal(_ name: String, type: IRType, addressSpace: AddressSpace = .zero) -> Global { return self.module.addGlobal(name, type: type, addressSpace: addressSpace) } @@ -1803,7 +1809,7 @@ extension IRBuilder { /// variable resides. /// /// - returns: A value representing the newly inserted global variable. - public func addGlobal(_ name: String, initializer: IRValue, addressSpace: Int? = nil) -> Global { + public func addGlobal(_ name: String, initializer: IRValue, addressSpace: AddressSpace = .zero) -> Global { return self.module.addGlobal(name, initializer: initializer, addressSpace: addressSpace) } diff --git a/Sources/LLVM/IRMetadata.swift b/Sources/LLVM/IRMetadata.swift index 87c6f6ae..3559fb09 100644 --- a/Sources/LLVM/IRMetadata.swift +++ b/Sources/LLVM/IRMetadata.swift @@ -438,7 +438,7 @@ public struct MDNode: IRMetadata { public init(in context: Context = .global, operands: [IRMetadata]) { var operands = operands.map { $0.asMetadata() as Optional } self.llvm = operands.withUnsafeMutableBufferPointer { buf in - return LLVMMDNodeInContext2(context.llvm, buf.baseAddress!, UInt32(buf.count)) + return LLVMMDNodeInContext2(context.llvm, buf.baseAddress!, buf.count) } } diff --git a/Sources/LLVM/IRType.swift b/Sources/LLVM/IRType.swift index 17e22afe..a77b1982 100644 --- a/Sources/LLVM/IRType.swift +++ b/Sources/LLVM/IRType.swift @@ -81,7 +81,7 @@ internal func convertType(_ type: LLVMTypeRef) -> IRType { case LLVMPointerTypeKind: let pointee = convertType(LLVMGetElementType(type)) let addressSpace = Int(LLVMGetPointerAddressSpace(type)) - return PointerType(pointee: pointee, addressSpace: addressSpace) + return PointerType(pointee: pointee, addressSpace: AddressSpace(addressSpace)) case LLVMVectorTypeKind: let elementType = convertType(LLVMGetElementType(type)) let count = Int(LLVMGetVectorSize(type)) diff --git a/Sources/LLVM/IRValue.swift b/Sources/LLVM/IRValue.swift index 09023e27..9c30d5a5 100644 --- a/Sources/LLVM/IRValue.swift +++ b/Sources/LLVM/IRValue.swift @@ -107,6 +107,8 @@ public enum IRValueKind { /// The value is a constant floating pointer value. case constantFloat /// The value is a constant pointer to null. + /// + /// Note that this pointer is a zero bit-value pointer. Its semantics are dependent upon the address space. case constantPointerNull /// The value is a constant none-token value. case constantTokenNone diff --git a/Sources/LLVM/MetadataAttributes.swift b/Sources/LLVM/MetadataAttributes.swift index 5ca0afaa..2af8fc07 100644 --- a/Sources/LLVM/MetadataAttributes.swift +++ b/Sources/LLVM/MetadataAttributes.swift @@ -496,8 +496,6 @@ public struct DIFlags : OptionSet { public static let bitField = DIFlags(rawValue: LLVMDIFlagBitField.rawValue) /// Denotes a `noreturn` function. public static let noReturn = DIFlags(rawValue: LLVMDIFlagNoReturn.rawValue) - /// Denotes the subprogram for main. - public static let mainSubprogram = DIFlags(rawValue: LLVMDIFlagMainSubprogram.rawValue) /// Denotes a parameter that is passed by value according to the target's /// calling convention. public static let passByValue = DIFlags(rawValue: LLVMDIFlagTypePassByValue.rawValue) @@ -508,9 +506,8 @@ public struct DIFlags : OptionSet { public static let enumClass = DIFlags(rawValue: LLVMDIFlagEnumClass.rawValue) /// Denotes a thunk function. public static let thunk = DIFlags(rawValue: LLVMDIFlagThunk.rawValue) - /// Denotes a class that has a trivial default constructor and is trivially - /// copiable. - public static let trivial = DIFlags(rawValue: LLVMDIFlagTrivial.rawValue) + /// Denotes a class that has a non-trivial default constructor or is not trivially copiable. + public static let nonTrivial = DIFlags(rawValue: LLVMDIFlagNonTrivial.rawValue) /// Denotes an indirect virtual base class. public static let indirectVirtualBase = DIFlags(rawValue: LLVMDIFlagIndirectVirtualBase.rawValue) /// The mask for `public`, `private`, and `protected` accessibility. diff --git a/Sources/LLVM/Module.swift b/Sources/LLVM/Module.swift index f4fd2ac7..a8002bb6 100644 --- a/Sources/LLVM/Module.swift +++ b/Sources/LLVM/Module.swift @@ -502,12 +502,9 @@ extension Module { /// variable resides. /// /// - returns: A value representing the newly inserted global variable. - public func addGlobal(_ name: String, type: IRType, addressSpace: Int? = nil) -> Global { - let val: LLVMValueRef - if let addressSpace = addressSpace { - val = LLVMAddGlobalInAddressSpace(llvm, type.asLLVM(), name, UInt32(addressSpace)) - } else { - val = LLVMAddGlobal(llvm, type.asLLVM(), name) + public func addGlobal(_ name: String, type: IRType, addressSpace: AddressSpace = .zero) -> Global { + guard let val = LLVMAddGlobalInAddressSpace(llvm, type.asLLVM(), name, UInt32(addressSpace.rawValue)) else { + fatalError() } return Global(llvm: val) } @@ -520,7 +517,7 @@ extension Module { /// variable resides. /// /// - returns: A value representing the newly inserted global variable. - public func addGlobal(_ name: String, initializer: IRValue, addressSpace: Int? = nil) -> Global { + public func addGlobal(_ name: String, initializer: IRValue, addressSpace: AddressSpace = .zero) -> Global { let global = addGlobal(name, type: initializer.type) global.initializer = initializer return global diff --git a/Sources/LLVM/ObjectFile.swift b/Sources/LLVM/ObjectFile.swift index e86805df..bf28fdb5 100644 --- a/Sources/LLVM/ObjectFile.swift +++ b/Sources/LLVM/ObjectFile.swift @@ -184,7 +184,7 @@ public final class MachOUniversalBinaryFile: BinaryFile { public func objectFile(for architecture: Triple.Architecture) throws -> Slice { var error: UnsafeMutablePointer? let archName = architecture.rawValue - let archFile: LLVMBinaryRef = LLVMUniversalBinaryCopyObjectForArchitecture(self.llvm, archName, archName.count, &error) + let archFile: LLVMBinaryRef = LLVMMachOUniversalBinaryCopyObjectForArch(self.llvm, archName, archName.count, &error) if let error = error { defer { LLVMDisposeMessage(error) } throw BinaryFileError.couldNotCreate(String(cString: error)) diff --git a/Sources/LLVM/PassManager.swift b/Sources/LLVM/PassManager.swift index f37e60df..475a469c 100644 --- a/Sources/LLVM/PassManager.swift +++ b/Sources/LLVM/PassManager.swift @@ -212,7 +212,8 @@ public enum Pass { /// Return a new pass object which transforms invoke instructions into calls, /// if the callee can *not* unwind the stack. case pruneEH - + /// This transformation attempts to discovery `alloca` allocations of aggregates that can be + /// broken down into component scalar values. case scalarReplacementOfAggregates /// This pass removes any function declarations (prototypes) that are not used. case stripDeadPrototypes diff --git a/Sources/LLVM/PointerType.swift b/Sources/LLVM/PointerType.swift index c24c1362..e3b036ad 100644 --- a/Sources/LLVM/PointerType.swift +++ b/Sources/LLVM/PointerType.swift @@ -16,7 +16,7 @@ public struct PointerType: IRType { /// Retrieves the type of the value being pointed to. public let pointee: IRType /// Retrieves the address space where the pointed-to object resides. - public let addressSpace: Int + public let addressSpace: AddressSpace /// Creates a `PointerType` from a pointee type and an optional address space. /// @@ -24,7 +24,7 @@ public struct PointerType: IRType { /// - parameter addressSpace: The optional address space where the pointed-to /// object resides. /// - note: The context of this type is taken from it's pointee - public init(pointee: IRType, addressSpace: Int = 0) { + public init(pointee: IRType, addressSpace: AddressSpace = .zero) { // FIXME: This class of invalid reference is not caught by Module.verify(), // only `lli`. if pointee is VoidType { @@ -40,7 +40,7 @@ public struct PointerType: IRType { /// Retrieves the underlying LLVM type object. public func asLLVM() -> LLVMTypeRef { - return LLVMPointerType(pointee.asLLVM(), UInt32(addressSpace)) + return LLVMPointerType(pointee.asLLVM(), UInt32(addressSpace.rawValue)) } } diff --git a/Sources/LLVM/TargetData.swift b/Sources/LLVM/TargetData.swift index 3556b29e..d90eb2bc 100644 --- a/Sources/LLVM/TargetData.swift +++ b/Sources/LLVM/TargetData.swift @@ -17,7 +17,7 @@ public class TargetData { /// Computes the byte offset of the indexed struct element for a target. /// /// - parameter element: The index of the element in the given structure to - // compute. + /// compute. /// - parameter type: The type of the structure to compute the offset with. /// /// - returns: The offset of the given element within the structure. @@ -66,17 +66,9 @@ public class TargetData { /// - addressSpace: The address space in which to derive the type. /// - returns: An IntegerType that is the same size as the pointer type /// on this target. - public func intPointerType(context: Context? = nil, addressSpace: Int? = nil) -> IntType { - let type: LLVMTypeRef - switch (context, addressSpace) { - case let (context?, addressSpace?): - type = LLVMIntPtrTypeForASInContext(context.llvm, llvm, UInt32(addressSpace)) - case let (nil, addressSpace?): - type = LLVMIntPtrTypeForAS(llvm, UInt32(addressSpace)) - case let (context?, nil): - type = LLVMIntPtrTypeInContext(context.llvm, llvm) - case (nil, nil): - type = LLVMIntPtrType(llvm) + public func intPointerType(context: Context = .global, addressSpace: AddressSpace = .zero) -> IntType { + guard let type = LLVMIntPtrTypeForASInContext(context.llvm, llvm, UInt32(addressSpace.rawValue)) else { + fatalError() } return convertType(type) as! IntType // Guaranteed to succeed } @@ -137,12 +129,8 @@ public class TargetData { /// - parameter addressSpace: The address space in which to compute /// pointer size. /// - returns: The size of a pointer in the target address space. - public func pointerSize(addressSpace: Int? = nil) -> Size { - if let addressSpace = addressSpace { - return Size(UInt64(LLVMPointerSizeForAS(llvm, UInt32(addressSpace)))) - } else { - return Size(UInt64(LLVMPointerSize(llvm))) - } + public func pointerSize(addressSpace: AddressSpace = .zero) -> Size { + return Size(UInt64(LLVMPointerSizeForAS(llvm, UInt32(addressSpace.rawValue)))) } /// Returns the offset in bytes between successive objects of the diff --git a/Sources/cllvm/shim.h b/Sources/cllvm/shim.h index 638e8eed..34606ac0 100644 --- a/Sources/cllvm/shim.h +++ b/Sources/cllvm/shim.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/Sources/llvmshims/include/shim.h b/Sources/llvmshims/include/shim.h index 4b0a69c5..4c60936b 100644 --- a/Sources/llvmshims/include/shim.h +++ b/Sources/llvmshims/include/shim.h @@ -8,7 +8,6 @@ size_t LLVMSwiftCountIntrinsics(void); const char *LLVMSwiftGetIntrinsicAtIndex(size_t index); -unsigned LLVMLookupIntrinsicID(const char *Name, size_t NameLen); const char *LLVMGetARMCanonicalArchName(const char *Name, size_t NameLen); typedef enum { @@ -20,84 +19,8 @@ typedef enum { LLVMARMProfileKind LLVMARMParseArchProfile(const char *Name, size_t NameLen); unsigned LLVMARMParseArchVersion(const char *Name, size_t NameLen); -typedef enum { - LLVMBinaryTypeArchive, - LLVMBinaryTypeMachOUniversalBinary, - LLVMBinaryTypeCOFFImportFile, - // LLVM IR - LLVMBinaryTypeIR, - - // Windows resource (.res) file. - LLVMBinaryTypeWinRes, - - // Object and children. - LLVMBinaryTypeCOFF, - - // ELF 32-bit, little endian - LLVMBinaryTypeELF32L, - // ELF 32-bit, big endian - LLVMBinaryTypeELF32B, - // ELF 64-bit, little endian - LLVMBinaryTypeELF64L, - // ELF 64-bit, big endian - LLVMBinaryTypeELF64B, - - // MachO 32-bit, little endian - LLVMBinaryTypeMachO32L, - // MachO 32-bit, big endian - LLVMBinaryTypeMachO32B, - // MachO 64-bit, little endian - LLVMBinaryTypeMachO64L, - // MachO 64-bit, big endian - LLVMBinaryTypeMachO64B, - - LLVMBinaryTypeWasm, -} LLVMBinaryType; - -typedef struct LLVMOpaqueBinary *LLVMBinaryRef; - -LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR); -LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, LLVMContextRef Context, char **ErrorMessage); -LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR); -void LLVMDisposeBinary(LLVMBinaryRef BR); - -LLVMBinaryRef LLVMUniversalBinaryCopyObjectForArchitecture(LLVMBinaryRef BR, const char *Arch, size_t ArchLen, char **ErrorMessage); - -LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR); - -LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, - LLVMSectionIteratorRef SI); -LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR); - -LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, - LLVMSymbolIteratorRef SI); - -LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst); -void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc); - -LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder); -void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc); - -LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope); -const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len); -const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len); -const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len); - -void LLVMBuilderSetDefaultFPMathTag(LLVMBuilderRef Builder, - LLVMMetadataRef FPMathTag); - -LLVMMetadataRef LLVMBuilderGetDefaultFPMathTag(LLVMBuilderRef Builder); - -LLVMMetadataRef LLVMMDNodeInContext2(LLVMContextRef C, LLVMMetadataRef *MDs, - unsigned Count); - uint64_t LLVMGlobalGetGUID(LLVMValueRef Global); -void LLVMAppendExistingBasicBlock(LLVMValueRef Fn, - LLVMBasicBlockRef BB); - -void LLVMAddAddDiscriminatorsPass(LLVMPassManagerRef PM); - void LLVMAddGlobalsAAWrapperPass(LLVMPassManagerRef PM); void LLVMAddInternalizePassWithMustPreservePredicate( diff --git a/Sources/llvmshims/src/shim.cpp b/Sources/llvmshims/src/shim.cpp index b5fc7b34..574e9bb5 100644 --- a/Sources/llvmshims/src/shim.cpp +++ b/Sources/llvmshims/src/shim.cpp @@ -15,11 +15,6 @@ #include "llvm/Transforms/IPO.h" extern "C" { - typedef struct LLVMOpaqueBinary *LLVMBinaryRef; - - // https://reviews.llvm.org/D59697 - unsigned LLVMLookupIntrinsicID(const char *Name, size_t NameLen); - // Not to be upstreamed: They support the hacks that power our dynamic member // lookup machinery for intrinsics. const char *LLVMSwiftGetIntrinsicAtIndex(size_t index); @@ -39,95 +34,10 @@ extern "C" { LLVMARMProfileKind LLVMARMParseArchProfile(const char *Name, size_t NameLen); unsigned LLVMARMParseArchVersion(const char *Name, size_t NameLen); - // https://reviews.llvm.org/D60366 - typedef enum { - LLVMBinaryTypeArchive, - LLVMBinaryTypeMachOUniversalBinary, - LLVMBinaryTypeCOFFImportFile, - // LLVM IR - LLVMBinaryTypeIR, - - // Windows resource (.res) file. - LLVMBinaryTypeWinRes, - - // Object and children. - LLVMBinaryTypeCOFF, - - // ELF 32-bit, little endian - LLVMBinaryTypeELF32L, - // ELF 32-bit, big endian - LLVMBinaryTypeELF32B, - // ELF 64-bit, little endian - LLVMBinaryTypeELF64L, - // ELF 64-bit, big endian - LLVMBinaryTypeELF64B, - - // MachO 32-bit, little endian - LLVMBinaryTypeMachO32L, - // MachO 32-bit, big endian - LLVMBinaryTypeMachO32B, - // MachO 64-bit, little endian - LLVMBinaryTypeMachO64L, - // MachO 64-bit, big endian - LLVMBinaryTypeMachO64B, - - LLVMBinaryTypeWasm, - } LLVMBinaryType; - - LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR); - - // https://reviews.llvm.org/D60322 - LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, LLVMContextRef Context, char **ErrorMessage); - LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR); - void LLVMDisposeBinary(LLVMBinaryRef BR); - - // https://reviews.llvm.org/D60378 - LLVMBinaryRef LLVMUniversalBinaryCopyObjectForArchitecture(LLVMBinaryRef BR, const char *Arch, size_t ArchLen, char **ErrorMessage); - - // https://reviews.llvm.org/D60407 - LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR); - - LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, - LLVMSectionIteratorRef SI); - LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR); - - LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, - LLVMSymbolIteratorRef SI); - - // https://reviews.llvm.org/D60481 - LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst); - void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc); - - // https://reviews.llvm.org/D60484 - LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder); - void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc); - - // https://reviews.llvm.org/D60489 - LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope); - const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len); - const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len); - const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len); - - // https://reviews.llvm.org/D60527 - void LLVMBuilderSetDefaultFPMathTag(LLVMBuilderRef Builder, - LLVMMetadataRef FPMathTag); - LLVMMetadataRef LLVMBuilderGetDefaultFPMathTag(LLVMBuilderRef Builder); - - // https://reviews.llvm.org/D60524 - LLVMMetadataRef LLVMMDNodeInContext2(LLVMContextRef C, LLVMMetadataRef *MDs, - unsigned Count); - // Not to be upstreamed: It's not clear there's value in having this outside // of PGO passes. uint64_t LLVMGlobalGetGUID(LLVMValueRef Global); - // https://reviews.llvm.org/D59658 - void LLVMAppendExistingBasicBlock(LLVMValueRef Fn, - LLVMBasicBlockRef BB); - - // https://reviews.llvm.org/D58624 - void LLVMAddAddDiscriminatorsPass(LLVMPassManagerRef PM); - // https://reviews.llvm.org/D66237 void LLVMAddGlobalsAAWrapperPass(LLVMPassManagerRef PM); @@ -151,139 +61,6 @@ extern "C" { using namespace llvm; using namespace llvm::object; -inline Binary *unwrap(LLVMBinaryRef OF) { - return reinterpret_cast(OF); -} - -inline static LLVMBinaryRef wrap(const Binary *OF) { - return reinterpret_cast(const_cast(OF)); -} - -inline static section_iterator *unwrap(LLVMSectionIteratorRef SI) { - return reinterpret_cast(SI); -} - -inline static LLVMSectionIteratorRef -wrap(const section_iterator *SI) { - return reinterpret_cast - (const_cast(SI)); -} - -inline static symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) { - return reinterpret_cast(SI); -} - -inline static LLVMSymbolIteratorRef -wrap(const symbol_iterator *SI) { - return reinterpret_cast - (const_cast(SI)); -} - -LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) { - class BinaryTypeMapper final : public Binary { - public: - static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) { - switch (Kind) { - case ID_Archive: - return LLVMBinaryTypeArchive; - case ID_MachOUniversalBinary: - return LLVMBinaryTypeMachOUniversalBinary; - case ID_COFFImportFile: - return LLVMBinaryTypeCOFFImportFile; - case ID_IR: - return LLVMBinaryTypeIR; - case ID_WinRes: - return LLVMBinaryTypeWinRes; - case ID_COFF: - return LLVMBinaryTypeCOFF; - case ID_ELF32L: - return LLVMBinaryTypeELF32L; - case ID_ELF32B: - return LLVMBinaryTypeELF32B; - case ID_ELF64L: - return LLVMBinaryTypeELF64L; - case ID_ELF64B: - return LLVMBinaryTypeELF64B; - case ID_MachO32L: - return LLVMBinaryTypeMachO32L; - case ID_MachO32B: - return LLVMBinaryTypeMachO32B; - case ID_MachO64L: - return LLVMBinaryTypeMachO64L; - case ID_MachO64B: - return LLVMBinaryTypeMachO64B; - case ID_Wasm: - return LLVMBinaryTypeWasm; - default: - llvm_unreachable("Unknown binary kind!"); - } - } - }; - return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType()); -} - -LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, LLVMContextRef Context, char **ErrorMessage) { - Expected> ObjOrErr( - createBinary(unwrap(MemBuf)->getMemBufferRef(), unwrap(Context))); - if (!ObjOrErr) { - *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str()); - return nullptr; - } - - return wrap(ObjOrErr.get().release()); -} - -LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) { - auto Buf = unwrap(BR)->getMemoryBufferRef(); - return wrap(llvm::MemoryBuffer::getMemBuffer( - Buf.getBuffer(), Buf.getBufferIdentifier(), - /*RequiresNullTerminator*/false).release()); -} - -void LLVMDisposeBinary(LLVMBinaryRef BR) { - delete unwrap(BR); -} - -LLVMBinaryRef LLVMUniversalBinaryCopyObjectForArchitecture(LLVMBinaryRef BR, const char *Arch, size_t ArchLen, char **ErrorMessage) { - assert(LLVMBinaryGetType(BR) == LLVMBinaryTypeMachOUniversalBinary); - auto universal = cast(unwrap(BR)); - Expected> ObjOrErr( - universal->getObjectForArch({Arch, ArchLen})); - if (!ObjOrErr) { - *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str()); - return nullptr; - } - return wrap(ObjOrErr.get().release()); -} - -LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) { - auto OF = cast(unwrap(BR)); - auto sections = OF->sections(); - if (sections.begin() == sections.end()) - return nullptr; - return wrap(new section_iterator(sections.begin())); -} - -LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, - LLVMSectionIteratorRef SI) { - auto OF = cast(unwrap(BR)); - return (*unwrap(SI) == OF->section_end()) ? 1 : 0; -} - -LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) { - auto OF = cast(unwrap(BR)); - auto symbols = OF->symbols(); - if (symbols.begin() == symbols.end()) - return nullptr; - return wrap(new symbol_iterator(symbols.begin())); -} - -LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, - LLVMSymbolIteratorRef SI) { - auto OF = cast(unwrap(BR)); - return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0; -} - size_t LLVMSwiftCountIntrinsics(void) { return llvm::Intrinsic::num_intrinsics; } @@ -292,10 +69,6 @@ const char *LLVMSwiftGetIntrinsicAtIndex(size_t index) { return llvm::Intrinsic::getName(static_cast(index)).data(); } -unsigned LLVMLookupIntrinsicID(const char *Name, size_t NameLen) { - return llvm::Function::lookupIntrinsicID({Name, NameLen}); -} - LLVMARMProfileKind LLVMARMParseArchProfile(const char *Name, size_t NameLen) { return static_cast(llvm::ARM::parseArchProfile({Name, NameLen})); } @@ -308,83 +81,10 @@ const char *LLVMGetARMCanonicalArchName(const char *Name, size_t NameLen) { return llvm::ARM::getCanonicalArchName({Name, NameLen}).data(); } -LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst) { - return wrap(unwrap(Inst)->getDebugLoc().getAsMDNode()); -} - -void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc) { - if (Loc) - unwrap(Inst)->setDebugLoc(DebugLoc(unwrap(Loc))); - else - unwrap(Inst)->setDebugLoc(DebugLoc()); -} - -LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder) { - return wrap(unwrap(Builder)->getCurrentDebugLocation().getAsMDNode()); -} - -void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc) { - if (Loc) - unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(unwrap(Loc))); - else - unwrap(Builder)->SetCurrentDebugLocation(DebugLoc()); -} - -const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len) { - auto Dir = unwrap(File)->getDirectory(); - *Len = Dir.size(); - return Dir.data(); -} - -const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len) { - auto Dir = unwrap(File)->getFilename(); - *Len = Dir.size(); - return Dir.data(); -} - -const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len) { - if (auto Dir = unwrap(File)->getSource()) { - *Len = Dir->size(); - return Dir->data(); - } - *Len = 0; - return ""; -} - -LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope) { - return wrap(unwrap(Scope)->getFile()); -} - -void LLVMBuilderSetDefaultFPMathTag(LLVMBuilderRef Builder, - LLVMMetadataRef FPMathTag) { - - unwrap(Builder)->setDefaultFPMathTag(FPMathTag - ? unwrap(FPMathTag) - : nullptr); -} - -LLVMMetadataRef LLVMBuilderGetDefaultFPMathTag(LLVMBuilderRef Builder) { - return wrap(unwrap(Builder)->getDefaultFPMathTag()); -} - -LLVMMetadataRef LLVMMDNodeInContext2(LLVMContextRef C, LLVMMetadataRef *MDs, - unsigned Count) { - return wrap(MDNode::get(*unwrap(C), ArrayRef(unwrap(MDs), Count))); -} - uint64_t LLVMGlobalGetGUID(LLVMValueRef Glob) { return unwrap(Glob)->getGUID(); } -void LLVMAppendExistingBasicBlock(LLVMValueRef Fn, - LLVMBasicBlockRef BB) { - unwrap(Fn)->getBasicBlockList().push_back(unwrap(BB)); -} - -void LLVMAddAddDiscriminatorsPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createAddDiscriminatorsPass()); -} - void LLVMAddInternalizePassWithMustPreservePredicate( LLVMPassManagerRef PM, void *Context, LLVMBool (*Pred)(LLVMValueRef, void *)) { @@ -429,4 +129,3 @@ void LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind TCK) { unwrap(Call)->setTailCallKind(kind); } - diff --git a/Tests/LLVMTests/UnitSpec.swift b/Tests/LLVMTests/UnitSpec.swift index 5e3f0b3e..bb572719 100644 --- a/Tests/LLVMTests/UnitSpec.swift +++ b/Tests/LLVMTests/UnitSpec.swift @@ -117,7 +117,7 @@ class UnitSpec : XCTestCase { let aarch32 = try! TargetMachine(triple: Triple("arm--"), cpu: "", features: "", optLevel: .none, relocations: .default, codeModel: .default) mod.dataLayout = aarch32.dataLayout - XCTAssertEqual(mod.dataLayoutString, "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64") + XCTAssertEqual(mod.dataLayoutString, "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64") let packedLayout32 = mod.dataLayout.layout(of: packedStruct) XCTAssertEqual(packedLayout32.alignment, Alignment.one) diff --git a/utils/make-pkgconfig.swift b/utils/make-pkgconfig.swift index c98ff0a5..9ed629f5 100644 --- a/utils/make-pkgconfig.swift +++ b/utils/make-pkgconfig.swift @@ -17,10 +17,10 @@ func run(_ path: String, args: [String] = []) -> String? { print("Running \(path) \(args.joined(separator: " "))...") let pipe = Pipe() let process = Process() - process.launchPath = path + process.executableURL = URL(fileURLWithPath: path) process.arguments = args process.standardOutput = pipe - process.launch() + try? process.run() process.waitUntilExit() let data = pipe.fileHandleForReading.readDataToEndOfFile() @@ -63,7 +63,7 @@ func makeFile() throws { } /// Ensure we have llvm-config in the PATH - guard let llvmConfig = which("llvm-config-7") ?? which("llvm-config") ?? brewLLVMConfig() else { + guard let llvmConfig = which("llvm-config-9") ?? which("llvm-config") ?? brewLLVMConfig() else { throw "Failed to find llvm-config. Ensure llvm-config is installed and " + "in your PATH" } @@ -84,8 +84,8 @@ func makeFile() throws { let version = (components[0], components[1], components[2]) - guard version >= (7, 0, 0) else { - throw "LLVMSwift requires LLVM version >=6.0.0, but you have \(versionStr)" + guard version >= (9, 0, 0) else { + throw "LLVMSwift requires LLVM version >=9.0.0, but you have \(versionStr)" } print("LLVM version is \(versionStr)")