Commit Graph

57 Commits

Author SHA1 Message Date
Saleem Abdulrasool
ec70054c93 IRGen: further generalise runtime function generation
This adjusts the runtime function declaration handling to track the
owning module for the well known functions. This allows us to ensure
that we are able to properly identify if the symbol should be imported
or not when building the shared libraries. This will require a
subsequent tweak to allow for checking for static library linkage to
ensure that we do not mark the symbol as DLLImport when doing static
linking.
2025-01-15 13:54:34 -08:00
Ben Barham
249f2d030a [rebranch] Correct read only argument memory and apply in getRuntimeFn
`ReadOnly, ArgMemOnly` previously meant `can only read argument memory`.
But with the rebranch changes, this became `(can only read *all* memory)
and (can read or write argument memory)`. Use `ArgMemReadOnly` for this
instead.

To expand on this, these attributes (prior to memory effects) used to be
split into two. There was the *kind* of access, eg.
```
readnone
readonly
writeonly
```
and the accessed *location*, eg.
```
argmemonly
inaccessiblememonly
inaccessiblemem_or_argmemonly
```

So `RuntimeFunctions.def` would use `ReadOnly, ArgMemOnly` to mean `can
only read argument memory`.

In the previous rebranch commits, this was changed such that `ReadOnly`
mapped to `MemoryEffectsBase::readOnly()` and `ArgMemOnly` to
`MemoryEffectsBase::argMemOnly()`.

And there lies the issue -
  - `MemoryEffectsBase::readOnly()` == `MemoryEffectsBase(Ref)` ie. all
    locations can only read
  - `MemoryEffectsBase::argMemOnly()` == `MemoryEffectsBase(ArgMem,
    ModRef)`, ie. can only access argument memory

But then OR'ing those together this would become:
```
ArgMem: ModRef, InaccessibleMem: Ref, Other: Ref
```
rather than the previously intended:
```
ArgMem: Ref, InaccessibleMem: NoModRef, Other: NoModRef
```
2023-08-10 22:03:50 -07:00
Arnold Schwaighofer
ad88fc6cbe Revert "[rebranch] Pass memory effects through to getRuntimeFn" 2023-08-09 10:27:10 -07:00
Ben Barham
b4ad633de7 [rebranch] Pass memory effects through to getRuntimeFn
These were being lost in the `IRGenModule::get##ID##Fn()`
implementation.
2023-08-08 13:50:16 -07:00
Evan Wilde
41d59b215a Update Triple.h location
Triple moved from ADT to TargetParser. Updating includes to reflect
that.
2023-07-17 10:53:42 -07:00
Arnold Schwaighofer
d810b0f7e4 IRGen: Pass the elementType of pointers through to operations
In preparation for moving to llvm's opaque pointer representation
replace getPointerElementType and CreateCall/CreateLoad/Store uses that
dependent on the address operand's pointer element type.

This means an `Address` carries the element type and we use
`FunctionPointer` in more places or read the function type off the
`llvm::Function`.
2022-10-03 15:27:12 -07:00
Evan Wilde
52c5f1a5f1 Fix build failure in LLVMMergeFunctions
- 3e1c787b3160bed4146d3b2b5f922aeed3caafd7 `arg_operands` was replaced with `args`.
 - 80ea2bb57450a65cc724565ecfc9971ad93a3f15 `get*Attributes` was replaced with `get*Attrs`
2021-10-21 13:40:42 -07:00
Minhyuk Kim
e924cf6104 Replace usages of StringRef.find(Key) != StringRef::npos to StringRef.contains(Key) 2021-02-04 00:42:04 +09:00
Alexis Laferrière
fe42c37f2e Update to follow LLVM change to getTypeByName
rdar://71864457
2020-12-01 13:31:03 -08:00
Michael Forster
8d1d9f1eb5 Remove calls to deprecated IRBuilder APIs
These APIs have been removed in upstream LLVM, breaking master-next.
2020-04-17 09:32:03 +02:00
Brent Royal-Gordon
fb20b503ba Merge branch 'master' into master-rebranch
# Conflicts:
#	lib/ClangImporter/ClangImporter.cpp
#	test/IRGen/builtins.swift
#	test/IRGen/enum.sil
#	tools/driver/autolink_extract_main.cpp
#	utils/build-presets.ini
2019-08-08 17:07:59 -07:00
Arnold Schwaighofer
27bfcd53dc Rework getRuntimeFn runtime availability
NFC.
2019-06-18 11:09:07 -07:00
Ben Langmuir
c42b732e26 Merge remote-tracking branch 'origin/master' into master-next
Conflicts:
	lib/IRGen/IRGenModule.cpp
