Commit Graph

1069 Commits

Author SHA1 Message Date
Ben Cohen
2b04e9f105 Suppress a number of warnings in no-assert builds (#17721)
* Supress a number of warnings about things used only in asserts

* Re-use a couple of variables instead of supressing the warning
2018-07-04 07:15:14 -07:00
David Zarzycki
057bbb366a [IRGen] Adopt reference storage type meta-programming macros
This commit also fixes reference storage extra inhabitant bugs.
2018-06-30 11:48:47 -04:00
Slava Pestov
fcfa1786c8 IRGen: Add another lldb resilience hack
When accessing global variables defined in the REPL, lldb does not consult
debug info, so it does not see that the DW_OP_deref was emitted.

So instead, set a special bit on globals defined in the REPL which bypasses
resilience for them altogether.

Part of the fix <rdar://problem/39722386>.
2018-06-28 16:56:55 -07:00
Michael Gottesman
97367d3dd4 [ownership] Do not lower copy_unowned_value to strong_retain_unowned.
The major important thing here is that by using copy_unowned_value we can
guarantee that the non-ownership SIL ARC optimizer will treat the release
associated with the strong_retain_unowned as on a distinc rc-identity from its
argument. As an example of this problem consider the following SILGen like
output:

----
%1 = copy_value %0 : $Builtin.NativeObject
%2 = ref_to_unowned %1
%3 = copy_unowned_value %2
destroy_value %1
...
destroy_value %3
----

In this case, we are converting a strong reference to an unowned value and then
lifetime extending the value past the original value. After eliminating
ownership this lowers to:

----
strong_retain %0 : $Builtin.NativeObject
%1 = ref_to_unowned %0
strong_retain_unowned %1
strong_release %0
...
strong_release %0
----

From an RC identity perspective, we have now blurred the lines in between %3 and
%1 in the previous example. This can then result in the following miscompile:

----
%1 = ref_to_unowned %0
strong_retain_unowned %1
...
strong_release %0
----

In this case, it is possible that we created a lifetime gap that will then cause
strong_retain_unowned to assert. By not lowering copy_unowned_value throughout
the SIL pipeline, we instead get this after lowering:

----
strong_retain %0 : $Builtin.NativeObject
%1 = ref_to_unowned %0
%2 = copy_unowned_value %1
strong_release %0
...
strong_release %2
----

And we do not miscompile since we preserved the high level rc identity
pairing.

There shouldn't be any performance impact since we do not really optimize
strong_retain_unowned at the SIL level. I went through all of the places that
strong_retain_unowned was referenced and added appropriate handling for
copy_unowned_value.

rdar://41328987

**NOTE** I am going to remove strong_retain_unowned in a forthcoming commit. I
just want something more minimal for cherry-picking purposes.
2018-06-27 13:02:58 -07:00
Slava Pestov
dbc8d5eb13 DebugInfo: Remove some code for InOutType that no longer makes sense 2018-06-13 15:50:10 -07:00
Adrian Prantl
a95791c1b8 Fix bugs that caused IRGen to behave differently when debug info was enabled.
It hass been a longstanding principle in LLVM that the presence of
debug info shall not affect code generation. This patch brings the
Swift frontend closer to this ideal:

- unconditionally emit shadow copies
- unconditionally bind type metadata

The extra allocas, bitcasts, geps, and stores being emitted get
optimized away when compiling at anything but -Onone. There are few
use-cases for compiling at -Onone without -g, so this shouldn't affect
performance for any real-world use-cases.
2018-06-01 11:17:39 -07:00
Davide Italiano
cbac4b112f [IRGenSIL] Add a comment explaining why we're resetting the location. 2018-05-25 16:34:36 -07:00
Adrian Prantl
c241ff305e Emit compiler-generated debug locations for outlined transparent functions.
In the majority of the use-cases transparent functions are inlined by
the mandatory inliner which by design drops all debug info and
pretends the inlined instructions were always part of the
caller. Since an outlined copy of the function is often still
generated, attaching debug locations to it is inconsistent and can
create the false impression that it were possible to set a breakpoint
in such a function when in reality these functions are only there for
very few edge cases.

<rdar://problem/40258813>
2018-05-17 16:38:04 -07:00
Doug Gregor
74902897e7 [IRGen] Eliminate SubstitutionList from IRGen. 2018-05-11 17:37:26 -07:00
Doug Gregor
d457f1c752 [IRGen/SIL] More widespread use of SubstitutionMap. 2018-05-11 13:18:06 -07:00
Davide Italiano
119e2b64e6 Merge pull request #16486 from dcci/garbageshadow
[IRGen] Zero-init stack shadow copies of values at -Onone.
2018-05-11 09:42:22 -07:00
Davide Italiano
ddf5130806 [IRGen] Zero-init stack shadow copies of values at -Onone.
We already zero init AllocStack, and here's the same.
The debugger's variable view shows up variables on the line
where they're declared (before they've been initialized).
In some cases, we just print garbage. In some others, it's
dangerous (imagine an array which we believe has 2^32 elements
because we ended up reusing a stack slot). This way it's always
consistent, as lldb uses the first word to understand whether
an object is initialized or not here.

