Commit Graph

88 Commits

Author SHA1 Message Date
Meghana Gupta
2f37e10674 Rewrite UnsafeRawBufferPointer.Iterator.next to avoid non natural loop in SIL
The current implementation creates a non-natural loop and none of the SIL and
LLVM loop passes will work for such loops. We have to find a way to fix this in
SIL. Until then, rewrite so we get a natural loop in SIL.
2024-09-05 15:35:39 -07:00
Kuba Mracek
f572000d94 [ARCOpts] Don't move releases before landingpads 2024-06-15 13:12:43 -07:00
Nuri Amari
a2eb58227a [swift-vfe][swift-wme] Stop disabling function mergers for Swift VFE / WME
The Swift and LLVM function mergers were disabled when Swift VFE or WME
are enabled because the function merger did not respect metadata on
calls to `llvm.type.checked.load`. This is no longer the case,
so we can turn these passes back on.
2023-10-25 11:09:47 -07:00
Ben Barham
993c0dff60 [rebranch] Fix recently added merge function test
Opaque pointers are always enabled on rebranch. Rename the test to
better represent what it's testing.
2023-08-21 19:57:42 -07:00
swift-ci
b57534c4db Merge remote-tracking branch 'origin/main' into rebranch 2023-08-16 21:40:49 -07:00
Erik Eckstein
fda5549908 SwiftMergeFunctionsPass: fix a problem with opaque pointers
Need to insert a cast for the return type of a call to a merged function.

Fixes an LLVM verifier crash.

