Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 76 additions & 13 deletions Sources/LLVM/IRBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,35 @@ public class IRBuilder {
}
}

// MARK: Convenience Instructions

/// Builds the specified binary operation instruction with the given arguments.
///
/// - parameter op: The operation to build.
/// - parameter lhs: The first operand.
/// - parameter rhs: The second operand.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the result of perfomring the given binary
/// operation with the given values as arguments.
public func buildBinaryOperation(_ op: OpCode.Binary, _ lhs: IRValue, _ rhs: IRValue, name: String = "") -> IRValue {
return LLVMBuildBinOp(llvm, op.llvm, lhs.asLLVM(), rhs.asLLVM(), name)
}

/// Builds the specified cast operation instruction with the given value and
/// destination type.
///
/// - parameter op: The cast operation to build.
/// - parameter value: The value to cast.
/// - parameter type: The destination type to cast to.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the result of casting the given value to
/// the given destination type using the given operation.
public func buildCast(_ op: OpCode.Cast, value: IRValue, type: IRType, name: String = "") -> IRValue {
return LLVMBuildCast(llvm, op.llvm, value.asLLVM(), type.asLLVM(), name)
}

// MARK: Arithmetic Instructions

/// Builds a negation instruction with the given value as an operand.
Expand All @@ -432,7 +461,7 @@ public class IRBuilder {
/// - parameter value: The value to negate.
/// - parameter overflowBehavior: Should overflow occur, specifies the
/// behavior of the program.
/// - name: The name for the newly inserted instruction.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the negation of the given value.
public func buildNeg(_ value: IRValue,
Expand Down Expand Up @@ -1035,6 +1064,21 @@ public class IRBuilder {
public func buildResume(_ val: IRValue) -> IRValue {
return LLVMBuildResume(llvm, val.asLLVM())
}

/// Build a `va_arg` instruction to access arguments passed through the
/// "variable argument" area of a function call.
///
/// This instruction is used to implement the `va_arg` macro in C.
///
/// - parameter list: A value of type `va_list*`
/// - parameter type: The type of values in the variable argument area.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value of the specified argument type. In addition, the
/// `va_list` pointer is incremented to point to the next argument.
public func buildVAArg(_ list: IRValue, type: IRType, name: String = "") -> IRValue {
return LLVMBuildVAArg(llvm, list.asLLVM(), type.asLLVM(), name)
}

// MARK: Memory Access Instructions

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

/// Builds an ExtractElement instruction to retrieve an indexed value from a
/// vector value.
///
/// - parameter vec: The vector you're indexing into.
/// - parameter index: The index at which to extract.
///
/// - returns: The value in the vector at the provided index.
public func buildExtractElement(_ vec: IRValue, index: IRValue,
name: String = "") -> IRValue {
return LLVMBuildExtractElement(llvm, vec.asLLVM(), index.asLLVM(), name)
}

/// Builds an ExtractValue instruction to retrieve an indexed value from a
/// struct or array value.
///
Expand Down Expand Up @@ -1191,6 +1223,19 @@ public class IRBuilder {
return LLVMBuildTruncOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
}

/// Builds an instruction that either performs a zero extension or a bitcast of
/// the given value to a value of the given type with a wider width.
///
/// - parameter val: The value to zero extend.
/// - parameter type: The destination type.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the result of zero extending or bitcasting
/// the given value to fit the given type.
public func buildZExtOrBitCast(_ val: IRValue, type: IRType, name: String = "") -> IRValue {
return LLVMBuildZExtOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
}

/// Builds a bitcast instruction to convert the given value to a value of the
/// given type by just copying the bit pattern.
///
Expand Down Expand Up @@ -1552,6 +1597,24 @@ public class IRBuilder {
return LLVMBuildExtractElement(llvm, vector.asLLVM(), index.asLLVM(), name)
}

/// Builds a vector shuffle instruction to construct a permutation of elements
/// from the two given input vectors, returning a vector with the same element
/// type as the inputs and length that is the same as the shuffle mask.
///
/// - parameter vector1: The first vector to shuffle.
/// - parameter vector2: The second vector to shuffle.
/// - parameter mask: A constant vector of `i32` values that acts as a mask
/// for the shuffled vectors.
///
/// - returns: A value representing a vector with the same element type as the
/// inputs and length that is the same as the shuffle mask.
public func buildShuffleVector(_ vector1: IRValue, and vector2: IRValue, mask: IRValue, name: String = "") -> IRValue {
guard let maskTy = mask.type as? VectorType, maskTy.elementType is IntType else {
fatalError("Vector shuffle mask's elements must be 32-bit integers")
}
return LLVMBuildShuffleVector(llvm, vector1.asLLVM(), vector2.asLLVM(), mask.asLLVM(), name)
}

// MARK: Global Variable Instructions

/// Build a named global of the given type.
Expand Down
107 changes: 107 additions & 0 deletions Sources/LLVM/OpCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,110 @@ public enum OpCode {
}
}
}

extension OpCode {
/// `BinaryOperation` enumerates the subset of opcodes that are binary operations.
public enum Binary {
/// The `add` instruction.
case add
/// The `fadd` instruction.
case fadd
/// The `sub` instruction.
case sub
/// The `fsub` instruction.
case fsub
/// The `mul` instruction.
case mul
/// The `fmul` instruction.
case fmul
/// The `udiv` instruction.
case udiv
/// The `sdiv` instruction.
case sdiv
/// The `fdiv` instruction.
case fdiv
/// The `urem` instruction.
case urem
/// The `srem` instruction.
case srem
/// The `frem` instruction.
case frem

/// The `shl` instruction.
case shl
/// The `lshr` instruction.
case lshr
/// The `ashr` instruction.
case ashr
/// The `and` instruction.
case and
/// The `or` instruction.
case or
/// The `xor` instruction.
case xor

static let binaryOperationMap: [Binary: LLVMOpcode] = [
.add: LLVMAdd, .fadd: LLVMFAdd, .sub: LLVMSub, .fsub: LLVMFSub,
.mul: LLVMMul, .fmul: LLVMFMul, .udiv: LLVMUDiv, .sdiv: LLVMSDiv,
.fdiv: LLVMFDiv, .urem: LLVMURem, .srem: LLVMSRem, .frem: LLVMFRem,
.shl: LLVMShl, .lshr: LLVMLShr, .ashr: LLVMAShr, .and: LLVMAnd,
.or: LLVMOr, .xor: LLVMXor,
]

/// Retrieves the corresponding `LLVMOpcode`.
public var llvm: LLVMOpcode {
return Binary.binaryOperationMap[self]!
}
}

/// `CastOperation` enumerates the subset of opcodes that are cast operations.
public enum Cast {
/// The `trunc` instruction.
case trunc
/// The `zext` instruction.
case zext
/// The `sext` instruction.
case sext
/// The `fpToUI` instruction.
case fpToUI
/// The `fpToSI` instruction.
case fpToSI
/// The `uiToFP` instruction.
case uiToFP
/// The `siToFP` instruction.
case siToFP
/// The `fpTrunc` instruction.
case fpTrunc
/// The `fpext` instruction.
case fpext
/// The `ptrToInt` instruction.
case ptrToInt
/// The `intToPtr` instruction.
case intToPtr
/// The `bitCast` instruction.
case bitCast
/// The `addrSpaceCast` instruction.
case addrSpaceCast

static let castOperationMap: [Cast: LLVMOpcode] = [
.trunc: LLVMTrunc,
.zext: LLVMZExt,
.sext: LLVMSExt,
.fpToUI: LLVMFPToUI,
.fpToSI: LLVMFPToSI,
.uiToFP: LLVMUIToFP,
.siToFP: LLVMSIToFP,
.fpTrunc: LLVMFPTrunc,
.fpext: LLVMFPExt,
.ptrToInt: LLVMPtrToInt,
.intToPtr: LLVMIntToPtr,
.bitCast: LLVMBitCast,
.addrSpaceCast: LLVMAddrSpaceCast,
]

/// Retrieves the corresponding `LLVMOpcode`.
public var llvm: LLVMOpcode {
return Cast.castOperationMap[self]!
}
}
}
2 changes: 1 addition & 1 deletion Tests/LLVMTests/FileCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ private struct CheckString {
}

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