Fixes <rdar://problem/39883298>
2018-05-10 14:50:06 -07:00
Andrew Trick
dda3d7be36 [exclusivity] Make KeyPath enforcement an error in Swift 3 mode.
Modify IRGen to emit builtin access markers with an error flag in
Swift 3 mode.

KeyPath enforcement is required by user code in Swift 4+ mode, but is
implemented within the standard library. A [builtin] flag marks the
special case for access generated by Builtins so that they are
always enforced as an error regardless of the language mode.

This is necessary for Swift 4.2 because the standard library continues
to build in Swift 3 mode. Once the standard library build migrates,
this is all irrelevant.

This does not actually affect existing Swift 3 code, since the KeyPath
feature wasn't introduced until Swift 4.

<rdar://problem/40115738> [Exclusivity] Enforce Keypath access as an error, not a warning in 4.2.
2018-05-09 22:52:42 -07:00
Arnold Schwaighofer
9ba545d280 IRGen: Make sure we compare equal units in type size comparison
This is in some code to initialize variables for the debugger.

From the original commit
"Zero-initialize uninitialized Dictionary variables for the debugger.

To avoid the debugger displaying garbage or having expressions crash
when inspecting an uninitialized dictionary variable, zero-initialize
the first word of the alloca at -Onone.
"

Unfortunately, we are comparing different quantities in that code.

rdar://40043512
2018-05-08 13:09:47 -07:00
David Zarzycki
8c0c55539f [SIL] NFC: Rename misleading getSwiftRValueType() to getASTType()
Reference storage types are not RValues. Also, use more SILType helper
methods to avoid line wrap.
2018-05-04 08:14:38 -04:00
Doug Gregor
7e08b66499 [SIL] Use SubstitutionMap in KeyPathInst rather than SubstitutionList. 2018-05-03 08:48:54 -07:00
Doug Gregor
d2cf60c465 Revert "[SIL] Replace more SubstitutionLists with SubstitutionMap" 2018-05-03 08:35:20 -07:00
Doug Gregor
a6dfe0ff88 [SIL] Use SubstitutionMap in KeyPathInst rather than SubstitutionList. 2018-05-03 00:05:21 -07:00
Arnold Schwaighofer
1f65ee25f6 Distinguish between withoutActuallyEscaping and passing @noescape
Objective C closures when reporting that a closure has escaped

rdar://39682865
2018-05-01 07:24:19 -07:00
Arnold Schwaighofer
16c4d650e7 SIL: Allow is_escaping_closure on optional closure types
rdar://39682865
2018-05-01 07:24:19 -07:00
Arnold Schwaighofer
678a99e76a Add a copy_block_without_escaping %block withoutEscaping %closure instruction
Mandatory pass will clean it up and replace it by a copy_block and
is_escaping/cond_fail/release combination on the %closure in follow-up
patches.

The instruction marks the dependence of a block on a closure that is
used as an 'withoutActuallyEscaping' sentinel.

rdar://39682865
2018-05-01 07:24:19 -07:00
Adrian Prantl
49b40e743d Zero-initialize uninitialized Dictionary variables for the debugger.
To avoid the debugger displaying garbage or having expressions crash
when inspecting an uninitialized dictionary variable, zero-initialize
the first word of the alloca at -Onone.

<rdar://problem/36619561>
2018-04-23 14:23:10 -07:00
Vedant Kumar
c94874460d [DebugInfo] Set the autogenerated bit to request recycled locations
IRGenDebugInfo expects to see an autogenerated bit before allowing reuse
of the last seen debug location for a new instruction.

rdar://28544248
(cherry picked from commit 5f6d8e8c8c)
2018-04-16 10:35:18 -07:00
Vedant Kumar
6b1372206a [DebugInfo] Remove a default location argument from setCurrentLoc
Having a default location of None doesn't seem to enhance readability.

(cherry picked from commit c3ba8ff1ff)
2018-04-16 10:35:18 -07:00
Andrew Trick
53a0676cc2 Revert "[DebugInfo] Set the autogenerated bit to request recycled locations" 2018-04-14 18:48:31 -07:00
Vedant Kumar
5f6d8e8c8c [DebugInfo] Set the autogenerated bit to request recycled locations
IRGenDebugInfo expects to see an autogenerated bit before allowing reuse
of the last seen debug location for a new instruction.