2019-06-18 09:35:57 -07:00
Arnold Schwaighofer
eb32194e97 Refactor to use RuntimeAvailability 2019-06-14 13:21:35 -07:00
swift-ci
e51820b17c Merge remote-tracking branch 'origin/master' into master-next 2019-05-16 07:09:56 -07:00
Joe Groff
2ade303387 IRGen: Weak-link opaque type entry points.
When backward deploying to an OS that may not have these entry points, weak-link them so that they
can be used conditionally in availability contexts that check for them.

rdar://problem/50731151
2019-05-15 20:40:54 -07:00
swift-ci
4473b97f4c Merge remote-tracking branch 'origin/master' into master-next 2019-03-21 21:49:58 -07:00
Joe Shajrawi
dae15989e8 ARCEntryPointBuilder: Don't mark the call instructions as tail-calls
rdar://problem/48833545

From the LLVM Manual regarding tail/musttail : "Both markers imply that the callee does not access allocas from the caller”

Swift’s LLVMARCContract just marks all the calls it creates as tail call without any analysis and/or checking if we are allowed to do that. This created an interesting runtime crash that was a pain to debug - story time:

I traced a runtime crash back to Swift’s LLVMARCContract, but could not grok why the transformation there is wrong: we replaced two consecutive _swift_bridgeObjectRelease(x) calls with _swift_bridgeObjectRelease_n(x, 2), which is a perfectly valid thing to do.

I noticed that the new call is marked as a tail call, disabling that portion of the pass “solved” the runtime crash, but I wanted to understand *why*:

This code worked:
	pushq	$2
	popq	%rsi
	movq	-168(%rbp), %rdi
	callq	_swift_bridgeObjectRelease_n
	leaq	-40(%rbp), %rsp
	popq	%rbx
	popq	%r12
	popq	%r13
	popq	%r14
	popq	%r15
	popq	%rbp
	retq

While this version crashed further on during the run:
	movq	-168(%rbp), %rdi
	leaq	-40(%rbp), %rsp
	popq	%rbx
	popq	%r12
	popq	%r13
	popq	%r14
	popq	%r15
	popq	%rbp
	jmp	_swift_bridgeObjectRelease_n

As you can see, the call is the last thing we do before returning, so nothing appeared out of the ordinary at first…

Dumping the heap object at the release basic block looked perfectly fine: the ref count was 2 and all the fields looked valid.

However, when we reached the callee the value was modified / dumping it showed it changed somewhere. Which did not make any sense.

Setting up a memory watchpoint on the heap object and/or its reference count did not get us anywhere: the watchpoint triggered on unrelated code in the entry to the callee..

I then realized what’s going on, here’s a an amusing reproducer that you can checkout in LLDB:
Experiment 1:
Setup a breakpoint at leaq	-40(%rbp), %rsp
Dump the heap object - it looks good
Experiment 2:
Rerun the same test with a small modification:
Setup a breakpoint at popq	%rbx (the instruction after leaq, do not set a breakpoint at leaq)
Dump the heap object - it looks bad!

So what is going on there? The SIL Optimizer changed an alloc_ref instruction into an alloc_ref [stack], which is a perfectly valid thing to do.

However, this means we allocated the heap object on the stack, and then tail-called into the swift runtime with said object. After having modified the stack pointer in the caller’s epilogue.

So why does experiment 2 show garbage? We’ve updated the stack pointer, and it just so happens that we are after the red zone on the stack. When the breakpoint is hit (the OS passes control back to LLDB), it is perfectly allowed to use the memory where the heap object used to reside.

Note: I then realized something even more concerning, that we were lucky not have hit so far: not only did we not check if we are allowed to mark a call as ’tail’ in this situation, which could have been considered a corner case,  we could have if we have not promoted it from heap to stack, but we marked *ALL* the call instructions created in this pass as tail call even if they are not the last thing that occurred in the calling function! Looking at the LVMPasses/contract.ll test case, which is modified in this PR, we see some scary checks that are just wrong: we are checking if a call is marked as ‘tail’ in the middle of the function, then check the rest of the function in CHECK-NEXT lines. Knowing full well that the new ‘tail call’ is not the last thing that should execute in the caller.
2019-03-21 16:58:09 -07:00
Bob Wilson
a43ee93445 Merge pull request #22353 from compnerd/r352827
Adjust for SVN r352827
2019-02-09 16:42:18 -08:00
Michael Gottesman
9326ef4d73 [upstream-update] Update LLVMPasses for new objc arc intrinsics.
We used to represent these just as normal LLVM functions, e.x.:

  declare objc_object* @objc_retain(objc_object*)
  declare void @objc_release(objc_object*)

Recently, special objc intrinsics were added to LLVM. This pass updates these
small (old) passes to use the new intrinsics.