rdar://113901800
2023-08-16 18:19:26 +02:00
Arnold Schwaighofer
597f8d9e99 Move swift-llvm-opt over to use the new pass manager
rdar://112424659
2023-08-04 07:50:38 -07:00
Erik Eckstein
6375647383 driver: add swift-frontend options to select the tool to run
Tool selection is primarily done by checking the executable (= symlink) name.
But sometimes (e.g. if the tool symlink is not there) it's useful to have an option for selecting the tool.
The selection option (e.g. -sil-opt) must be the first argument of swift-frontend.
2023-04-28 15:18:16 +02:00
Erik Eckstein
8bed2f32ed [rebranch] some test fixes 2022-11-04 20:44:19 +01:00
Meghana Gupta
87cde88aca Fix for a crash due to performLocalReleaseMotion and performLocalRetainMotion (#38150)
In low level LLVMARCOptimizer, during canonicalization we don't rauw the result of RT_Retain with its arg similarly to RT_ObjCRetain and RT_BridgeRetain.
And during performLocalReleaseMotion, we assert that we have canonicalized RT_Retain.
In a release compiler, if we optimize such an RT_Retain with a RT_Release, then this can result in a compiler crash

Similarly not rauw'ing, can cause a crash due to performLocalRetainMotion

Fixes rdar://79238115
2021-06-30 15:40:15 -07:00
Arnold Schwaighofer
1f16f7ad8a Adjust to LLVM change that requires sret parameter attributes to be
annotated with the pointee type.

rdar://71808491
2020-12-03 09:39:41 -08:00
Erik Eckstein
e64848274f tests: add a missing codesign command in merge_func_ptrauth.swift
rdar://problem/69727772
2020-09-29 13:43:10 +02:00
Erik Eckstein
e4e5484ab4 LLVM-Passes: add pointer authentication to Swift's function merge pass.
If during merging a function pointer is passed as a parameter to the merged function, it needs to be signed on arm64e.

rdar://problem/66797689
2020-09-23 16:25:17 +02:00
Arnold Schwaighofer
9ee12db2a9 Fix tests for LLVM change that added anonymous parameter labeling
Fix for r367755.
2019-08-15 14:57:24 -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
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
Vedant Kumar
0db7e4864f [mergefunc] Avoid eliminating dtrace patchpoints (#21305)
Dtrace has special linker support to detect and patch probe call sites.

Each call to a dtrace probe must resolve to a unique patchpoint.

rdar://45738058
2018-12-13 15:57:52 -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
Erik Eckstein
bcc13e8060 Fix a miscompile in the swift function merging pass.
In rare corner cases the pass merged two functions which contain incompatible call instructions.
See source comment in the change for details.

rdar://problem/43051718
2018-08-09 14:46:06 -07: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
Michael Gottesman
08fc956382 Make our LLVM level passes obey disable-llvm-optzns.
We weren't performing the right check here... I added a test that tests both
positive/negative cases.

rdar://40097698
2018-05-14 12:09:06 -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
Erik Eckstein
d342041420 Mangling: use ‘Tm’ mangling for merged functions
Previously merged functions just got the name with a “_merged” suffix
2017-05-24 17:00:16 -07:00
Erik Eckstein
f3a7824028 MergeFunctions: now really handle self recursions correctly.
fixes rdar://problem/31519893
2017-04-11 13:57:29 -07:00
Erik Eckstein
2584078e3c MergeFunctions: handle self recursive functions correctly.
First, it fixes a crash where the eliminated function is still referenced.
This shows up if two equivalent self-recursive functions are merged and those functions are internal.
Fixes SR-4514, rdar://problem/31479425

Second, it avoids creating a not needed parameter for really equivalent self recursive functions.
2017-04-07 14:21:26 -07:00
practicalswift
cc852042c9 [gardening] Fix accidental trailing whitespace. 2016-10-29 10:22:58 +02:00
Michael Gottesman
b018645418 [semantic-arc] Add __swift_endBorrow support to LLVMPasses and make sure it is removed by LLVMARCContract.cpp. 2016-10-17 14:43:28 -07:00
Michael Gottesman
2c88a72d04 [llvm-arc-contract] Fix __swift_fixLifetime removal test so it actually tests something.
Evidently this has been silently not testing anything for a while. Luckily, the
functionality seems not to be broken, just the test. Also IRGen is emitting the
correct function name as well.
2016-10-17 14:43:28 -07:00
Roman Levenstein
56d55dec2b [swift-runtime] Rename rt_swift_* to swift_rt_*. NFC
Swift uses rt_swift_* functions to call the Swift runtime without using dyld's stubs. These functions are renamed to swift_rt_* to reduce namespace pollution.

rdar://28706212
2016-10-11 09:49:06 -07:00
Saleem Abdulrasool
8e1a88e985 LLVMPasses: fix DLL storage for merged functions
When constructing the body of the merged function, the internal function is
given internal linkage always.  It is only accessible through the adjusting
thunks which retain the original DLL storage.  Ensure that we reset the DLL
storage which it inherited from the first function.
2016-10-06 08:09:23 -07:00
Erik Eckstein
bd0d2bfed4 Remove the LLVM stack promotion pass and related SIL optimization logic.
It's not needed anymore because array buffers are now allocated with alloc_ref instead of a swift_bufferAllocate runtime call.
2016-09-16 11:02:19 -07:00
Dmitri Gribenko
fbb3cf35a5 Revert "New SIL instructions to support tail-allocated arrays in SIL." 2016-09-15 00:25:25 -07:00
Erik Eckstein
6ae818c9d1 Remove the LLVM stack promotion pass and related SIL optimization logic.
It's not needed anymore because array buffers are now allocated with alloc_ref instead of a swift_bufferAllocate runtime call.
2016-09-14 14:54:18 -07:00
Xin Tong
026cee2f84 Fix a globalvariable initializer bug in LLVMSwiftARC 2016-08-22 14:23:21 -07:00
Dmitri Gribenko
d175b3b66d Migrate FileCheck to %FileCheck in tests 2016-08-10 23:52:02 -07:00
Mark Lacey
da9c346444 Functions with differing phis should not be merged.
Check that the incoming blocks of phi nodes are identical, and block
function merging if they are not.

rdar://problem/26387654
2016-05-20 08:58:43 -07:00
Erik Eckstein
f0022a5aac Add an LLVM pass to merge similar functions.
It's like LLVM's MergeFunctions pass, except that it can also merge functions which differ by some constants.
The intention is to merge specialized functions which only differ by metadata lookups. But it can also merge other types of functions.
It gives ~7% code size reducation for the stdlib.

There are still some open TODOs, e.g. to share common code with LLVM's MergeFunctions pass (currently much code is just copied).
2016-05-11 09:46:46 -07:00
Erik Eckstein
bf87de3bc3 Fix a memory leak caused by the ReleaseDevirtualizer.
This occured if a stack-promoted object with a devirtualized final release is not actually allocated on the stack.
Now the ReleaseDevirtualizer models the procedure of a final release more accurately.
It inserts a set_deallocating instruction and calles the deallocator (instead of just the deinit).

This changes also includes two peephole optimizations in IRGen and LLVMStackPromotion which get rid of
unused runtime calls in case the stack promoted object is really allocated on the stack.

This fixes rdar://problem/25068118
2016-03-15 12:56:54 -07:00
Roman Levenstein
2ff5755dc3 Use the "rt_" prefix for all generated wrappers to distinguish them from the actual runtime functions. 2016-02-25 06:00:30 -08:00
Joe Groff
8cb1175e49 IRGen: Emit public definitions with protected visibility on ELF.
This prevents the linker from trying to emit relative relocations to locally-defined public symbols into dynamic libraries, which gives ld.so heartache.
2016-02-08 13:09:27 -08:00
practicalswift
fd70b26033 Fix typos in comments. 2015-12-28 02:15:34 +01:00
Joe Groff
cf87b9d571 IRGen: Generate swift_fixLifetime marker as a private stub.
This lets us remove `swift_fixLifetime` as a real runtime entry point. Also, avoid generating the marker at all if the LLVM ARC optimizer won't be run, as in -Onone or -disable-llvm-arc-optimizer mode.
2015-12-21 18:06:18 -08:00
Xin Tong
0b79ecf51c Rename swift-arc-optimize to swift-llvm-arc-optimize as this is a LLVM pass 2015-11-18 11:53:23 -08:00
Erik Eckstein
ce848c648d And again: re-apply the StackPromotion commit 0dd045ca04.
The problem of the failure was a bug in instruction cloning, which is fixed in the previous commit.
2015-11-08 15:51:00 -08:00
Mark Lacey
e9718f619e Revert "Another try to re-apply the StackPromotion commit 0dd045ca04dcc10a33abf57f7e1b08260c4e3de1."
This reverts commit 7d70aa39dc because
it may be responsible for a bot breakage.
2015-11-07 16:51:24 -08:00
Erik Eckstein
7d70aa39dc Another try to re-apply the StackPromotion commit 0dd045ca04.
One bug fixed in escape analysis (previous commit) and one bug fixed in StackPromotion itself.
2015-11-06 16:16:36 -08:00
Arnold Schwaighofer
fd662987c8 Revert the StackPromotion pass - bots hit an assert.
Assertion failed: (NumUsePointsToFind > 0 && "There must be at least one
releasing instruction for an alloc"), function canPromoteAlloc

Revert "Fix comment for StackPromotion pass in SIL Passes"
Revert "Reapply the StackPromotion commit
0dd045ca04dcc10a33abf57f7e1b08260c4e3de1."

This reverts commit 3f4b1496bd and commit
199cfca13b.
2015-11-06 06:40:05 -08:00
Erik Eckstein
199cfca13b Reapply the StackPromotion commit 0dd045ca04.
This time with fixing a crash.
2015-11-05 22:01:27 -08:00