rdar://28544248
2018-04-13 14:38:54 -07:00
Vedant Kumar
c3ba8ff1ff [DebugInfo] Remove a default location argument from setCurrentLoc
Having a default location of None doesn't seem to enhance readability.
2018-04-13 14:38:54 -07:00
Joe Groff
a4aa054838 IRGen: Make type(of:) behavior consistent in ObjC bridged contexts.
When we use type(of: x) on a class in an ObjC bridged context, the optimizer turns this into a SIL `value_metatype @objc` operation, which is supposed to get the dynamic type of the object as an ObjC class. This was previously lowered by IRGen into a `object_getClass` call, which extracts the isa pointer from the object, but is inconsistent with the `-class` method in ObjC or with the Swift-native behavior, which both look through artificial subclasses, proxies, and so on. This inconsistency led to observably different behavior between debug and release builds and between ObjC-bridged and native entry points, so provide an alternative runtime entry point that replicates the behavior of getting a native Swift class. Fixes SR-7258.
2018-04-06 15:17:04 -07:00
Adrian Prantl
6632a200f2 Represent indirect function arguments in the DWARF expression instead of the type.
The current approach has several problems:

- Types that are not inout types but loadable may incorrectly get
  marked as inout types.

- When inout arguments get inlined or otherwise optimized LLDB cannot
  rely on the type to decide to dereference that value.

- One argument may get represented by different types in the same
  function depending on what code is generated for it.

Fixes rdar://problem/rdar://problem/39023374
2018-04-03 09:46:58 -07:00
Andrew Trick
02e4429dba Full IRGen support for begin_access [no_nested_conflict].
Suppress generation of the endAccess runtime call when the
begin_access was a "non-tracking" access.
2018-03-31 16:44:27 -07:00
Andrew Trick
14649ae49e Add IRGen support for begin_access [no_nested_conflict]. 2018-03-27 12:04:32 -07:00
Sho Ikeda
3eecb49c55 Merge pull request #15514 from ikesyo/irgen-using-over-typedef
[gardening][IRGen] Replace `typedef` with `using`
2018-03-27 22:50:36 +09:00
Slava Pestov
c31620d302 IRGen: Mangle generic signature and type for outlined thunks 2018-03-26 19:39:26 -07:00
Sho Ikeda
08644c1d8f [gardening][IRGen] Replace typedef with using 2018-03-27 09:06:33 +09:00
John McCall
a906f43329 Allow type metadata to be incomplete.
Most of the work of this patch is just propagating metadata states
throughout the system, especially local-type-data caching and
metadata-path resolution.  It took a few design revisions to get both
DynamicMetadataRequest and MetadataResponse to a shape that felt
right and seemed to make everything easier.

The design is laid out pretty clearly (I hope) in the comments on
DynamicMetadataRequest and MetadataResponse, so I'm not going to
belabor it again here.  Instead, I'll list out the work that's still
outstanding:

- I'm sure there are places we're asking for complete metadata where
  we could be asking for something weaker.

- I need to actually test the runtime behavior to verify that it's
  breaking the cycles it's supposed to, instead of just not regressing
  anything else.

- I need to add something to the runtime to actually force all the
  generic arguments of a generic type to be complete before reporting
  completion.  I think we can get away with this for now because all
  existing types construct themselves completely on the first request,
  but there might be a race condition there if another asks for the
  type argument, gets an abstract metadata, and constructs a type with
  it without ever needing it to be completed.

- Non-generic resilient types need to be switched over to an IRGen
  pattern that supports initialization suspension.

- We should probably space out the MetadataStates so that there's some
  space between Abstract and Complete.

- The runtime just calmly sits there, never making progress and
  permanently blocking any waiting threads, if you actually form an
  unresolvable metadata dependency cycle.  It is possible to set up such
  a thing in a way that Sema can't diagnose, and we should detect it at
  runtime.  I've set up some infrastructure so that it should be
  straightforward to diagnose this, but I haven't actually implemented
  the diagnostic yet.

- It's not clear to me that swift_checkMetadataState is really cheap
  enough that it doesn't make sense to use a cache for type-fulfilled
  metadata in associated type access functions.  Fortunately this is not
  ABI-affecting, so we can evaluate it anytime.

- Type layout really seems like a lot of code now that we sometimes
  need to call swift_checkMetadataState for generic arguments.  Maybe
  we can have the runtime do this by marking low bits or something, so
  that a TypeLayoutRef is actually either (1) a TypeLayout, (2) a known
  layout-complete metadata, or (3) a metadata of unknown state.  We could
  do that later with a flag, but we'll need to at least future-proof by
  allowing the runtime functions to return a MetadataDependency.
2018-03-26 12:18:04 -04:00
Vedant Kumar
3bdcb00b0f [IRGenSIL] Force early materialization of liverange-extended values
At -Onone, we may opt to extend the liverange of a value by inserting
fake uses of the value in blocks which postdominate its def. This keeps
values available throughout the entirety of a function when stepping
through it in a debugger.

