Commit Graph

43 Commits

Author SHA1 Message Date
Doug Gregor
bce3fa000b [IRGen] Correctly assign lazily-emitted global variables in multi-threaded IRGen
With multi-threaded IRGen, the global variables associated with "once"
initialization tokens were not getting colocated with their actual
global variables, which caused the initialization code to get split
across different files. This issue manifest as autolinking errors in
some projects.

Fixes rdar://162400654.
2025-11-10 23:08:57 -08:00
Doug Gregor
5d576470fd [IRGen] Detect duplicate definitions at the IR level 2025-10-31 10:32:54 -07:00
Doug Gregor
f267f62f65 [SILGen] Consistently use SIL asmname for foreign function/variable references
Whenever we have a reference to a foreign function/variable in SIL, use
a mangled name at the SIL level with the C name in the asmname
attribute. The expands the use of asmname to three kinds of cases that
it hadn't been used in yet:

* Declarations imported from C headers/modules
* @_cdecl @implementation of C headers/modules
* @_cdecl functions in general

Some code within the SIL pipeline makes assumptions that the C names of
various runtime functions are reflected at the SIL level. For example,
the linking of Embedded Swift runtime functions is done by-name, and
some of those names refer to C functions (like `swift_retain`) and
others refer to Swift functions that use `@_silgen_name` (like
`swift_getDefaultExecutor`). Extend the serialized module format to
include a table that maps from the asmname of functions/variables over
to their mangled names, so we can look up functions by asmname if we
want. These tables could also be used for checking for declarations
that conflict on their asmname in the future. Right now, we leave it
up to LLVM or the linker to do the checking.

`@_silgen_name` is not affected by these changes, nor should it be:
that hidden feature is specifically meant to affect the name at the
SIL level.

The vast majority of test changes are SIL tests where we had expected
to see the C/C++/Objective-C names in the tests for references to
foreign entities, and now we see Swift mangled names (ending in To).
The SIL declarations themselves will have a corresponding asmname.

Notably, the IRGen tests have *not* changed, because we generally the
same IR as before. It's only the modeling at the SIL lever that has
changed.

Another part of rdar://137014448.
2025-10-29 19:35:55 -07:00
Doug Gregor
081b5cd1e8 [SIL] Serialize section name correctly and model it on global variables
Fixes rdar://162549960.
2025-10-15 20:44:11 -07:00
Doug Gregor
cc519a09d0 [Embedded] Identify more places to emit symbols even with deferred code generation
Deferred code generation only produces symbols when they are needed.
Expand this out to cover more of the cases where we need them:
* @c/@_cdecl with and without @implementation
* @_expose(Cxx) and @_expose(Wasm)
* @_section and @_used
* (already present) the main entry point

Part of the Embedded Swift linkage model. Also fixes #74328 /
rdar://147207945 along the way.
2025-10-03 16:00:46 -07:00
Doug Gregor
74e85c8416 [SIL] Track the parent module of a SIL global variable through serialization
As with SIL functions, track the parent module where a SIL global
variable was originally defined so that we can determine whether we
are outside of its original module for linkage purposes. Use this to
make sure we emit via a weak definition when emitting to a module
other than the originating module.

Fixes rdar://160153163.
2025-09-08 17:44:49 -07:00
Doug Gregor
4009814783 [IRGen] Lazily emit SIL global variables
Delay the emission of SIL global variables that aren't externally
visible until they are actually used. This is the same lazy emission
approach that we use for a number of other entities, such as SIL
functions.

Part of rdar://158363967.
2025-09-04 13:03:15 -07:00
Doug Gregor
9a20ebac5b [Embedded] Emit weak definitions for imported symbols
When Embedded Swift emits a symbol that was imported from another
module, ensure that the symbol is emitted as a weak definition. This
way, importing the same module (and using its symbol) into several
different modules doesn't cause duplicate-symbol errors at link time.
Rather, the linker will merge the different symbol definitions. This
makes Embedded Swift libraries work without resorting to
`-mergeable-symbols` or `-emit-empty-object-file`.
2025-08-17 15:26:08 -07:00
Doug Gregor
c91a4822d3 Serialize the "markedAsUsed" bit for SILGlobalVariable 2025-08-17 15:25:50 -07:00
Erik Eckstein
162794ca35 SIL: don't set the let flag on a SILGlobalVariable if it contains a struct with @_rawLayout
Even if the global declaration is a `let`.
Raw-layout storage may be mutated even for let-variables.
Treating such variables as non-let ensures that optimization don't assume that they are not mutated.
2025-08-03 17:25:42 +02:00
Kuba Mracek
f402eb623c [Compile Time Values] Add parsing of @constInitialized attribute under CompileTimeValues experimental feature 2025-03-24 09:31:57 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Ellie Shin
4ecfc96578 [SIL][PackageCMO] Allow optimizing [serialized_for_pkg] functions during SIL
inlining, generic/closure specialization, and devirtualization optimization passes.

