Skip to content

Commit cda044f

Browse files
authored
Feat: Restructure code & manage Packages (#4)
1 parent 45f60d7 commit cda044f

33 files changed

+3820
-6
lines changed

Package.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func getTargets() -> [Target] {
9191
let llvmTarget: Target = .target(
9292
name: "LLVM",
9393
dependencies: ["CLLVM"],
94-
path: "llvm-api/LLVM",
94+
// path: "llvm-api/LLVM",
9595
cSettings: [
9696
.unsafeFlags(cFlags),
9797
],
@@ -103,13 +103,13 @@ func getTargets() -> [Target] {
103103
} else {
104104
let customSystemLibrary: Target = .systemLibrary(
105105
name: "CLLVM",
106-
path: "llvm-api/CLLVM",
107-
pkgConfig: "cllvm"
106+
// path: "llvm-api/CLLVM",
107+
pkgConfig: "llvm"
108108
)
109109
let llvmTarget: Target = .target(
110110
name: "LLVM",
111-
dependencies: ["CLLVM"],
112-
path: "llvm-api/LLVM"
111+
dependencies: ["CLLVM"]
112+
// path: "llvm-api/LLVM"
113113
)
114114
return [customSystemLibrary, llvmTarget]
115115
}

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ brew install llvm
9393
- [x] v17.0
9494
- [x] v18.0
9595

96+
### XCode support
97+
98+
To develop correctly with XCode it's necessary to generate package-config: `llvm.pc`:
99+
- `sh utils/llvm-pkg.swift` - will generate package config and copy to your default `pkg-config` path.
100+
101+
After that XCode should correctly recognize LLVM headers path, and can build project.
96102

97103
### Troubleshooting
98104

@@ -108,6 +114,9 @@ llc --version
108114
brew info llvm
109115
```
110116

117+
- **conditional build**: `Package.swift` supports conditional builds:
118+
- for CLI build: `CLI_BUILD swift build` - it get's LLVM veriabels form Environment sets.
119+
- `swift build` - if presented `llvm.pc` package config
111120
- To get more insights take a look current project [Github CI config](.github/workflows/swift.yaml).
112121

113122
### LICENS: [MIT](LICENSE)

Source/CLLVM/bridge.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// bridge.h
3+
// llvm-codegen
4+
//
5+
// Created by Evgeny Ukhanov on 22/12/2023.
6+
//
7+
8+
#ifndef bridge_h
9+
#define bridge_h
10+
11+
#include <llvm-c/Transforms/PassBuilder.h>
12+
#include <llvm-c/Analysis.h>
13+
#include <llvm-c/BitReader.h>
14+
#include <llvm-c/BitWriter.h>
15+
#include <llvm-c/Comdat.h>
16+
#include <llvm-c/Core.h>
17+
#include <llvm-c/DataTypes.h>
18+
#include <llvm-c/DebugInfo.h>
19+
#include <llvm-c/Disassembler.h>
20+
#include <llvm-c/DisassemblerTypes.h>
21+
#include <llvm-c/Error.h>
22+
#include <llvm-c/ErrorHandling.h>
23+
#include <llvm-c/ExecutionEngine.h>
24+
#include <llvm-c/ExternC.h>
25+
#include <llvm-c/IRReader.h>
26+
#include <llvm-c/LLJIT.h>
27+
#include <llvm-c/Linker.h>
28+
#include <llvm-c/Object.h>
29+
#include <llvm-c/Orc.h>
30+
#include <llvm-c/OrcEE.h>
31+
#include <llvm-c/Remarks.h>
32+
#include <llvm-c/Support.h>
33+
#include <llvm-c/Target.h>
34+
#include <llvm-c/TargetMachine.h>
35+
#include <llvm-c/Types.h>
36+
#include <llvm-c/blake3.h>
37+
#include <llvm-c/lto.h>
38+
39+
#endif /* bridge_h */

Source/CLLVM/module.modulemap

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// module.modulemap
3+
// llvm-codegen
4+
//
5+
// Created by Evgeny Ukhanov on 22/12/2023.
6+
//
7+
8+
module CLLVM [system] {
9+
header "bridge.h"
10+
export *
11+
}

Source/LLVM/Core/AddressSpace.swift

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import CLLVM
2+
3+
/// An address space is an identifier for a target-specific range of address values. An address space is a
4+
/// fundamental part of the type of a pointer value and the type of operations that manipulate memory.
5+
///
6+
/// LLVM affords a default address space (numbered zero) and places a number of assumptions on pointer
7+
/// values within that address space:
8+
/// - The pointer must have a fixed integral value
9+
/// - The null pointer has a bit-value of 0
10+
///
11+
/// These assumptions are not guaranteed to hold in any other address space. In particular, a target may
12+
/// allow pointers in non-default address spaces to have *non-integral* types. Non-integral pointer types
13+
/// represent pointers that have an unspecified bitwise representation; that is, the integral representation may
14+
/// be target dependent or have an unstable value. Further, outside of the default address space, it is not
15+
/// always the case that the `null` pointer value, especially as returned by
16+
/// `constPointerNull()` has a bit value of 0. e.g. A non-default address space may use
17+
/// an offset-based or segment-based addressing mode in which 0 is a valid, addressable pointer value.
18+
///
19+
/// Target-Level Address Space Overrides
20+
/// ====================================
21+
///
22+
/// A target may choose to override the default address space for code, data, and local allocations through the
23+
/// data layout string. This has multiple uses. For example, the address space of an `alloca` is *only*
24+
/// configurable via the data layout string, because it is a target-dependent property. There are also
25+
/// use-cases for overriding language standards e.g. the C standard requires the address-of operator applied
26+
/// to values on the stack to result in a pointer in the default address space. However, many OpenCL-based
27+
/// targets consider the stack to be a private region, and place such pointers in a non-default address space.
28+
///
29+
/// Care must be taken when interacting with these non-standard targets. The IR printer currently does not
30+
/// print anything when the default address space is attached to an instruction or value, and values will still
31+
/// report being assigned to that space. However, these values are still subject to the backend's interpretation
32+
/// of the data layout string overrides and as such may not always reside in the default address space when
33+
/// it comes time to codegen them.
34+
///
35+
/// Restrictions
36+
/// ============
37+
///
38+
/// There are currently a number of artificial restrictions on values and operations that have non-default
39+
/// address spaces:
40+
/// - A `bitcast` between two pointer values residing in different address spaces, even if those two
41+
/// values have the same size, is always an illegal operation. Use an `addrspacecast` instead or
42+
/// always use `buildPointerCast()` to get the correct operation.
43+
/// - The so-called "null pointer" has a bit value that may differ from address space to address space. This
44+
/// exposes bugs in optimizer passes and lowerings that did not consider this possibility.
45+
/// - A pointer value may not necessarily "round-trip" when converted between address spaces, even if
46+
/// annotated `nonnull` and `dereferenceable`. This is especially true of non-integral pointer types.
47+
/// - Though the zero address space is the default, many backends and some errant passes interpret this to
48+
/// mean a "lack of address space" and may miscompile code with pointers in mixed address spaces.
49+
/// - A number of intriniscs that operate on memory currently do not support a non-default address space.
50+
/// - The address space is ultimately an integer value and in theory an address space identifier may take on
51+
/// any value. In practice, LLVM guarantees only 24 bits of precision, though higher address space
52+
/// identifiers may succeed in being properly represented.
53+
public struct AddressSpace: Equatable {
54+
let rawValue: UInt32
55+
56+
/// LLVM's default address space.
57+
public static let zero = AddressSpace(0)
58+
59+
/// Creates and initializes an address space with the given identifier.
60+
/// - Parameter identifier: The raw, integral address space identifier.
61+
public init(_ identifier: UInt32) {
62+
rawValue = identifier
63+
}
64+
}

0 commit comments

Comments
 (0)