This patch makes it so that we also insert a fake use at the start of a
value's lifetime. This forces early materialization of the value, i.e it
becomes available for inspection in a debugger as soon as it's defined.

This is useful when a value has no uses except fake uses. In such cases,
ISel may (correctly!) decide to materialize the value at the end of its
scope. This is really unintuitive and unhelpful for users, because you
need to be done stepping through the value's scope before you can
inspect it.

For the same reasons, forcing early materialization is also useful when
a value *does* have uses. Consider:

  let d = ...
  print("Here is the value of d: \(d)")

Without early materialization, if you set a breakpoint on the line
containing the print, you would not be able to inspect "d". That's
because "d" would be materialized right before string interpolation
happens, which is *after* the breakpoint PC.

rdar://38465084
2018-03-22 18:15:51 -07:00
Vedant Kumar
f98ab4a1c7 [IRGenSIL] Break up and simplify liverange extension logic, NFC
Split out the logic to emit lifetime-extending inline assembly gadgets
into emitLifetimeExtendingUse().
2018-03-22 16:01:46 -07:00
John McCall
aaa40ee82b Move metadata-accessing IRGen out of GenMeta. NFC.
Abstract type/heap metadata access goes into MetadataRequest.
Metadata access starting from a heap object goes into GenHeap.
Accessing various components of class metadata goes into GenClass
or MetadataLayout.
2018-03-18 23:53:11 -04:00
Joe Groff
c0629d2240 IRGen: Set CurSourceFile for SIL functions using the module's associated context.
SIL functions might be associated with decls from other source files whose symbols we can't necessarily locally link to. The module should be associated with the SourceFile that was compiled.
2018-03-13 14:20:52 -07:00
Joe Groff
0bd90e0f13 IRGen: Set IGM.CurSourceFile while emitting SILFunctions.
This makes it more likely we'll do optimizations that are currently scoped to same-SourceFile references, such as direct relative references or symbolic references in mangling, in codegen that gets triggered on behalf of a SILFunction. Should be NFC, aside from some tiny code size improvement.
2018-03-09 12:12:11 -08:00
Arnold Schwaighofer
5940796cc1 SIL: Add an is_escaping_closure instruction
Will be used to verify that withoutActuallyEscaping's block does not
escape the closure.

``%escaping = is_escaping_closure %closure`` tests the reference count. If the
closure is not uniquely referenced it prints out and error message and
returns true. Otherwise, it returns false. The returned result can be
used with a ``cond_fail %escaping`` instruction to abort the program.

rdar://35525730
2018-03-07 08:56:00 -08:00
swift-ci
d468dcb108 Merge pull request #14767 from adrian-prantl/37720555 2018-02-21 13:10:45 -08:00
Adrian Prantl
9b6a9946ec Be explicit about whether a DebugInfo-carying SILInstruction has debug info.
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.

Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.

rdar://problem/37720555
2018-02-21 10:50:19 -08:00
Vedant Kumar
132bb19274 [IRGen] Avoid generating mergeable traps
Factor out and reuse logic in the lowering of CondFailInst to emit
non-mergeable traps, everywhere we emit traps. This should address a
debugging quality issue with ambiguous ud2 instructions.

rdar://32772768
2018-02-20 13:40:40 -08:00
Adrian Prantl
3c96333929 Emit debug info shadow copies of the addresses of dynamic allocas.
Whan an alloca is dynamic, all FastISel can do is describe the
register in which the address of of the dynamic alloca is kept, and if
the value isn't used it will get kicked out by regalloc.

rdar://problem/36663932
2018-02-15 10:00:33 -08:00
Adrian Prantl
56d8a8dfe9 When generating debug info for AllocStackInst, make sure to describe the alloca.
This way an llvm.dbg.declare instrinsic is used, which is valid for
the entire lifetime of the alloca.

rdar://problem/36663932
2018-02-14 11:12:48 -08:00
Arnold Schwaighofer
a9fa8c9c2b Merge pull request #14514 from aschwaighofer/wip_closure_capture_abi_part2
WIP: Closure ABI - Make @noescape Swift closures trivial
2018-02-14 05:19:25 -08:00
Joe Shajrawi
102b6f0b61 Merge pull request #14587 from shajrawi/newinstr
Optimizer peephole for tagged BridgeObjects
2018-02-13 07:38:53 -08:00
Arnold Schwaighofer
882059674f IRGen: Support for trivial @noescape function types
- make @noescape function types trivial
- think_to_thick_function with @noescape result type
- Fix for getSwiftFunctionPointerCallee

Part of:
SR-5441
rdar://36116691
2018-02-13 04:19:59 -08:00
Joe Shajrawi
f732ea66ef Builtins: add ValueToBridgeObject instruction 2018-02-12 13:27:59 +02:00