Skip to content

Commit 0fb5c00

Browse files
authored
Merge pull request #178 from CodaFi/octogenarian
Update to LLVM 8.0
2 parents 3c588dd + bd42124 commit 0fb5c00

22 files changed

+1180
-105
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ matrix:
1818
sudo: required
1919
dist: trusty
2020
env:
21-
- LLVM_API_VERSION=7
21+
- LLVM_API_VERSION=8
2222
before_install:
2323
- export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:"${PKG_CONFIG_PATH}"
2424
- wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -

Sources/LLVM/AttachedMetadata.swift

Lines changed: 706 additions & 0 deletions
Large diffs are not rendered by default.

Sources/LLVM/BasicBlock.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,32 @@ public struct BasicBlock: IRValue {
2323
self.llvm = llvm
2424
}
2525

26+
/// Creates a new basic block without a parent function.
27+
///
28+
/// The basic block should be inserted into a function or destroyed before
29+
/// the IR builder is finalized.
30+
public init(context: Context = .global, name: String = "") {
31+
self.llvm = LLVMCreateBasicBlockInContext(context.llvm, name)
32+
}
33+
34+
/// Given that this block and a given block share a parent function, move this
35+
/// block before the given block in that function's basic block list.
36+
///
37+
/// - Parameter position: The basic block that acts as a position before
38+
/// which this block will be moved.
39+
public func move(before position: BasicBlock) {
40+
LLVMMoveBasicBlockBefore(self.asLLVM(), position.asLLVM())
41+
}
42+
43+
/// Given that this block and a given block share a parent function, move this
44+
/// block after the given block in that function's basic block list.
45+
///
46+
/// - Parameter position: The basic block that acts as a position after
47+
/// which this block will be moved.
48+
public func move(after position: BasicBlock) {
49+
LLVMMoveBasicBlockAfter(self.asLLVM(), position.asLLVM())
50+
}
51+
2652
/// Retrieves the underlying LLVM value object.
2753
public func asLLVM() -> LLVMValueRef {
2854
return llvm

Sources/LLVM/DIBuilder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,12 +645,12 @@ extension DIBuilder {
645645
/// - encoding: The basic type encoding
646646
/// - size: Size of the type.
647647
public func buildBasicType(
648-
named name: String, encoding: DIAttributeTypeEncoding, size: Size
648+
named name: String, encoding: DIAttributeTypeEncoding, flags: DIFlags, size: Size
649649
) -> DIType {
650650
let radix = UInt64(self.module.dataLayout.intPointerType().width)
651651
guard let ty = LLVMDIBuilderCreateBasicType(
652652
self.llvm, name, name.count,
653-
size.valueInBits(radix: radix), encoding.llvm)
653+
size.valueInBits(radix: radix), encoding.llvm, flags.llvm)
654654
else {
655655
fatalError("Failed to allocate metadata")
656656
}

Sources/LLVM/IRBuilder.swift

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,56 @@ extension IRBuilder {
123123
public func buildCast(_ op: OpCode.Cast, value: IRValue, type: IRType, name: String = "") -> IRValue {
124124
return LLVMBuildCast(llvm, op.llvm, value.asLLVM(), type.asLLVM(), name)
125125
}
126+
127+
/// Builds a cast operation from a value of pointer type to any other
128+
/// integral, pointer, or vector of integral/pointer type.
129+
///
130+
/// There are a number of restrictions on the form of the input value and
131+
/// destination type. The source value of a pointer cast must be either a
132+
/// pointer or a vector of pointers. The destination type must either be
133+
/// an integer type, a pointer type, or a vector type with integral or pointer
134+
/// element type.
135+
///
136+
/// If the destination type is an integral type or a vector of integral
137+
/// elements, this builds a `ptrtoint` instruction. Else, if the destination
138+
/// is a pointer type or vector of pointer type, and it has an address space
139+
/// that differs from the address space of the source value, an
140+
/// `addrspacecast` instruction is built. If none of these are true, a
141+
/// `bitcast` instruction is built.
142+
///
143+
/// - Parameters:
144+
/// - value: The value to cast. The value must have pointer type.
145+
/// - type: The destination type to cast to. This must be a pointer type,
146+
/// integer type, or vector of the same.
147+
/// - name: The name for the newly inserted instruction.
148+
/// - Returns: A value representing the result of casting the given value to
149+
/// the given destination type using the appropriate pointer cast operation.
150+
public func buildPointerCast(of value: IRValue, to type: IRType, name: String = "") -> IRValue {
151+
precondition(value.type is PointerType || value.type.scalarType is PointerType,
152+
"cast value must be a pointer or vector of pointers")
153+
precondition(type.scalarType is IntType || type.scalarType is PointerType,
154+
"destination type must be int, pointer, or vector of int/pointer")
155+
156+
return LLVMBuildPointerCast(llvm, value.asLLVM(), type.asLLVM(), name)
157+
}
158+
159+
/// Builds a cast operation from a value of integral type to given integral
160+
/// type by zero-extension, sign-extension, bitcast, or truncation
161+
/// as necessary.
162+
///
163+
/// - Parameters:
164+
/// - value: The value to cast.
165+
/// - type: The destination integer type to cast to.
166+
/// - signed: If true, if an extension is required it will be a
167+
/// sign-extension. Else, all required extensions will be
168+
/// zero-extensions.
169+
/// - name: The name for the newly inserted instruction.
170+
/// - Returns: A value reprresenting the result of casting the given value to
171+
/// the given destination integer type using the appropriate
172+
/// integral cast operation.
173+
public func buildIntCast(of value: IRValue, to type: IntType, signed: Bool = true, name: String = "") -> IRValue {
174+
return LLVMBuildIntCast2(llvm, value.asLLVM(), type.asLLVM(), signed.llvm, name)
175+
}
126176
}
127177

128178
// MARK: Arithmetic Instructions
@@ -1392,6 +1442,100 @@ extension IRBuilder {
13921442
}
13931443
}
13941444

1445+
// MARK: Memory Intrinsics
1446+
1447+
extension IRBuilder {
1448+
/// Builds a call to the `llvm.memset.*` family of intrinsics to fill a
1449+
/// given block of memory with a given byte value.
1450+
///
1451+
/// - NOTE: Unlike the standard function `memset` defined in libc,
1452+
/// `llvm.memset` does not return a value and may be volatile. The address
1453+
/// space of the source and destination values need not match.
1454+
///
1455+
/// - Parameters:
1456+
/// - dest: A pointer value to the destination that will be filled.
1457+
/// - value: A byte value to fill the destination with.
1458+
/// - length: The number of bytes to fill.
1459+
/// - alignment: The alignment of the destination pointer value.
1460+
/// - volatile: If true, builds a volatile `llvm.memset` intrinsic, else
1461+
/// builds a non-volatile `llvm.memset` instrinsic. The exact behavior of
1462+
/// volatile memory intrinsics is platform-dependent and should not be
1463+
/// relied upon to perform consistently. For more information, see the
1464+
/// language reference's section on [Volatile Memory
1465+
/// Access](http://llvm.org/docs/LangRef.html#volatile-memory-accesses).
1466+
public func buildMemset(
1467+
to dest: IRValue, of value: IRValue, length: IRValue,
1468+
alignment: Alignment, volatile: Bool = false
1469+
) {
1470+
let instruction = LLVMBuildMemSet(self.llvm, dest.asLLVM(), value.asLLVM(), length.asLLVM(), alignment.rawValue)
1471+
LLVMSetVolatile(instruction, volatile.llvm)
1472+
}
1473+
1474+
/// Builds a call to the `llvm.memcpy.*` family of intrinsics to copy a block
1475+
/// of memory to a given destination memory location from a given source
1476+
/// memory location.
1477+
///
1478+
/// - WARNING: It is illegal for the destination and source locations to
1479+
/// overlap each other.
1480+
///
1481+
/// - NOTE: Unlike the standard function `memcpy` defined in libc,
1482+
/// `llvm.memcpy` does not return a value and may be volatile. The address
1483+
/// space of the source and destination values need not match.
1484+
///
1485+
/// - Parameters:
1486+
/// - dest: A pointer to the destination that will be filled.
1487+
/// - destAlign: The alignment of the destination pointer value.
1488+
/// - src: A pointer to the source that will be copied from.
1489+
/// - srcAlign: The alignment of the source pointer value.
1490+
/// - length: The number of bytes to fill.
1491+
/// - volatile: If true, builds a volatile `llvm.memcpy` intrinsic, else
1492+
/// builds a non-volatile `llvm.memcpy` instrinsic. The exact behavior of
1493+
/// volatile memory intrinsics is platform-dependent and should not be
1494+
/// relied upon to perform consistently. For more information, see the
1495+
/// language reference's section on [Volatile Memory
1496+
/// Access](http://llvm.org/docs/LangRef.html#volatile-memory-accesses).
1497+
public func buildMemCpy(
1498+
to dest: IRValue, _ destAlign: Alignment,
1499+
from src: IRValue, _ srcAlign: Alignment,
1500+
length: IRValue, volatile: Bool = false
1501+
) {
1502+
let instruction = LLVMBuildMemCpy(self.llvm, dest.asLLVM(), destAlign.rawValue, src.asLLVM(), srcAlign.rawValue, length.asLLVM())
1503+
LLVMSetVolatile(instruction, volatile.llvm)
1504+
}
1505+
1506+
/// Builds a call to the `llvm.memmove.*` family of intrinsics to move a
1507+
/// block of memory to a given destination memory location from a given source
1508+
/// memory location.
1509+
///
1510+
/// Unlike `llvm.memcpy.*`, the destination and source memory locations may
1511+
/// overlap with each other.
1512+
///
1513+
/// - NOTE: Unlike the standard function `memmove` defined in libc,
1514+
/// `llvm.memmove` does not return a value and may be volatile. The address
1515+
/// space of the source and destination values need not match.
1516+
///
1517+
/// - Parameters:
1518+
/// - dest: A pointer to the destination that will be filled.
1519+
/// - destAlign: The alignment of the destination pointer value.
1520+
/// - src: A pointer to the source that will be copied from.
1521+
/// - srcAlign: The alignment of the source pointer value.
1522+
/// - length: The number of bytes to fill.
1523+
/// - volatile: If true, builds a volatile `llvm.memmove` intrinsic, else
1524+
/// builds a non-volatile `llvm.memmove` instrinsic. The exact behavior of
1525+
/// volatile memory intrinsics is platform-dependent and should not be
1526+
/// relied upon to perform consistently. For more information, see the
1527+
/// language reference's section on [Volatile Memory
1528+
/// Access](http://llvm.org/docs/LangRef.html#volatile-memory-accesses).
1529+
public func buildMemMove(
1530+
to dest: IRValue, _ destAlign: Alignment,
1531+
from src: IRValue, _ srcAlign: Alignment,
1532+
length: IRValue, volatile: Bool = false
1533+
) {
1534+
let instruction = LLVMBuildMemMove(self.llvm, dest.asLLVM(), destAlign.rawValue, src.asLLVM(), srcAlign.rawValue, length.asLLVM())
1535+
LLVMSetVolatile(instruction, volatile.llvm)
1536+
}
1537+
}
1538+
13951539
// MARK: Aggregate Instructions
13961540

13971541
extension IRBuilder {
@@ -1422,7 +1566,7 @@ extension IRBuilder {
14221566
///
14231567
/// - returns: A value representing an aggregate that has been updated with
14241568
/// the given value at the given index.
1425-
func buildExtractValue(aggregate: IRValue, index: Int, name: String = "") -> IRValue {
1569+
public func buildExtractValue(aggregate: IRValue, index: Int, name: String = "") -> IRValue {
14261570
return LLVMBuildExtractValue(llvm, aggregate.asLLVM(), UInt32(index), name)
14271571
}
14281572
}

Sources/LLVM/IRGlobal.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import cllvm
77
public protocol IRGlobal: IRConstant {}
88

99
extension IRGlobal {
10+
/// Retrieves the "value type" of this global value.
11+
///
12+
/// The formal type of a global value is always a pointer type. The value
13+
/// type, in contrast, is the type of the value the global points to.
14+
public var valueType: IRType {
15+
return convertType(LLVMGlobalGetValueType(asLLVM()))
16+
}
17+
1018
/// Retrieves the alignment of this value.
1119
public var alignment: Alignment {
1220
get { return Alignment(LLVMGetAlignment(asLLVM())) }

Sources/LLVM/IRMetadata.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ extension IRMetadata {
6969
public func forceCast<DestTy: IRMetadata>(to: DestTy.Type) -> DestTy {
7070
return DestTy(llvm: self.asMetadata())
7171
}
72+
73+
/// Returns the kind of this metadata node.
74+
public var kind: IRMetadataKind {
75+
return IRMetadataKind(raw: LLVMGetMetadataKind(self.asMetadata()))
76+
}
7277
}
7378

7479
/// Denotes a scope in which child metadata nodes can be inserted.
@@ -377,3 +382,76 @@ public struct ExpressionMetadata: IRMetadata {
377382
self.llvm = llvm
378383
}
379384
}
385+
386+
/// Enumerates the kind of metadata nodes.
387+
public enum IRMetadataKind {
388+
case mdString
389+
case constantAsMetadata
390+
case localAsMetadata
391+
case distinctMDOperandPlaceholder
392+
case mdTuple
393+
case location
394+
case expression
395+
case globalVariableExpression
396+
case genericDINode
397+
case subrange
398+
case enumerator
399+
case basicType
400+
case derivedType
401+
case compositeType
402+
case subroutineType
403+
case file
404+
case compileUnit
405+
case subprogram
406+
case lexicalBlock
407+
case lexicalBlockFile
408+
case namespace
409+
case module
410+
case templateTypeParameter
411+
case templateValueParameter
412+
case globalVariable
413+
case localVariable
414+
case label
415+
case objCProperty
416+
case importedEntity
417+
case macro
418+
case macroFile
419+
420+
fileprivate init(raw: LLVMMetadataKind) {
421+
switch Int(raw) {
422+
case LLVMMDStringMetadataKind: self = .mdString
423+
case LLVMConstantAsMetadataMetadataKind: self = .constantAsMetadata
424+
case LLVMLocalAsMetadataMetadataKind: self = .localAsMetadata
425+
case LLVMDistinctMDOperandPlaceholderMetadataKind: self = .distinctMDOperandPlaceholder
426+
case LLVMMDTupleMetadataKind: self = .mdTuple
427+
case LLVMDILocationMetadataKind: self = .location
428+
case LLVMDIExpressionMetadataKind: self = .expression
429+
case LLVMDIGlobalVariableExpressionMetadataKind: self = .globalVariableExpression
430+
case LLVMGenericDINodeMetadataKind: self = .genericDINode
431+
case LLVMDISubrangeMetadataKind: self = .subrange
432+
case LLVMDIEnumeratorMetadataKind: self = .enumerator
433+
case LLVMDIBasicTypeMetadataKind: self = .basicType
434+
case LLVMDIDerivedTypeMetadataKind: self = .derivedType
435+
case LLVMDICompositeTypeMetadataKind: self = .compositeType
436+
case LLVMDISubroutineTypeMetadataKind: self = .subroutineType
437+
case LLVMDIFileMetadataKind: self = .file
438+
case LLVMDICompileUnitMetadataKind: self = .compileUnit
439+
case LLVMDISubprogramMetadataKind: self = .subprogram
440+
case LLVMDILexicalBlockMetadataKind: self = .lexicalBlock
441+
case LLVMDILexicalBlockFileMetadataKind: self = .lexicalBlockFile
442+
case LLVMDINamespaceMetadataKind: self = .namespace
443+
case LLVMDIModuleMetadataKind: self = .module
444+
case LLVMDITemplateTypeParameterMetadataKind: self = .templateTypeParameter
445+
case LLVMDITemplateValueParameterMetadataKind: self = .templateValueParameter
446+
case LLVMDIGlobalVariableMetadataKind: self = .globalVariable
447+
case LLVMDILocalVariableMetadataKind: self = .localVariable
448+
case LLVMDILabelMetadataKind: self = .label
449+
case LLVMDIObjCPropertyMetadataKind: self = .objCProperty
450+
case LLVMDIImportedEntityMetadataKind: self = .importedEntity
451+
case LLVMDIMacroMetadataKind: self = .macro
452+
case LLVMDIMacroFileMetadataKind: self = .macroFile
453+
default:
454+
fatalError("Unknown kind")
455+
}
456+
}
457+
}

Sources/LLVM/IRType.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ public extension IRType {
3434
var context: Context {
3535
return Context(llvm: LLVMGetTypeContext(asLLVM()))
3636
}
37+
38+
/// If this is a vector type, return the element type, otherwise
39+
/// return `self`.
40+
var scalarType: IRType {
41+
guard let vecTy = self as? VectorType else {
42+
return self
43+
}
44+
return vecTy.elementType
45+
}
3746
}
3847

3948
internal func convertType(_ type: LLVMTypeRef) -> IRType {

Sources/LLVM/JIT.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,22 @@ public final class JIT {
257257
try checkForJITError(LLVMOrcRemoveModule(self.llvm, handle.llvm))
258258
}
259259

260-
private func checkForJITError(_ orcError: LLVMOrcErrorCode) throws {
261-
switch orcError {
262-
case LLVMOrcErrSuccess:
260+
private func checkForJITError(_ orcError: LLVMErrorRef!) throws {
261+
guard let err = orcError else {
263262
return
264-
case LLVMOrcErrGeneric:
265-
guard let msg = LLVMOrcGetErrorMsg(self.llvm) else {
263+
}
264+
265+
switch LLVMGetErrorTypeId(err)! {
266+
case LLVMGetStringErrorTypeId():
267+
guard let msg = LLVMGetErrorMessage(self.llvm) else {
266268
fatalError("Couldn't get the error message?")
267269
}
268270
throw JITError.generic(String(cString: msg))
269271
default:
270-
fatalError("Uncategorized ORC error code!")
272+
guard let msg = LLVMOrcGetErrorMsg(self.llvm) else {
273+
fatalError("Couldn't get the error message?")
274+
}
275+
throw JITError.generic(String(cString: msg))
271276
}
272277
}
273278
}

Sources/LLVM/MetadataAttributes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ public struct DIFlags : OptionSet {
505505
/// target's calling convention.
506506
public static let passByReference = DIFlags(rawValue: LLVMDIFlagTypePassByReference.rawValue)
507507
/// Denotes a "fixed enum" type e.g. a C++ `enum class`.
508-
public static let fixedEnum = DIFlags(rawValue: LLVMDIFlagFixedEnum.rawValue)
508+
public static let enumClass = DIFlags(rawValue: LLVMDIFlagEnumClass.rawValue)
509509
/// Denotes a thunk function.
510510
public static let thunk = DIFlags(rawValue: LLVMDIFlagThunk.rawValue)
511511
/// Denotes a class that has a trivial default constructor and is trivially

0 commit comments

Comments
 (0)