Skip to content
Draft
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
6 changes: 4 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"sswg.swift-lang"
"sswg.swift-lang",
"swiftlang.swift-vscode"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
"containerEnv": {
"HYLO_LLVM_BUILD_TYPE": "${localEnv:HYLO_LLVM_BUILD_TYPE:MinSizeRel}"
"HYLO_LLVM_BUILD_TYPE": "${localEnv:HYLO_LLVM_BUILD_TYPE:MinSizeRel}",
"HYLO_USE_BUILTIN_STDLIB": "true" // point standard library diagnostics to the sources
},
"remoteEnv": {
"PATH": "/opt/llvm-${containerEnv:HYLO_LLVM_BUILD_TYPE}/bin:${containerEnv:PATH}"
Expand Down
37 changes: 23 additions & 14 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let package = Package(
branch: "main"),
.package(
url: "https://github.com/apple/swift-format",
from: "508.0.1"),
from: "510.1.0"),
.package(
url: "https://github.com/SwiftPackageIndex/SPIManifest.git",
from: "0.12.0"),
Expand Down
2 changes: 2 additions & 0 deletions Sources/CodeGen/LLVM/ConcreteTypeLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct ConcreteTypeLayout {
self.init(size: 8, alignment: 8)
case .float128:
self.init(size: 16, alignment: 8)
case .cNumeric(let cType):
self.init(size: cType.size, alignment: cType.alignment)
case .module:
notLLVMRepresentable(^t)
}
Expand Down
166 changes: 122 additions & 44 deletions Sources/CodeGen/LLVM/Transpilation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import IR
import SwiftyLLVM
import Utils