This turned out to not be too difficult since we never create these
instructions. We only analyze them, move them, and delete them.

rdar://47852297
2019-02-08 14:22:57 -08:00
Michael Gottesman
81fada9fb5 [upstream-update] Update LLVMPasses for new objc arc intrinsics.
We used to represent these just as normal LLVM functions, e.x.:

  declare objc_object* @objc_retain(objc_object*)
  declare void @objc_release(objc_object*)

Recently, special objc intrinsics were added to LLVM. This pass updates these
small (old) passes to use the new intrinsics.

This turned out to not be too difficult since we never create these
instructions. We only analyze them, move them, and delete them.

rdar://47852297
2019-02-06 16:22:15 -08:00
Saleem Abdulrasool
6a1072d825 Adjust for SVN r352827
Update for `getOrInsertFunction` API in LLVM.
2019-02-04 12:48:46 -08:00
Mike Ash
46309d9794 [Runtime] Rename swift_unknown* functions to swift_unknownObject*.
These functions don't accept local variable heap memory, although the names make it sound like they work on anything. When you try, they mistakenly identify such things as ObjC objects, call through to the equivalent objc_* function, and crash confusingly. This adds Object to the name of each one to make it more clear what they accept.

rdar://problem/37285743
2018-08-15 17:48:23 -04:00
Michael Gottesman
32805cbd23 [llvm-arc-opts] When RAUWing of bridgeRetain->bridgeRetainN, cast the result of the bridgeRetainN to the type of bridgeRetain.
Since we introduce the declaration for bridgeRetainN, its result type may be out
of sync with bridgeRetain's. This means that when we perform a RAUW of one for
the other, the types do not match and we get an LLVM error. Instead, just cast
the bridgeRetainN's type to bridgeRetain's result type.

rdar://40507281
2018-06-04 13:15:28 -07:00
Michael Gottesman
9d35e973f7 [llvm-arc-opts] If we are missing "swift.{refcounted,bridge}", create it as an opaque structure and don't assert.
Sometimes when running ARCContract on LLVM-IR certain required declarations will
be deleted. This triggers an assert that makes it difficult to work on running
test cases through the pass.

Instead, if we can not find by name the runtime function we are looking for,
recreate the named type as an opaque struct. Since we can not find the function
by name, we can assume that either this is a runtime function that we are the
only passes that create them or that the declarations were dead. Thus, there is
no earlier data, so we can just create a new opaque struct type and use pointers
to that struct_type. If we later need to merge this with another module that did
not delete that type definition, LLVM IR will set the type's body. Since we are
just using pointers to the type, there will be no codegen differences.

