Skip to content

Commit b40580c

Browse files
committed
Opaque Pointer Cleanup
Finish the migration to opaque pointers. * Fixup the singular load in the README * Fixup the test suite * Move the deprecations into a convenient extension
1 parent 15f1656 commit b40580c

11 files changed

+170
-164
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Package.resolved
55
Package.pins
66
/*.xcodeproj
77
/build
8+
/.swiftpm

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ phi.addIncoming([
133133
(elseVal, elseBB),
134134
])
135135
builder.buildStore(phi, to: local)
136-
let ret = builder.buildLoad(local, name: "ret")
136+
let ret = builder.buildLoad(local, type: FloatType.double, name: "ret")
137137
builder.buildRet(ret)
138138
```
139139

Sources/LLVM/IRBuilder.swift

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,27 +1078,6 @@ extension IRBuilder {
10781078
return storeInst
10791079
}
10801080

1081-
/// Build a load instruction that loads a value from the location in the
1082-
/// given value.
1083-
///
1084-
/// - parameter ptr: The pointer value to load from.
1085-
/// - parameter ordering: The ordering effect of the fence for this load,
1086-
/// if any. Defaults to a nonatomic load.
1087-
/// - parameter volatile: Whether this is a load from a volatile memory location.
1088-
/// - parameter alignment: The alignment of the access.
1089-
/// - parameter name: The name for the newly inserted instruction.
1090-
///
1091-
/// - returns: A value representing the result of a load from the given
1092-
/// pointer value.
1093-
@available(*, deprecated, message: "Use buildLoad(type:ptr:ordering:volatile:alignment:name) instead")
1094-
public func buildLoad(_ ptr: IRValue, ordering: AtomicOrdering = .notAtomic, volatile: Bool = false, alignment: Alignment = .zero, name: String = "") -> IRInstruction {
1095-
let loadInst = LLVMBuildLoad(llvm, ptr.asLLVM(), name)!
1096-
LLVMSetOrdering(loadInst, ordering.llvm)
1097-
LLVMSetVolatile(loadInst, volatile.llvm)
1098-
LLVMSetAlignment(loadInst, alignment.rawValue)
1099-
return loadInst
1100-
}
1101-
11021081
/// Build a load instruction that loads a value from the location in the
11031082
/// given value.
11041083
///
@@ -1119,29 +1098,7 @@ extension IRBuilder {
11191098
LLVMSetAlignment(loadInst, alignment.rawValue)
11201099
return loadInst
11211100
}
1122-
1123-
/// Build a `GEP` (Get Element Pointer) instruction with a resultant value
1124-
/// that is undefined if the address is outside the actual underlying
1125-
/// allocated object and not the address one-past-the-end.
1126-
///
1127-
/// The `GEP` instruction is often the source of confusion. LLVM [provides a
1128-
/// document](http://llvm.org/docs/GetElementPtr.html) to answer questions
1129-
/// around its semantics and correct usage.
1130-
///
1131-
/// - parameter ptr: The base address for the index calculation.
1132-
/// - parameter indices: A list of indices that indicate which of the elements
1133-
/// of the aggregate object are indexed.
1134-
/// - parameter name: The name for the newly inserted instruction.
1135-
///
1136-
/// - returns: A value representing the address of a subelement of the given
1137-
/// aggregate data structure value.
1138-
@available(*, deprecated, message: "Use buildInBoundsGEP(type:ptr:indices:name) instead")
1139-
public func buildInBoundsGEP(_ ptr: IRValue, indices: [IRValue], name: String = "") -> IRValue {
1140-
var vals = indices.map { $0.asLLVM() as Optional }
1141-
return vals.withUnsafeMutableBufferPointer { buf in
1142-
return LLVMBuildInBoundsGEP(llvm, ptr.asLLVM(), buf.baseAddress, UInt32(buf.count), name)
1143-
}
1144-
}
1101+
11451102

11461103
/// Build a `GEP` (Get Element Pointer) instruction with a resultant value
11471104
/// that is undefined if the address is outside the actual underlying
@@ -1166,27 +1123,6 @@ extension IRBuilder {
11661123
}
11671124
}
11681125

1169-
/// Build a GEP (Get Element Pointer) instruction.
1170-
///
1171-
/// The `GEP` instruction is often the source of confusion. LLVM [provides a
1172-
/// document](http://llvm.org/docs/GetElementPtr.html) to answer questions
1173-
/// around its semantics and correct usage.
1174-
///
1175-
/// - parameter ptr: The base address for the index calculation.
1176-
/// - parameter indices: A list of indices that indicate which of the elements
1177-
/// of the aggregate object are indexed.
1178-
/// - parameter name: The name for the newly inserted instruction.
1179-
///
1180-
/// - returns: A value representing the address of a subelement of the given
1181-
/// aggregate data structure value.
1182-
@available(*, deprecated, message: "Use buildGEP(type:ptr:indices:name) instead")
1183-
public func buildGEP(_ ptr: IRValue, indices: [IRValue], name: String = "") -> IRValue {
1184-
var vals = indices.map { $0.asLLVM() as Optional }
1185-
return vals.withUnsafeMutableBufferPointer { buf in
1186-
return LLVMBuildGEP(llvm, ptr.asLLVM(), buf.baseAddress, UInt32(buf.count), name)
1187-
}
1188-
}
1189-
11901126
/// Build a GEP (Get Element Pointer) instruction.
11911127
///
11921128
/// The `GEP` instruction is often the source of confusion. LLVM [provides a
@@ -1207,20 +1143,6 @@ extension IRBuilder {
12071143
return LLVMBuildGEP2(llvm, type.asLLVM(), ptr.asLLVM(), buf.baseAddress, UInt32(buf.count), name)
12081144
}
12091145
}
1210-
1211-
/// Build a GEP (Get Element Pointer) instruction suitable for indexing into
1212-
/// a struct.
1213-
///
1214-
/// - parameter ptr: The base address for the index calculation.
1215-
/// - parameter index: The offset from the base for the index calculation.
1216-
/// - parameter name: The name for the newly inserted instruction.
1217-
///
1218-
/// - returns: A value representing the address of a subelement of the given
1219-
/// struct value.
1220-
@available(*, deprecated, message: "Use buildStructGEP(type:ptr:index:name) instead")
1221-
public func buildStructGEP(_ ptr: IRValue, index: Int, name: String = "") -> IRValue {
1222-
return LLVMBuildStructGEP(llvm, ptr.asLLVM(), UInt32(index), name)
1223-
}
12241146

12251147
/// Build a GEP (Get Element Pointer) instruction suitable for indexing into
12261148
/// a struct of a given type.
@@ -1993,6 +1915,89 @@ extension IRBuilder {
19931915
}
19941916
}
19951917

1918+
// MARK: Deprecated APIs
1919+
1920+
extension IRBuilder {
1921+
/// Build a load instruction that loads a value from the location in the
1922+
/// given value.
1923+
///
1924+
/// - parameter ptr: The pointer value to load from.
1925+
/// - parameter ordering: The ordering effect of the fence for this load,
1926+
/// if any. Defaults to a nonatomic load.
1927+
/// - parameter volatile: Whether this is a load from a volatile memory location.
1928+
/// - parameter alignment: The alignment of the access.
1929+
/// - parameter name: The name for the newly inserted instruction.
1930+
///
1931+
/// - returns: A value representing the result of a load from the given
1932+
/// pointer value.
1933+
@available(*, deprecated, message: "Use buildLoad(_:type:ordering:volatile:alignment:name) instead")
1934+
public func buildLoad(_ ptr: IRValue, ordering: AtomicOrdering = .notAtomic, volatile: Bool = false, alignment: Alignment = .zero, name: String = "") -> IRInstruction {
1935+
let loadInst = LLVMBuildLoad(llvm, ptr.asLLVM(), name)!
1936+
LLVMSetOrdering(loadInst, ordering.llvm)
1937+
LLVMSetVolatile(loadInst, volatile.llvm)
1938+
LLVMSetAlignment(loadInst, alignment.rawValue)
1939+
return loadInst
1940+
}
1941+
1942+
/// Build a GEP (Get Element Pointer) instruction suitable for indexing into
1943+
/// a struct.
1944+
///
1945+
/// - parameter ptr: The base address for the index calculation.
1946+
/// - parameter index: The offset from the base for the index calculation.
1947+
/// - parameter name: The name for the newly inserted instruction.
1948+
///
1949+
/// - returns: A value representing the address of a subelement of the given
1950+
/// struct value.
1951+
@available(*, deprecated, message: "Use buildStructGEP(_:type:index:name) instead")
1952+
public func buildStructGEP(_ ptr: IRValue, index: Int, name: String = "") -> IRValue {
1953+
return LLVMBuildStructGEP(llvm, ptr.asLLVM(), UInt32(index), name)
1954+
}
1955+
1956+
/// Build a GEP (Get Element Pointer) instruction.
1957+
///
1958+
/// The `GEP` instruction is often the source of confusion. LLVM [provides a
1959+
/// document](http://llvm.org/docs/GetElementPtr.html) to answer questions
1960+
/// around its semantics and correct usage.
1961+
///
1962+
/// - parameter ptr: The base address for the index calculation.
1963+
/// - parameter indices: A list of indices that indicate which of the elements
1964+
/// of the aggregate object are indexed.
1965+
/// - parameter name: The name for the newly inserted instruction.
1966+
///
1967+
/// - returns: A value representing the address of a subelement of the given
1968+
/// aggregate data structure value.
1969+
@available(*, deprecated, message: "Use buildGEP(_:type:indices:name) instead")
1970+
public func buildGEP(_ ptr: IRValue, indices: [IRValue], name: String = "") -> IRValue {
1971+
var vals = indices.map { $0.asLLVM() as Optional }
1972+
return vals.withUnsafeMutableBufferPointer { buf in
1973+
return LLVMBuildGEP(llvm, ptr.asLLVM(), buf.baseAddress, UInt32(buf.count), name)
1974+
}
1975+
}
1976+
1977+
/// Build a `GEP` (Get Element Pointer) instruction with a resultant value
1978+
/// that is undefined if the address is outside the actual underlying
1979+
/// allocated object and not the address one-past-the-end.
1980+
///
1981+
/// The `GEP` instruction is often the source of confusion. LLVM [provides a
1982+
/// document](http://llvm.org/docs/GetElementPtr.html) to answer questions
1983+
/// around its semantics and correct usage.
1984+
///
1985+
/// - parameter ptr: The base address for the index calculation.
1986+
/// - parameter indices: A list of indices that indicate which of the elements
1987+
/// of the aggregate object are indexed.
1988+
/// - parameter name: The name for the newly inserted instruction.
1989+
///
1990+
/// - returns: A value representing the address of a subelement of the given
1991+
/// aggregate data structure value.
1992+
@available(*, deprecated, message: "Use buildInBoundsGEP(_:type:indices:name) instead")
1993+
public func buildInBoundsGEP(_ ptr: IRValue, indices: [IRValue], name: String = "") -> IRValue {
1994+
var vals = indices.map { $0.asLLVM() as Optional }
1995+
return vals.withUnsafeMutableBufferPointer { buf in
1996+
return LLVMBuildInBoundsGEP(llvm, ptr.asLLVM(), buf.baseAddress, UInt32(buf.count), name)
1997+
}
1998+
}
1999+
}
2000+
19962001

19972002
private func lowerVector(_ type: IRType) -> IRType {
19982003
guard let vectorType = type as? VectorType else {

Tests/LLVMTests/BFC.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ private func compileProgramBody(
247247
let flushExtern = Externs.flush.resolve(builder)
248248

249249
var addressPointer: IRValue = cellTape.constGEP(indices: [
250-
IntType.int32.zero(),
251-
IntType.int32.zero()
250+
IntType.int32.zero(), // (*self)
251+
IntType.int32.zero() // [0]
252252
])
253253

254254
/// Create an artificial typedef and variable for the current
@@ -291,23 +291,23 @@ private func compileProgramBody(
291291
switch c {
292292
case ">":
293293
// Move right
294-
addressPointer = builder.buildGEP(addressPointer, indices: [ IntType.int32.constant(1) ])
294+
addressPointer = builder.buildGEP(addressPointer, type: cellTapeType, indices: [ IntType.int32.constant(1) ])
295295
builder.currentDebugLocation = dibuilder.buildDebugLocation(at: (sourceLine, sourceColumn), in: scope)
296296
dibuilder.buildDbgValue(of: addressPointer, to: diVariable,
297297
atEndOf: builder.insertBlock!,
298298
expr: dibuilder.buildExpression([.deref]),
299299
location: builder.currentDebugLocation!)
300300
case "<":
301301
// Move left
302-
addressPointer = builder.buildGEP(addressPointer, indices: [ IntType.int32.constant(-1) ])
302+
addressPointer = builder.buildGEP(addressPointer, type: cellTapeType, indices: [ IntType.int32.constant(-1) ])
303303
builder.currentDebugLocation = dibuilder.buildDebugLocation(at: (sourceLine, sourceColumn), in: scope)
304304
dibuilder.buildDbgValue(of: addressPointer, to: diVariable,
305305
atEndOf: builder.insertBlock!,
306306
expr: dibuilder.buildExpression([.deref]),
307307
location: builder.currentDebugLocation!)
308308
case "+":
309309
// Increment
310-
let value = builder.buildLoad(addressPointer)
310+
let value = builder.buildLoad(addressPointer, type: cellType)
311311
let ptrUp = builder.buildAdd(value, cellType.constant(1))
312312
builder.buildStore(ptrUp, to: addressPointer)
313313
builder.currentDebugLocation = dibuilder.buildDebugLocation(at: (sourceLine, sourceColumn), in: scope)
@@ -317,7 +317,7 @@ private func compileProgramBody(
317317
location: builder.currentDebugLocation!)
318318
case "-":
319319
// Decrement
320-
let value = builder.buildLoad(addressPointer)
320+
let value = builder.buildLoad(addressPointer, type: cellType)
321321
let ptrDown = builder.buildSub(value, cellType.constant(1))
322322
builder.buildStore(ptrDown, to: addressPointer)
323323
builder.currentDebugLocation = dibuilder.buildDebugLocation(at: (sourceLine, sourceColumn), in: scope)
@@ -327,7 +327,7 @@ private func compileProgramBody(
327327
location: builder.currentDebugLocation!)
328328
case ".":
329329
// Write
330-
let dataValue = builder.buildLoad(addressPointer)
330+
let dataValue = builder.buildLoad(addressPointer, type: cellType)
331331
_ = builder.buildCall(putCharExtern, args: [dataValue])
332332
builder.currentDebugLocation = dibuilder.buildDebugLocation(at: (sourceLine, sourceColumn), in: scope)
333333
case ",":
@@ -343,7 +343,7 @@ private func compileProgramBody(
343343
let loopExit = function.appendBasicBlock(named: "exit")
344344

345345
// If zero
346-
let cond = builder.buildIsNotNull(builder.buildLoad(addressPointer))
346+
let cond = builder.buildIsNotNull(builder.buildLoad(addressPointer, type: cellType))
347347
builder.buildCondBr(condition: cond, then: loopBody, else: loopExit)
348348

349349
// Build a PHI for any address pointer changes in the exit block.
@@ -387,7 +387,7 @@ private func compileProgramBody(
387387
loop.exitDestination.addIncoming([ (addressPointer, builder.insertBlock!) ])
388388

389389
// If not zero.
390-
let cond = builder.buildIsNotNull(builder.buildLoad(addressPointer))
390+
let cond = builder.buildIsNotNull(builder.buildLoad(addressPointer, type: cellType))
391391
builder.buildCondBr(condition: cond, then: loop.body, else: loop.exit)
392392

393393
// Move the exit block after the loop body.

0 commit comments

Comments
 (0)