SILFunction::canBeInlinedIntoCaller now exlicitly requires a caller's SerializedKind_t arg.
isAnySerialized() is added as a convenience function that checks if [serialized] or [serialized_for_pkg].

Resolves rdar://128704752
2024-05-27 23:05:56 -07:00
Ellie Shin
5ccc4cd394 SIL function can be serialized with different kinds: [serialized] or
[serialized_for_package] if Package CMO is enabled. The latter kind
allows a function to be serialized even if it contains loadable types,
if Package CMO is enabled. Renamed IsSerialized_t as SerializedKind_t.

The tri-state serialization kind requires validating inlinability
depending on the serialization kinds of callee vs caller; e.g. if the
callee is [serialized_for_package], the caller must be _not_ [serialized].
Renamed `hasValidLinkageForFragileInline` as `canBeInlinedIntoCaller`
that takes in its caller's SerializedKind as an argument. Another argument
`assumeFragileCaller` is also added to ensure that the calle sites of
this function know the caller is serialized unless it's called for SIL
inlining optimization passes.

The [serialized_for_package] attribute is allowed for SIL function, global var,
v-table, and witness-table.

Resolves rdar://128406520
2024-05-23 15:53:02 -07:00
Augusto Noronha
529845056b Fix functions not being kept for debugger
At Onone, many types of functions (anything user written, compiler
generated setters and getters, etc), should be kept in the final
binary so they're accessible by the debugger.

rdar://126763340
2024-05-14 10:31:44 -07:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Allan Shortlidge
da3af768e6 SIL: Fix a crash during access path verification.
The access path verification optimizer pass calls
`getStaticallyInitializedVariable()`, which was written assuming that the given
`SILFunction` would always have a valid return basic block. When the
`-unavailable-decl-optimization=stub` option is passed to the frontend, though,
any function generated for a declaration marked `@available(*, unavailable)` is
rewritten to trap by calling a function that returns `Never`. Therefore the
rewritten functions do not have return blocks and passing these functions to
`getStaticallyInitializedVariable()` would result in the compiler invoking
undefined behavior.

Resolves rdar://118281508
2023-11-12 09:47:49 -08:00
Kuba Mracek
145f12f6a3 Allow using structs with trivial initializers in globals that require static initialization (e.g. @_section attribute)
Before this change, if a global variable is required to be statically initialized (e.g. due to @_section attribute), we don't allow its type to be a struct, only a scalar type works. This change improves on that by teaching MandatoryPerformanceOptimizations pass to inline struct initializer calls into initializer of globals, as long as they are simple enough so that we can be sure that we don't trigger recursive/infinite inlining.
2023-07-08 19:26:59 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Erik Eckstein
a80d0cb8a7 remove now unused utilities
* StaticInitCloner
* some APIs in SILGlobalVariable
2023-05-22 15:34:26 +02:00
Erik Eckstein
85aa1c12db handle debug_step in static initializers of globals and in the const expression evaluator 2023-05-08 21:23:36 +02:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Erik Eckstein
6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
Erik Eckstein
c578c937c8 SILOptimizer: run the GlobalOpt pass in the mandatory pipeline.
Replace the dynamic initialization of trivial globals with statically initialized globals, even in -Onone.
This is required to be able to use global variables in performance-annotated functions.
Also, it's a small performance improvement for -Onone.
2021-10-29 22:35:57 +02:00
Erik Eckstein
8080465e77 libswift: basic SIL and SIL bridging
This is the initial version of a buildable SIL definition in libswift.
It defines an initial set of SIL classes, like Function, BasicBlock, Instruction, Argument, and a few instruction classes.
The interface between C++ and SIL is a bridging layer, implemented in C.
It contains all the required bridging data structures used to access various SIL data structures.
2021-06-09 11:28:57 +02:00
Erik Eckstein
24799e1526 SIL: defer instruction deletion to the end of a pass run.
When an instruction is "deleted" from the SIL, it is put into the SILModule::scheduledForDeletion list.
The instructions in this list are eventually deleted for real in SILModule::flushDeletedInsts(), which is called by the pass manager after each pass run.
In other words: instruction deletion is deferred to the end of a pass.