fileprivate extension SwiftyLLVM.OverflowBehavior {
extension SwiftyLLVM.OverflowBehavior {

/// An instance equivalent to `x`
init(_ x: FrontEnd.OverflowBehavior) {
fileprivate init(_ x: FrontEnd.OverflowBehavior) {
switch x {
case .ignore: self = .ignore
case .nsw: self = .nsw
Expand All @@ -17,10 +17,10 @@ fileprivate extension SwiftyLLVM.OverflowBehavior {

}

fileprivate extension SwiftyLLVM.IntegerPredicate {
extension SwiftyLLVM.IntegerPredicate {

/// An instance equivalent to `x`
init(_ x: FrontEnd.IntegerPredicate) {
fileprivate init(_ x: FrontEnd.IntegerPredicate) {
switch x {
case .eq: self = .eq
case .slt: self = .slt
Expand All @@ -37,10 +37,10 @@ fileprivate extension SwiftyLLVM.IntegerPredicate {

}

fileprivate extension SwiftyLLVM.FloatingPointPredicate {
extension SwiftyLLVM.FloatingPointPredicate {

/// An instance equivalent to `x`
init(_ x: FrontEnd.FloatingPointPredicate) {
fileprivate init(_ x: FrontEnd.FloatingPointPredicate) {
switch x {
case .alwaysFalse: self = .alwaysFalse
case .alwaysTrue: self = .alwaysTrue
Expand Down Expand Up @@ -121,11 +121,12 @@ extension SwiftyLLVM.Module {

// Get the declaraiton of LLVM function corresponding to `f`. It is possible that this function
// has already been declared if it is referred to by some code that was transpiled first.
let transpilation = if context.source[f].isSubscript {
declareSubscript(transpiledFrom: f, in: &context)
} else {
declareFunction(transpiledFrom: f, in: &context)
}
let transpilation =
if context.source[f].isSubscript {
declareSubscript(transpiledFrom: f, in: &context)
} else {
declareFunction(transpiledFrom: f, in: &context)
}

transpile(contentsOf: f, into: transpilation.function, inContext: &context)
if f == context.source.entryFunction {
Expand Down Expand Up @@ -1126,6 +1127,15 @@ extension SwiftyLLVM.Module {
let source = llvm(s.operands[0])
register[.register(i)] = insertPtrToInt(source, to: target, at: insertionPoint)

case .fromcint(let cIntType, let targetType):
insertTruncateOrExtend(
sourceType: .cNumeric(cIntType), targetType: targetType, sourceValue: llvm(s.operands[0]),
isSourceTypeSigned: cIntType.signedInteger, for: i)
case .tocint(let hyloIntegerType, let targetCType, let sourceTypeSigned):
insertTruncateOrExtend(
sourceType: hyloIntegerType, targetType: .cNumeric(targetCType),
sourceValue: llvm(s.operands[0]),
isSourceTypeSigned: sourceTypeSigned, for: i)
case .fadd:
let l = llvm(s.operands[0])
let r = llvm(s.operands[1])
Expand Down Expand Up @@ -1456,94 +1466,130 @@ extension SwiftyLLVM.Module {
insert(atomicRMW: .xor, ordering: .sequentiallyConsistent, for: i)

case .atomic_cmpxchg_relaxed_relaxed:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .monotonic, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .monotonic, weak: false, for: i)

case .atomic_cmpxchg_relaxed_acquire:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .acquire, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .acquire, weak: false, for: i)

case .atomic_cmpxchg_relaxed_seqcst:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .sequentiallyConsistent, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .sequentiallyConsistent, weak: false, for: i
)

case .atomic_cmpxchg_acquire_relaxed:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .monotonic, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .monotonic, weak: false, for: i)

case .atomic_cmpxchg_acquire_acquire:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .acquire, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .acquire, weak: false, for: i)

case .atomic_cmpxchg_acquire_seqcst:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .sequentiallyConsistent, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .sequentiallyConsistent, weak: false, for: i)

case .atomic_cmpxchg_release_relaxed:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .monotonic, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .monotonic, weak: false, for: i)

case .atomic_cmpxchg_release_acquire:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .acquire, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .acquire, weak: false, for: i)

case .atomic_cmpxchg_release_seqcst:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .sequentiallyConsistent, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .sequentiallyConsistent, weak: false, for: i)

case .atomic_cmpxchg_acqrel_relaxed:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .monotonic, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .monotonic, weak: false, for: i)

case .atomic_cmpxchg_acqrel_acquire:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .acquire, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .acquire, weak: false, for: i)

case .atomic_cmpxchg_acqrel_seqcst:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .sequentiallyConsistent, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .sequentiallyConsistent, weak: false,
for: i)

case .atomic_cmpxchg_seqcst_relaxed:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .monotonic, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .monotonic, weak: false, for: i
)

case .atomic_cmpxchg_seqcst_acquire:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .acquire, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .acquire, weak: false, for: i)

case .atomic_cmpxchg_seqcst_seqcst:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .sequentiallyConsistent, weak: false, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .sequentiallyConsistent,
weak: false, for: i)

case .atomic_cmpxchgweak_relaxed_relaxed:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .monotonic, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .monotonic, weak: true, for: i)

case .atomic_cmpxchgweak_relaxed_acquire:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .acquire, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .acquire, weak: true, for: i)

case .atomic_cmpxchgweak_relaxed_seqcst:
insertAtomicCompareExchange(successOrdering: .monotonic, failureOrdering: .sequentiallyConsistent, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .monotonic, failureOrdering: .sequentiallyConsistent, weak: true, for: i)

case .atomic_cmpxchgweak_acquire_relaxed:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .monotonic, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .monotonic, weak: true, for: i)

case .atomic_cmpxchgweak_acquire_acquire:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .acquire, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .acquire, weak: true, for: i)

case .atomic_cmpxchgweak_acquire_seqcst:
insertAtomicCompareExchange(successOrdering: .acquire, failureOrdering: .sequentiallyConsistent, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquire, failureOrdering: .sequentiallyConsistent, weak: true, for: i)

case .atomic_cmpxchgweak_release_relaxed:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .monotonic, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .monotonic, weak: true, for: i)

case .atomic_cmpxchgweak_release_acquire:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .acquire, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .acquire, weak: true, for: i)

case .atomic_cmpxchgweak_release_seqcst:
insertAtomicCompareExchange(successOrdering: .release, failureOrdering: .sequentiallyConsistent, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .release, failureOrdering: .sequentiallyConsistent, weak: true, for: i)

