diff --git a/Package.swift b/Package.swift index e8f8c31f1..14fd0d5b1 100644 --- a/Package.swift +++ b/Package.swift @@ -17,6 +17,7 @@ let package = Package( .executable(name: "hc", targets: ["hc"]), .executable(name: "hylo-demangle", targets: ["hylo-demangle"]), .library(name: "Hylo", targets: ["Driver"]), + .library(name: "HyloFrontEnd", targets: ["FrontEnd"]), ], dependencies: [ @@ -87,7 +88,6 @@ let package = Package( dependencies: [ "Utils", .product(name: "Collections", package: "swift-collections"), - .product(name: "LLVM", package: "Swifty-LLVM"), ], swiftSettings: allTargetsSwiftSettings), diff --git a/Sources/CodeGen/LLVM/FloatingPointPredicate.swift b/Sources/CodeGen/LLVM/FloatingPointPredicate.swift new file mode 100644 index 000000000..06c3c38b6 --- /dev/null +++ b/Sources/CodeGen/LLVM/FloatingPointPredicate.swift @@ -0,0 +1,8 @@ +import LLVM +import Core + +extension LLVM.FloatingPointPredicate { + public init(_ p: Core.FloatingPointPredicate) { + self = LLVM.FloatingPointPredicate(rawValue: p.rawValue)! + } +} diff --git a/Sources/CodeGen/LLVM/IntegerPredicate.swift b/Sources/CodeGen/LLVM/IntegerPredicate.swift new file mode 100644 index 000000000..5ad4ba1ad --- /dev/null +++ b/Sources/CodeGen/LLVM/IntegerPredicate.swift @@ -0,0 +1,8 @@ +import LLVM +import Core + +extension LLVM.IntegerPredicate { + public init(_ p: Core.IntegerPredicate) { + self = LLVM.IntegerPredicate(rawValue: p.rawValue)! + } +} diff --git a/Sources/CodeGen/LLVM/OverflowBehavior.swift b/Sources/CodeGen/LLVM/OverflowBehavior.swift new file mode 100644 index 000000000..090a75902 --- /dev/null +++ b/Sources/CodeGen/LLVM/OverflowBehavior.swift @@ -0,0 +1,12 @@ +import LLVM +import Core + +extension LLVM.OverflowBehavior { + public init(_ ob: Core.OverflowBehavior) { + switch ob { + case .ignore: self = OverflowBehavior.ignore + case .nuw: self = OverflowBehavior.nuw + case .nsw: self = OverflowBehavior.nsw + } + } +} diff --git a/Sources/CodeGen/LLVM/Transpilation.swift b/Sources/CodeGen/LLVM/Transpilation.swift index 6ea2cb26c..915e29eb9 100644 --- a/Sources/CodeGen/LLVM/Transpilation.swift +++ b/Sources/CodeGen/LLVM/Transpilation.swift @@ -760,17 +760,17 @@ extension LLVM.Module { case .add(let p, _): let l = llvm(s.operands[0]) let r = llvm(s.operands[1]) - register[.register(i)] = insertAdd(overflow: p, l, r, at: insertionPoint) + register[.register(i)] = insertAdd(overflow: OverflowBehavior(p), l, r, at: insertionPoint) case .sub(let p, _): let l = llvm(s.operands[0]) let r = llvm(s.operands[1]) - register[.register(i)] = insertSub(overflow: p, l, r, at: insertionPoint) + register[.register(i)] = insertSub(overflow: OverflowBehavior(p), l, r, at: insertionPoint) case .mul(let p, _): let l = llvm(s.operands[0]) let r = llvm(s.operands[1]) - register[.register(i)] = insertMul(overflow: p, l, r, at: insertionPoint) + register[.register(i)] = insertMul(overflow: OverflowBehavior(p), l, r, at: insertionPoint) case .shl: let l = llvm(s.operands[0]) @@ -852,7 +852,7 @@ extension LLVM.Module { case .icmp(let p, _): let l = llvm(s.operands[0]) let r = llvm(s.operands[1]) - register[.register(i)] = insertIntegerComparison(p, l, r, at: insertionPoint) + register[.register(i)] = insertIntegerComparison(IntegerPredicate(p), l, r, at: insertionPoint) case .and(_): let l = llvm(s.operands[0]) @@ -916,7 +916,7 @@ extension LLVM.Module { case .fcmp(_, let p, _): let l = llvm(s.operands[0]) let r = llvm(s.operands[1]) - register[.register(i)] = insertFloatingPointComparison(p, l, r, at: insertionPoint) + register[.register(i)] = insertFloatingPointComparison(FloatingPointPredicate(p), l, r, at: insertionPoint) case .fptrunc(_, let t): let target = ir.llvm(builtinType: t, in: &self) diff --git a/Sources/Core/BuiltinFunction.swift b/Sources/Core/BuiltinFunction.swift index 0c2793213..9ff545c15 100644 --- a/Sources/Core/BuiltinFunction.swift +++ b/Sources/Core/BuiltinFunction.swift @@ -1,4 +1,3 @@ -import LLVM import Utils /// A function representing an IR instruction in Hylo source code. @@ -335,7 +334,7 @@ private func mathFlags(_ stream: inout ArraySlice) -> NativeInstructi } /// Returns an overflow behavior parsed from `stream` or `.ignore` if none can be parsed. -private func overflowBehavior(_ stream: inout ArraySlice) -> LLVM.OverflowBehavior { +private func overflowBehavior(_ stream: inout ArraySlice) -> OverflowBehavior { switch stream.first { case "nuw": stream.removeFirst() @@ -362,7 +361,7 @@ private let integerArithmeticTail = /// Parses the parameters and type of `icmp`. private let integerComparisonTail = - take(LLVM.IntegerPredicate.self) ++ builtinType + take(IntegerPredicate.self) ++ builtinType /// Parses the parameters and type of a floating-point arithmetic instruction. private let floatingPointArithmeticTail = @@ -370,4 +369,4 @@ private let floatingPointArithmeticTail = /// Parses the parameters and type of `fcmp`. private let floatingPointComparisonTail = - mathFlags ++ take(LLVM.FloatingPointPredicate.self) ++ builtinType + mathFlags ++ take(FloatingPointPredicate.self) ++ builtinType diff --git a/Sources/Core/FloatingPointPredicate.swift b/Sources/Core/FloatingPointPredicate.swift new file mode 100644 index 000000000..e11d35a61 --- /dev/null +++ b/Sources/Core/FloatingPointPredicate.swift @@ -0,0 +1,66 @@ +/// Copied from SwiftLLVM, used to remove LLVM dependency from Core + +/// The predicate of an integer comparison. +/// +/// - Note: Ordered means that neither operand is a QNAN while unordered means that either operand +/// may be a QNAN. +public enum FloatingPointPredicate: String, Hashable { + + /// No comparison; always false. + case alwaysFalse = "false" + + /// No comparison; always true. + case alwaysTrue = "true" + + /// Values are ordered and equal. + case oeq + + /// Values are ordered and not equal. + case one + + /// Values are ordered and LHS is greater than RHS. + case ogt + + /// Values are ordered and LHS greater than or equal to RHS. + case oge + + /// Values are ordered and LHS is less than RHS. + case olt + + /// Values are ordered and LHS is less than or equal to RHS. + case ole + + /// Values are ordered (no nans). + case ord + + /// Values are unordered or equal. + case ueq + + /// Values are unordered or not equal. + case une + + /// Values are unordered or LHS is greater than RHS. + case ugt + + /// Values are unordered or LHS is greater than or equal to RHS. + case uge + + /// Values are unordered or LHS is less than RHS. + case ult + + /// Values are unordered or LHS is less than or equal to RHS. + case ule + + /// Values are unordered (either nans). + case uno +} + +extension FloatingPointPredicate: LosslessStringConvertible { + + public init?(_ description: String) { + self.init(rawValue: description) + } + + public var description: String { self.rawValue } + +} diff --git a/Sources/Core/IntegerPredicate.swift b/Sources/Core/IntegerPredicate.swift new file mode 100644 index 000000000..c09352076 --- /dev/null +++ b/Sources/Core/IntegerPredicate.swift @@ -0,0 +1,46 @@ +/// Copied from SwiftLLVM, used to remove LLVM dependency from Core + +/// The predicate of an integer comparison. +public enum IntegerPredicate: String, Hashable { + + /// Values are equal. + case eq + + /// Values are not equal. + case ne + + /// LHS is greater than RHS, by unsigned comparison. + case ugt + + /// LHS is greater than or equal to RHS, by unsigned comparison. + case uge + + /// LHS is less than RHS, by unsigned comparison. + case ult + + /// LHS is less than or equal to RHS, by unsigned comparison. + case ule + + /// LHS is less than RHS, by signed comparison. + case slt + + /// LHS is greater than or equal to RHS, by signed comparison. + case sge + + /// LHS is greater than RHS, by signed comparison. + case sgt + + /// LHS is less than or equal to RHS, by signed comparison. + case sle + +} + +extension IntegerPredicate: LosslessStringConvertible { + + public init?(_ description: String) { + self.init(rawValue: description) + } + + public var description: String { self.rawValue } + +} diff --git a/Sources/Core/NativeInstruction.swift b/Sources/Core/NativeInstruction.swift index bb58ed82e..73fd4368b 100644 --- a/Sources/Core/NativeInstruction.swift +++ b/Sources/Core/NativeInstruction.swift @@ -1,5 +1,3 @@ -import LLVM - /// The name of an native instruction mapped to a built-in function. /// /// Native instructions implement basis operations on built-in types, such as `Builtin.i64`, with @@ -27,13 +25,13 @@ import LLVM /// integral and floating-point numbers as well as conversions from and to these types. public enum NativeInstruction: Hashable { - case add(LLVM.OverflowBehavior, BuiltinType) + case add(OverflowBehavior, BuiltinType) - case sub(LLVM.OverflowBehavior, BuiltinType) + case sub(OverflowBehavior, BuiltinType) - case mul(LLVM.OverflowBehavior, BuiltinType) + case mul(OverflowBehavior, BuiltinType) - case shl(LLVM.OverflowBehavior, BuiltinType) + case shl(OverflowBehavior, BuiltinType) case udiv(exact: Bool, BuiltinType) @@ -71,7 +69,7 @@ public enum NativeInstruction: Hashable { // Corresponding LLVM instruction: umul.with.overflow case unsignedMultiplicationWithOverflow(BuiltinType) - case icmp(LLVM.IntegerPredicate, BuiltinType) + case icmp(IntegerPredicate, BuiltinType) case trunc(BuiltinType, BuiltinType) @@ -97,7 +95,7 @@ public enum NativeInstruction: Hashable { case frem(MathFlags, BuiltinType) - case fcmp(MathFlags, LLVM.FloatingPointPredicate, BuiltinType) + case fcmp(MathFlags, FloatingPointPredicate, BuiltinType) case fptrunc(BuiltinType, BuiltinType) diff --git a/Sources/Core/OverflowBehavior.swift b/Sources/Core/OverflowBehavior.swift new file mode 100644 index 000000000..287233f4c --- /dev/null +++ b/Sources/Core/OverflowBehavior.swift @@ -0,0 +1,15 @@ +/// Copied from SwiftLLVM, used to remove LLVM dependency from Core + +/// The behavior that should occur on overflow during mathematical operations. +public enum OverflowBehavior { + + /// Overflow is ignored. + case ignore + + /// The result is a poison value should unsigned overflow occur. + case nuw + + /// The result is a poison value should signed overflow occur. + case nsw + +}