rdar://40491584
2018-06-04 13:15:07 -07:00
Greg Parker
e223f1fc9b [IRGen][runtime] Simplify runtime CCs and entry point ABIs (#14175)
* Remove RegisterPreservingCC. It was unused.
* Remove DefaultCC from the runtime. The distinction between C_CC and DefaultCC
  was unused and inconsistently applied. Separate C_CC and DefaultCC are
  still present in the compiler.
* Remove function pointer indirection from runtime functions except those
  that are used by Instruments. The remaining Instruments interface is
  expected to change later due to function pointer liability.
* Remove swift_rt_ wrappers. Function pointers are an ABI liability that we
  don't want, and there are better ways to get nonlazy binding if we need it.
  The fully custom wrappers were only needed for RegisterPreservingCC and
  for optimizing the Instruments function pointers.
2018-01-29 13:22:30 -08:00
Arnold Schwaighofer
3ae6d7cb4d runtime/IRGen: return the argument from swift_retain family of functions
On architectures where the calling convention uses the same argument register as
return register this allows the argument register to be live through the calls.

We use LLVM's 'returned' attribute on the parameter to facilitate this.

We used to perform this optimization via an optimization pass. This was ripped
out some time ago around commit 955e4ed652.
By using LLVM's 'returned' attribute on swift_*retain, we get the same
optimization from the LLVM backend.
2017-09-19 07:16:37 -07:00
Bob Wilson
dcf374dbed Adjust for LLVM r299949: Remove nullptr for Module::getOrInsertFunction
Module::getOrInsertFunction no longer needs the trailing nullptr argument,
and leaving it there causes a crash.
2017-04-13 14:35:07 -07:00
Saleem Abdulrasool
15565c116a Adjust for SVN r298393 2017-03-22 07:44:03 -07:00
Han Sangjin
b8dd577693 [swiftc] Fixed for Cygwin
Fixed for the difference of Cygwin with other Windows variants (MSVC,
Itanium, MinGW).

- The platform name is renamed to "cygwin" from "windows" which is used
  for searching the standard libraries.

- The consideration for DLL storage class (DllExport/DllImport) is not
  required for Cygwin and MinGW. There is no problem when linking in
  these environment.

- Cygwin should use large memory model as default.(This may be changed
  if someone ports to 32bit)

- Cygwin and MinGW should use the autolink feature in the sameway of
  Linux due to the linker's limit.
2017-01-19 05:48:24 +09:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
Saleem Abdulrasool
7352392830 IRGen: add support for DLL Storage semantics
Add initial support for modelling DLL Storage semantics for global values.  This
is needed to support the indirect addressing mechanism used on Windows.
2016-07-06 18:03:57 -07:00
Roman Levenstein
d8e28bb690 Handle the [nonatomic] attribute in IRGen and LLVM passes.
Properly lower reference counting SIL instructions with nonatomic attribute as invocations of corresponding non-atomic reference counting runtime functions.
2016-04-06 22:30:23 -07:00
practicalswift
a45e7b82fb [gardening] Fix recently introduced typo: "targe" → "target" 2016-04-02 11:31:26 +02:00
Roman Levenstein
b985794992 Prepare IRGen and LLVM passes to use the new preserve_most calling convention, but do not enable it yet.
The convention should be enabled once we can properly build the runtime library using Siwft's own clang/llvm binaries.
2016-04-01 14:19:47 -07:00
Roman Levenstein
99fd8b6080 Rename some macros based on the PR review comments.
- use  the SWIFT prefix for all macros
- make names of some macros shorter
2016-02-25 05:31:00 -08:00
Roman Levenstein
de3b850ce8 Use more descriptive names for calling conventions.
Rename RuntimeCC into DefaultCC
Rename RuntimeCC1 into RegisterPreservingCC
Remove RuntimeCC0 because it was identical to DefaultCC.
2016-02-25 05:31:00 -08:00
Roman Levenstein
ec04b22145 Properly propagate the calling convention into LLVM's call instructions.
Each runtime function definition in RuntimeFunctions.def states which calling convention
should be used for this runtime function.  But IRGen and LLVMPasses were not always
properly propagating this declared calling convention all the way down to llvm's Call instructions.
In many cases, the standard C convention was set for the call irrespective of the actual calling
convention defined for a given runtime function. As a result, incorrect code was generated.

This commit tries to fix all those places, where such a mismatch was found. In many cases this is
achieved by defining a helper function CreateCall in such a way that makes sure that the call instruction
gets the same calling convention as the one used by its callee operand.
2016-02-25 05:30:59 -08:00
Roman Levenstein
7350fee0e3 LLVMPasses should generate LLVM IR declarations of runtime functions in the same way as done by IRGen.
Make use of the re-usable functionality provided by IRGen. This ensures that LLVM IR generated by IRGen and
LLVMPasses for runtime functions declarations or wrappers is always in sync.
2016-02-25 05:30:58 -08:00
practicalswift
f91525a10f Consistent placement of "-*- [language] -*-===//" in header. 2016-01-04 09:46:20 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
ken0nek
fcd8fcee91 Convert [Cc]an not -> [Cc]annot 2015-12-23 00:55:48 +09:00
Simone Ferrini
ce4031f240 Removed unnecessary semicolons 2015-12-03 21:24:40 +01:00
Michael Gottesman
9fb54bf4bf Fix for upstream ilist changes. 2015-11-11 16:07:41 -08:00
Chris Lattner
fe78e77783 silence some warnings.
Swift SVN r32176
2015-09-23 05:06:51 +00:00
Xin Tong
2b546cd6b5 Implement bridgeobject_retain/release merging in LLVMARCContract. rdar://22108790
recommit for r32132.

Swift SVN r32145
2015-09-22 04:34:53 +00:00
Dmitri Hrybenko
55c6c8bd98 Revert "Implement bridgeobject_retain/release merging in LLVMARCContract. rdar://22108790"
This reverts commit r32132.  It broke tests:

Swift :: 1_stdlib/FloatingPoint.swift.gyb
Swift :: 1_stdlib/NSStringAPI.swift
Swift :: 1_stdlib/Runtime.swift
Swift :: Interpreter/SDK/CoreGraphics_CGFloat.swift

Swift SVN r32142
2015-09-22 01:08:02 +00:00
Xin Tong
3eb7000b8f Implement bridgeobject_retain/release merging in LLVMARCContract. rdar://22108790
Swift SVN r32132
2015-09-21 23:06:19 +00:00
Xin Tong
33193ef2d8 Strength reduce unknownRetain to retain.
when an object is passed to unknownRetain and retain, the unknownRetain
can be strength reduced to retain.  same for unknownRelease and release.

Swift SVN r32087
2015-09-18 23:20:20 +00:00