case .atomic_cmpxchgweak_acqrel_relaxed:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .monotonic, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .monotonic, weak: true, for: i)

case .atomic_cmpxchgweak_acqrel_acquire:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .acquire, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .acquire, weak: true, for: i)

case .atomic_cmpxchgweak_acqrel_seqcst:
insertAtomicCompareExchange(successOrdering: .acquireRelease, failureOrdering: .sequentiallyConsistent, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .acquireRelease, failureOrdering: .sequentiallyConsistent, weak: true,
for: i)

case .atomic_cmpxchgweak_seqcst_relaxed:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .monotonic, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .monotonic, weak: true, for: i)

case .atomic_cmpxchgweak_seqcst_acquire:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .acquire, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .acquire, weak: true, for: i)

case .atomic_cmpxchgweak_seqcst_seqcst:
insertAtomicCompareExchange(successOrdering: .sequentiallyConsistent, failureOrdering: .sequentiallyConsistent, weak: true, for: i)
insertAtomicCompareExchange(
successOrdering: .sequentiallyConsistent, failureOrdering: .sequentiallyConsistent,
weak: true, for: i)

case .atomic_fence_acquire:
insertAtomicFence(.acquire, singleThread: false, for: i)
Expand Down Expand Up @@ -1578,12 +1624,17 @@ extension SwiftyLLVM.Module {
let s = context.source[i] as! IR.CallBuiltinFunction
let target = llvm(s.operands[0])
let value = llvm(s.operands[1])
let o = insertAtomicRMW(target, operation: oper, value: value, ordering: ordering, singleThread: false, at: insertionPoint)
let o = insertAtomicRMW(
target, operation: oper, value: value, ordering: ordering, singleThread: false,
at: insertionPoint)
register[.register(i)] = o
}

/// Inserts the transpilation of `i` at `insertionPoint`.
func insertAtomicCompareExchange(successOrdering: AtomicOrdering, failureOrdering: AtomicOrdering, weak: Bool, for i: IR.InstructionID) {
func insertAtomicCompareExchange(
successOrdering: AtomicOrdering, failureOrdering: AtomicOrdering, weak: Bool,
for i: IR.InstructionID
) {
let s = context.source[i] as! IR.CallBuiltinFunction
let target = llvm(s.operands[0])
let old = llvm(s.operands[1])
Expand All @@ -1601,11 +1652,38 @@ extension SwiftyLLVM.Module {
}

/// Inserts the transpilation of `i` at `insertionPoint`.
func insertAtomicFence(_ ordering: AtomicOrdering, singleThread: Bool, for i: IR.InstructionID) {
func insertAtomicFence(_ ordering: AtomicOrdering, singleThread: Bool, for i: IR.InstructionID)
{
insertFence(ordering, singleThread: singleThread, at: insertionPoint)
register[.register(i)] = ptr.null
}

/// Inserts a truncation/extension from source to target type.
func insertTruncateOrExtend(
sourceType: BuiltinType, targetType: BuiltinType, sourceValue: IRValue,
isSourceTypeSigned: Bool,
for i: IR.InstructionID
) {

let targetLLVMType = context.ir.llvm(builtinType: targetType, in: &self)
let sourceTypeSize = ConcreteTypeLayout(of: sourceType, forUseIn: &self)
let targetTypeSize = ConcreteTypeLayout(of: targetType, forUseIn: &self)

if sourceTypeSize.size == targetTypeSize.size {
// just copy the value
register[.register(i)] = sourceValue
} else if sourceTypeSize.size > targetTypeSize.size {
// Truncate the value. Negative values are correctly truncated also due to two's complement.
register[.register(i)] = insertTrunc(sourceValue, to: targetLLVMType, at: insertionPoint)
} else if isSourceTypeSigned {
register[.register(i)] = insertSignExtend(
sourceValue, to: targetLLVMType, at: insertionPoint)
} else {
register[.register(i)] = insertZeroExtend(
sourceValue, to: targetLLVMType, at: insertionPoint)
}
}

/// Inserts the transpilation of `i` at `insertionPoint`.
func insert(load i: IR.InstructionID) {
let s = context.source[i] as! Load
Expand Down
Loading
Loading