Skip to content

Commit cddd297

Browse files
authored
Merge pull request #70 from CodaFi/race-to-the-finish
Finish up the builder's instructions
2 parents 52bf103 + fd9afe6 commit cddd297

File tree

5 files changed

+343
-14
lines changed

5 files changed

+343
-14
lines changed

Sources/LLVM/IRBuilder.swift

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,35 @@ public class IRBuilder {
421421
}
422422
}
423423

424+
// MARK: Convenience Instructions
425+
426+
/// Builds the specified binary operation instruction with the given arguments.
427+
///
428+
/// - parameter op: The operation to build.
429+
/// - parameter lhs: The first operand.
430+
/// - parameter rhs: The second operand.
431+
/// - parameter name: The name for the newly inserted instruction.
432+
///
433+
/// - returns: A value representing the result of perfomring the given binary
434+
/// operation with the given values as arguments.
435+
public func buildBinaryOperation(_ op: OpCode.Binary, _ lhs: IRValue, _ rhs: IRValue, name: String = "") -> IRValue {
436+
return LLVMBuildBinOp(llvm, op.llvm, lhs.asLLVM(), rhs.asLLVM(), name)
437+
}
438+
439+
/// Builds the specified cast operation instruction with the given value and
440+
/// destination type.
441+
///
442+
/// - parameter op: The cast operation to build.
443+
/// - parameter value: The value to cast.
444+
/// - parameter type: The destination type to cast to.
445+
/// - parameter name: The name for the newly inserted instruction.
446+
///
447+
/// - returns: A value representing the result of casting the given value to
448+
/// the given destination type using the given operation.
449+
public func buildCast(_ op: OpCode.Cast, value: IRValue, type: IRType, name: String = "") -> IRValue {
450+
return LLVMBuildCast(llvm, op.llvm, value.asLLVM(), type.asLLVM(), name)
451+
}
452+
424453
// MARK: Arithmetic Instructions
425454