This avoids dangling instruction pointers within the run of a pass and in analysis caches.
Note that the analysis invalidation mechanism ensures that analysis caches are invalidated before flushDeletedInsts().
2021-05-26 21:57:54 +02:00
Erik Eckstein
eee33a71e6 GlobalOpt: bail is the initializer instructions of a global variable contain "undef"
Fixes a compiler crash

rdar://75364429
2021-03-16 11:26:54 +01:00
Erik Eckstein
0a483a6b6b SILOptimizer: allow function pointers in static globals and static global arrays.
For example, generate a static global for the array literal in:

func foo(_ i: Int) -> Int { ... }
func bar(_ i: Int) -> Int { ... }

func returnFunctionArray() -> [(Int) -> Int] {
  return [foo, bar]
}

rdar://73570149
https://bugs.swift.org/browse/SR-14101
2021-02-09 19:56:43 +01:00
Erik Eckstein
ee8cdac501 DeadFunctionElimination: Also eliminate dead global variables.
It makes sense to to this in a single pass, because there might be dead cycles for globals and functions, e.g. if a global references a function in its static initializer and the function references that global.

Another improvement: eliminate dead global-initializers. Before we had an explicit SIL representation of statically initialized globals, we had to keep them alive.

rdar://32956923
2021-02-09 19:56:43 +01:00
Erik Eckstein
542a378436 SIL: add FunctionRefInst::getReferencedFunction()
If we know that we have a FunctionRefInst (and not another variant of FunctionRefBaseInst), we know that getting the referenced function will not be null (in contrast to FunctionRefBaseInst::getReferencedFunctionOrNull).

NFC
2021-02-09 19:56:43 +01:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Erik Eckstein
170d9e9eea SIL: Let SILGlobalVariables be destroyed.
This fixes a memory leak: instructions of the static initializer block were not be freed.

rdar://problem/66931238
2020-09-11 11:09:29 +02:00
Joe Groff
6d6165a9db SILOptimizer: Recognize globalinit once functions using an attribute instead of symbol name matching 2020-08-25 17:43:27 -07:00
Erik Eckstein
755f6aa2e4 AST, SIL: Remove UTF16 encoding from StringLiteralExpr and StringLiteralInst
The UTF16 encoding is not used (anymore). I think it became obsolete with the switch to the UTF8 String representation.
2020-08-06 19:09:09 +02:00
Erik Eckstein
ba7ecfb2c4 SIL: small refactoring of swift::findInitializer
NFC
2020-08-03 12:01:29 +02:00
Meghana Gupta
4d705abc87 Merge pull request #32319 from meg-gupta/onfastpath
Ignore onFastPath builtin while looking for valid static initializer of a global variable
2020-06-15 10:23:09 -07:00
David Zarzycki
d9073c83fa Merge pull request #32135 from davezarzycki/pr32135
[SIL] NFC: Shrink SILGlobalVariable by 16 bytes
2020-06-11 14:51:05 -04:00
Meghana Gupta
632b5ce0c8 Ignore OnFastPath builtin while looking for valid static initializer of a global variable 2020-06-11 10:06:10 -07:00
David Zarzycki
6c46118cfd [SIL] NFC: "Stop being a sop" 2020-06-09 10:51:03 -04:00
David Zarzycki
5f162eb1fa [SIL] NFC: Shrink SILGlobalVariable by 16 bytes 2020-06-05 07:24:25 -04:00
David Zarzycki
9bd6b02f5c [SILOpt] Add ZeroInitializer to isValidStaticInitializerInst 2020-05-11 15:56:52 -04:00
Michael Gottesman
e1a19e4173 [sil] Split library into subfolders, while still building as a single library still.
Specifically, I split it into 3 initial categories: IR, Utils, Verifier. I just
did this quickly, we can always split it more later if we want.

I followed the model that we use in SILOptimizer: ./lib/SIL/CMakeLists.txt vends
 a macro (sil_register_sources) to the sub-folders that register the sources of
 the subdirectory with a global state variable that ./lib/SIL/CMakeLists.txt
 defines. Then after including those subdirs, the parent cmake declares the SIL
 library. So the output is the same, but we have the flexibility of having
 subdirectories to categorize source files.
2020-03-30 11:01:00 -07:00