Skip to content

Add (constant) Select #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2017
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
33 changes: 33 additions & 0 deletions Sources/LLVM/Constant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -487,4 +487,37 @@ extension Constant where Repr: IntegralConstantRepresentation {

return Constant(llvm: LLVMConstXor(lhs.llvm, rhs.llvm))
}

// MARK: Bitshifting Operations

/// A constant left-shift of the first value by the second amount.
///
/// - parameter lhs: The first operand.
/// - parameter rhs: The second operand.
///
/// - returns: A constant value representing the value of the first operand
/// shifted left by the number of bits specified in the second operand.
public static func <<(lhs: Constant, rhs: Constant) -> Constant {
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")

return Constant(llvm: LLVMConstShl(lhs.llvm, rhs.llvm))
}


// MARK: Conditional Operations

/// A constant select using the given condition to select among two values.
///
/// - parameter cond: The condition to evaluate. It must have type `i1` or
/// be a vector of `i1`.
/// - parameter then: The value to select if the given condition is true.
/// - parameter else: The value to select if the given condition is false.
///
/// - returns: A constant value representing the constant value selected for
/// by the condition.
public static func select<T: ConstantRepresentation>(_ cond: Constant, then: Constant<T>, else: Constant<T>) -> Constant<T> {
precondition(then.repr == `else`.repr, "Mixed-representation constant operations are disallowed")

return Constant<T>(llvm: LLVMConstSelect(cond.llvm, then.llvm, `else`.llvm))
}
}
38 changes: 31 additions & 7 deletions Sources/LLVM/IRBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ public class IRBuilder {
}
}

// MARK: Declaration Instructions
// MARK: Conditional Instructions

/// Build a phi node with the given type acting as the result of any incoming
/// basic blocks.
Expand All @@ -760,14 +760,26 @@ public class IRBuilder {
return PhiNode(llvm: value)
}

/// Build a named function body with the given type.
/// Build a select instruction to choose a value based on a condition without
/// IR-level branching.
///
/// - parameter name: The name of the newly defined function.
/// - parameter type: The type of the newly defined function.
/// - parameter cond: The condition to evaluate. It must have type `i1` or
/// be a vector of `i1`.
/// - parameter then: The value to select if the given condition is true.
/// - parameter else: The value to select if the given condition is false.
/// - parameter name: The name for the newly inserted instruction.
///
/// - returns: A value representing the newly inserted function definition.
public func addFunction(_ name: String, type: FunctionType) -> Function {
return Function(llvm: LLVMAddFunction(module.llvm, name, type.asLLVM()))
/// - returns: A value representing the value selected for by the condition.
public func buildSelect(_ cond: IRValue, then: IRValue, else: IRValue, name: String = "") -> IRValue {
if let ty = cond.type as? IntType {
precondition(ty.width == 1, "Switch statement condition must have bitwidth of 1, instead has bitwidth of \(ty.width)")
return LLVMBuildSelect(llvm, cond.asLLVM(), then.asLLVM(), `else`.asLLVM(), name)
} else if let ty = cond.type as? VectorType, let intTy = ty.elementType as? IntType {
precondition(intTy.width == 1, "Switch statement condition must have bitwidth of 1, instead has bitwidth of \(intTy.width)")
return LLVMBuildSelect(llvm, cond.asLLVM(), then.asLLVM(), `else`.asLLVM(), name)
} else {
fatalError("Condition must have type i1 or <i1 x N>")
}
}

/// Build a branch table that branches on the given value with the given
Expand All @@ -790,6 +802,18 @@ public class IRBuilder {
UInt32(caseCount))!)
}

// MARK: Declaration Instructions

/// Build a named function body with the given type.
///
/// - parameter name: The name of the newly defined function.
/// - parameter type: The type of the newly defined function.
///
/// - returns: A value representing the newly inserted function definition.
public func addFunction(_ name: String, type: FunctionType) -> Function {
return Function(llvm: LLVMAddFunction(module.llvm, name, type.asLLVM()))
}

/// Build a named structure definition.
///
/// - parameter name: The name of the structure.
Expand Down