426455
/// Builds a negation instruction with the given value as an operand.
@@ -432,7 +461,7 @@ public class IRBuilder {
432461
/// - parameter value: The value to negate.
433462
/// - parameter overflowBehavior: Should overflow occur, specifies the
434463
/// behavior of the program.
435-
/// - name: The name for the newly inserted instruction.
464+
/// - parameter name: The name for the newly inserted instruction.
436465
///
437466
/// - returns: A value representing the negation of the given value.
438467
public func buildNeg(_ value: IRValue,
@@ -1035,6 +1064,21 @@ public class IRBuilder {
10351064
public func buildResume(_ val: IRValue) -> IRValue {
10361065
return LLVMBuildResume(llvm, val.asLLVM())
10371066
}
1067+
1068+
/// Build a `va_arg` instruction to access arguments passed through the
1069+
/// "variable argument" area of a function call.
1070+
///
1071+
/// This instruction is used to implement the `va_arg` macro in C.
1072+
///
1073+
/// - parameter list: A value of type `va_list*`
1074+
/// - parameter type: The type of values in the variable argument area.
1075+
/// - parameter name: The name for the newly inserted instruction.
1076+
///
1077+
/// - returns: A value of the specified argument type. In addition, the
1078+
/// `va_list` pointer is incremented to point to the next argument.
1079+
public func buildVAArg(_ list: IRValue, type: IRType, name: String = "") -> IRValue {
1080+
return LLVMBuildVAArg(llvm, list.asLLVM(), type.asLLVM(), name)
1081+
}
10381082

10391083
// MARK: Memory Access Instructions
10401084

@@ -1126,18 +1170,6 @@ public class IRBuilder {
11261170
return LLVMBuildStructGEP(llvm, ptr.asLLVM(), UInt32(index), name)
11271171
}
11281172

1129-
/// Builds an ExtractElement instruction to retrieve an indexed value from a
1130-
/// vector value.
1131-
///
1132-
/// - parameter vec: The vector you're indexing into.
1133-
/// - parameter index: The index at which to extract.
1134-
///
1135-
/// - returns: The value in the vector at the provided index.
1136-
public func buildExtractElement(_ vec: IRValue, index: IRValue,
1137-
name: String = "") -> IRValue {
1138-
return LLVMBuildExtractElement(llvm, vec.asLLVM(), index.asLLVM(), name)
1139-
}
1140-
11411173
/// Builds an ExtractValue instruction to retrieve an indexed value from a
11421174
/// struct or array value.
11431175
///
@@ -1191,6 +1223,19 @@ public class IRBuilder {
11911223
return LLVMBuildTruncOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
11921224
}
11931225

1226+
/// Builds an instruction that either performs a zero extension or a bitcast of
1227+
/// the given value to a value of the given type with a wider width.
1228+
///
1229+
/// - parameter val: The value to zero extend.
1230+
/// - parameter type: The destination type.
1231+
/// - parameter name: The name for the newly inserted instruction.
1232+
///
1233+
/// - returns: A value representing the result of zero extending or bitcasting
1234+
/// the given value to fit the given type.
1235+
public func buildZExtOrBitCast(_ val: IRValue, type: IRType, name: String = "") -> IRValue {
1236+
return LLVMBuildZExtOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
1237+
}
1238+
11941239
/// Builds a bitcast instruction to convert the given value to a value of the
11951240
/// given type by just copying the bit pattern.
11961241
///
@@ -1552,6 +1597,24 @@ public class IRBuilder {
15521597
return LLVMBuildExtractElement(llvm, vector.asLLVM(), index.asLLVM(), name)
15531598
}
15541599

1600+
/// Builds a vector shuffle instruction to construct a permutation of elements
1601+
/// from the two given input vectors, returning a vector with the same element
1602+
/// type as the inputs and length that is the same as the shuffle mask.
1603+
///
1604+
/// - parameter vector1: The first vector to shuffle.
1605+
/// - parameter vector2: The second vector to shuffle.
1606+
/// - parameter mask: A constant vector of `i32` values that acts as a mask
1607+
/// for the shuffled vectors.
1608+
///
1609+
/// - returns: A value representing a vector with the same element type as the
1610+
/// inputs and length that is the same as the shuffle mask.
1611+
public func buildShuffleVector(_ vector1: IRValue, and vector2: IRValue, mask: IRValue, name: String = "") -> IRValue {
1612+
guard let maskTy = mask.type as? VectorType, maskTy.elementType is IntType else {
1613+
fatalError("Vector shuffle mask's elements must be 32-bit integers")
1614+
}
1615+
return LLVMBuildShuffleVector(llvm, vector1.asLLVM(), vector2.asLLVM(), mask.asLLVM(), name)
1616+
}
1617+
15551618
// MARK: Global Variable Instructions
15561619

15571620
/// Build a named global of the given type.

Sources/LLVM/OpCode.swift

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,110 @@ public enum OpCode {
227227
}
228228
}
229229
}
230+
231+
extension OpCode {
232+
/// `BinaryOperation` enumerates the subset of opcodes that are binary operations.
233+
public enum Binary {
234+
/// The `add` instruction.
235+
case add
236+
/// The `fadd` instruction.
237+
case fadd
238+
/// The `sub` instruction.
239+
case sub
240+
/// The `fsub` instruction.
241+
case fsub
242+
/// The `mul` instruction.
243+
case mul
244+
/// The `fmul` instruction.
245+
case fmul
246+
/// The `udiv` instruction.
247+
case udiv
248+
/// The `sdiv` instruction.
249+
case sdiv
250+
/// The `fdiv` instruction.
251+
case fdiv
252+
/// The `urem` instruction.
253+
case urem
254+
/// The `srem` instruction.
255+
case srem
256+
/// The `frem` instruction.
257+
case frem
258+
259+
/// The `shl` instruction.
260+
case shl
261+
/// The `lshr` instruction.
262+
case lshr
263+
/// The `ashr` instruction.
264+
case ashr
265+
/// The `and` instruction.
266+
case and
267+
/// The `or` instruction.
268+
case or
269+
/// The `xor` instruction.
270+
case xor
271+
272+
static let binaryOperationMap: [Binary: LLVMOpcode] = [
273+
.add: LLVMAdd, .fadd: LLVMFAdd, .sub: LLVMSub, .fsub: LLVMFSub,
274+
.mul: LLVMMul, .fmul: LLVMFMul, .udiv: LLVMUDiv, .sdiv: LLVMSDiv,
275+
.fdiv: LLVMFDiv, .urem: LLVMURem, .srem: LLVMSRem, .frem: LLVMFRem,
276+
.shl: LLVMShl, .lshr: LLVMLShr, .ashr: LLVMAShr, .and: LLVMAnd,
277+
.or: LLVMOr, .xor: LLVMXor,
278+
]
279+
280+
/// Retrieves the corresponding `LLVMOpcode`.
281+
public var llvm: LLVMOpcode {
282+
return Binary.binaryOperationMap[self]!
283+
}
284+
}
285+
286+
/// `CastOperation` enumerates the subset of opcodes that are cast operations.
287+
public enum Cast {
288+
/// The `trunc` instruction.
289+
case trunc
290+
/// The `zext` instruction.
291+
case zext
292+
/// The `sext` instruction.
293+
case sext
294+
/// The `fpToUI` instruction.
295+
case fpToUI
296+
/// The `fpToSI` instruction.
297+
case fpToSI
298+
/// The `uiToFP` instruction.
299+
case uiToFP
300+
/// The `siToFP` instruction.
301+
case siToFP
302+
/// The `fpTrunc` instruction.
303+
case fpTrunc
304+
/// The `fpext` instruction.
305+
case fpext
306+
/// The `ptrToInt` instruction.
307+
case ptrToInt
308+
/// The `intToPtr` instruction.
309+
case intToPtr
310+
/// The `bitCast` instruction.
311+
case bitCast
312+
/// The `addrSpaceCast` instruction.
313+
case addrSpaceCast
314+
315+
static let castOperationMap: [Cast: LLVMOpcode] = [
316+
.trunc: LLVMTrunc,
317+
.zext: LLVMZExt,
318+
.sext: LLVMSExt,
319+
.fpToUI: LLVMFPToUI,
320+
.fpToSI: LLVMFPToSI,
321+
.uiToFP: LLVMUIToFP,
322+
.siToFP: LLVMSIToFP,
323+
.fpTrunc: LLVMFPTrunc,
324+
.fpext: LLVMFPExt,
325+
.ptrToInt: LLVMPtrToInt,
326+
.intToPtr: LLVMIntToPtr,
327+
.bitCast: LLVMBitCast,
328+
.addrSpaceCast: LLVMAddrSpaceCast,
329+
]
330+
331+
/// Retrieves the corresponding `LLVMOpcode`.
332+
public var llvm: LLVMOpcode {
333+
return Cast.castOperationMap[self]!
334+
}
335+
}
336+
}

Tests/LLVMTests/FileCheck.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ private struct CheckString {
11671167
}
11681168

11691169
// Re-calc it as the offset relative to the start of the original string.
1170-
var matchPos = range.location + startPos
1170+
let matchPos = range.location + startPos
11711171
if !notStrings.isEmpty {
11721172
if matchPos < lastPos {
11731173
// Reordered?

0 commit comments

Comments
 (0)