rdar://problem/19701613
Code size reductions (negative means less code size):
bin/PerfTests_O: -3.7%
bin/PerfTests_Ounchecked: -1.9%
bin/PerfTests_Onone: +0.2%
stdlib/core/macosx/Swift.o: -2.2%
The -2.2% in Swift.o constitutes of about +5% in specializations and -11% in protocoll witnesses in the dylib.
(-> still room for improvement regarding specializations)
Note that completely disabling inlining into thunks (even small functions) would increase the code size.
There is litte change in performance, a few + and - within 10%.
Beyond this there is (+ means faster):
Phonebook@O: +26%
ImageProc@Ounchecked: +14%
StringWalk@Ounchecked: -16%
Swift SVN r25001
was incomplete; we do use it on i386 for arbitrary small
aggregates, and unfortunately this means we have to learn
how to expand quite a lot of types.
Tested by the i386-simulator build. I still think
we can completely remove this code relatively soon.
Swift SVN r24981
Specialization can introduce 'A as! B' casts between unrelated types A and B, and we're not always smart enough to fold them away to a failure. We shouldn't crash in IRGen when we see them. Fixes rdar://problem/19544667.
Swift SVN r24971
the C calling convention.
You might notice the absence of tests. Older versions of Clang
used Expand for ARM64 homogeneous aggregates. Trunk Clang no
longer does this, and indeed, on Apple platforms we no longer
use Expand to pass any kind of argument at all. The only target
in trunk that uses it is the Windows target's vectorcall
alternative CC, which I have no way to convince Swift to
generate a call against. Therefore this code is completely
dead in trunk, and thus untestable.
Removing Expand completely from Clang would be the ideal solution,
but that's politically tricky because this is a part of Clang
that's frequently edited by people supporting out-of-tree backends.
I've started the process, but until then, if we're going to have
dead code, it ought to at least be correct dead code.
This commit fixes rdar://19199427, or at least it will
when it's merged to branches that actually use Expand.
Swift SVN r24949
Reapply commit r24722.
The original commit did not break the build. There appears to be an issue in
CoreAutomation (an iOS test failed with empty output). Follow up builds with
the original commit in succeeded.
Also apply Dimitri's patch to make the test condfail.sil portable.
Original message:
This significantly improves debugging experience as failures such as overflow
can be mapped back to a source line.
Code size impacts I measured on PerfTestSuite and libswift*.dylib was
neglectable.
__text section size increase:
0.24% bin/PerfTest_O
0.01% bin/PerfTest_Onone
0.20% libswift*.dylib
rdar://19118593
Swift SVN r24725
This significantly improves debugging experience as failures such as overflow
can be mapped back to a source line.
Code size impacts I measured on PerfTestSuite and libswift*.dylib was
neglectable.
__text section size increase:
0.24% bin/PerfTest_O
0.01% bin/PerfTest_Onone
0.20% libswift*.dylib
rdar://19118593
Swift SVN r24722
Until now, we treated all value parameters as +1, and all indirect parameters as +0 by reference, which is totally bogus. Now that we'll be partially applying guaranteed parameters, for instance to implement SomeType.foo curried method references, we need to get this right.
This breaks curries that capture dependent-layout parameters by value, but they were already broken due to us treating them as 'inout' captures. I'll fix this by adding NecessaryBindings and NonFixedOffsets to HeapLayout next.
Swift SVN r24475
patterns.
<rdar://problem/19184859> Swift methods defining closures that capture self in the "in" clause end up with two "self" variables in the debug info
Swift SVN r24461
emitValueCaseTest/emitIndirectCaseTest implementations when testing for
one case. This leads to dramatically better IRGen for optional (among other
things). For example, for:
class C{}
var x : C?
if let a = x {
}
we used to produce:
%15 = load i64* %14, align 8
switch i64 %15, label %16 [
i64 0, label %17
]
; <label>:16 ; preds = %entry
br label %select_enum
; <label>:17 ; preds = %entry
br label %select_enum
select_enum: ; preds = %17, %16
%18 = phi i1 [ true, %16 ], [ false, %17 ]
br i1 %18, label %22, label %19
now we produce:
%15 = load i64* %14, align 8
%16 = icmp eq i64 %15, 0
%17 = xor i1 %16, true
br i1 %17, label %21, label %18
Hopefully this makes a measurable improvement in the -O0 performance tests, but
I didn't check.
This resolves:
<rdar://problem/19404937> select_enum/select_enum_addr should generate select in obvious cases [-O0 performance]
Swift SVN r24366
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
This commit repplies r24305 with two fixes:
- It fixes the computation of spare bits for unusual
integer types to use the already-agreed-upon type
size instead of recomputing it. This fixes the
i386 stdlib build. Joe and I agreed that we should
also change the size to use the LLVM alloc size
instead of the next power of 2, but this patch
does not do that yet.
- It changes the spare bits in function types back
to the empty set. I'll be changing this in a
follow-up, but it needs to be tied to runtime
changes. This fixes the regression test failures.
Swift SVN r24324
IRGen uses a typedef, SpareBitVector, for its principal
purpose of tracking spare bits. Other uses should not
use this typedef, and I've tried to follow that, but I
did this rewrite mostly with sed and may have missed
some fixups.
This should be almost completely NFC. There may be
some subtle changes in spare bits for witness tables
and other off-beat pointer types. I also fixed a bug
where IRGen thought that thin functions were two
pointers wide, but this wouldn't have affected anything
because we never store thin functions anyway, since
they're not a valid AST type.
Swift SVN r24305
memory layout and add a SelectInst API that allows for one to access select inst
operands when one does not care about what the cases actually are.
Previously select_enum, select_enum_addr had the following memory layout:
[operands], [cases]
In constrast, select_value had the following layout:
[operand1, case1, operand2, case 2, ...]
The layout for select_value makes it impossible to just visit operands in a
generic way via a higher level API. This is an important operation for many
analyses such as AA on select insts.
This commit does the following:
1. Adds a new abstract parent class for all select instructions called
SelectInst.
2. Adds a new templated implementation parent class that inherits from
SelectInst called SelectInstBase. This handles the complete implementation of
select for all types by templating on CaseTy.
3. Changes SelectEnumAddrInst, SelectEnumInst, SelectValueInst to be thin
classes that inherit from the appropriately specialized SelectInstBase.
I left in SelectEnumInstBase for now as a subclass of SelectInstBase and parent
class of SelectEnum{,Addr}Inst since it provides specific enum APIs that are
used all over the compiler. All of these methods have equivalent methods on
SelectInstBase. I just want to leave them for a later commit so that this commit
stays small.
Swift SVN r24159
storage for arbitrary values.
A buffer doesn't provide any way to identify the type of
value it stores, and so it cannot be copied, moved, or
destroyed independently; thus it's not available as a
first-class type in Swift, which is why I've labelled
it Unsafe. But it does allow an efficient means of
opaquely preserving information between two cooperating
functions. This will be useful for the adjustments I
need to make to materializeForSet to support safe
addressors.
I considered making this a SIL type category instead,
like $@value_buffer T. This is an attractive idea because
it's generally better-typed. The disadvantages are that:
- it would need its own address_to_pointer equivalents and
- alloc_stack doesn't know what type will be stored in
any particular buffer, so there still needs to be
something opaque.
This representation is a bit gross, but it'll do.
Swift SVN r23903
It avoids generation of llvm phi nodes with identical predecessors and differing values.
This change replaces my previous fix of this problem in r23580, where I handled it in IRGen.
There were some discussions about it with the conclusion that it's better to just disallow such cond_br instructions in SIL.
It makes the life easier for some SIL optimizations which can't deal with cond_br with identical destinations.
The original radar is <rdar://problem/18568272> Swift compiler fails with "PHI node has multiple entries for the same basic block with different incoming values!"
Swift SVN r23861
Using the intrinsics is obnoxious because I needed them
to return Builtin.NativeObject?, but there's no reasonable
way to safely generate optional types from Builtins.cpp.
Ugh.
Dave and I also decided that there's no need for
swift_tryPin to allow a null object.
Swift SVN r23824
or pointer depends on another for validity in a
non-obvious way.
Also, document some basic value-propagation rules
based roughly on the optimization rules for ARC.
Swift SVN r23695
Phi nodes may not have identical predecessors and differing values.
This should fix <rdar://problem/18568272> Swift compiler fails with "PHI node has multiple entries for the same basic block with different incoming values!"
Swift SVN r23580
variable part of the function prologue by omitting its location.
Fixes <rdar://problem/18989457> Xcode 6.2 6C86C (lldb-320.4.157) : po self returns error: Execution was interrupted, reason: EXC_BAD_ACCESS
Swift SVN r23569
Make it easier to get the "do I expect null ProtocolConformance* pointers" logic right. Audit existing uses of is<ArchetypeType>() for this purpose.
Swift SVN r23479
They don't need storage because they're empty, so we don't emit their offsets, but we still emitted references to their offset variable. Fix this by lowering ref_element_addr to an undef for empty fields.
Swift SVN r23317
Previously, we were not respecting the representation of the existential
metatype and were treating all existential metatypes as if the metatype
was a thick metatype. Instead now we properly grab the instance of the
class from the existential and then query the runtime for the
objc_class. This is done via the new entrypoint
emitHeapMetadataRefForUnknownHeapObject.
I also modified emitHeapMetadataRefForHeapObject to use
emitHeapMetadataRefForUnknownHeapObject instead of
emitLoadOfObjCHeapMetadataRef since the latter does not properly handle
tagged pointers. This bug was found on inspection when Joe and I were
talking about this change.
rdar://18841292
Swift SVN r23308
The code path here is mostly the same as the class cast case--we have to test the ObjC class (if it is a class) against any ObjC protocols, then look up conformances for the native protocols.
Swift SVN r23184
without a valid SILDebugScope. An assertion in IRGenSIL prevents future
optimizations from regressing in this regard.
Introducing SILBuilderWithScope and SILBuilderwithPostprocess to ease the
transition.
This patch is large, but mostly mechanical.
<rdar://problem/18494573> Swift: Debugger is not stopping at the set breakpoint
Swift SVN r22978
This is a type that has ownership of a reference while allowing access to the
spare bits inside the pointer, but which can also safely hold an ObjC tagged pointer
reference (with no spare bits of course). It additionally blesses one
Foundation-coordinated bit with the meaning of "has swift refcounting" in order
to get a faster short-circuit to native refcounting. It supports the following
builtin operations:
- Builtin.castToBridgeObject<T>(ref: T, bits: Builtin.Word) ->
Builtin.BridgeObject
Creates a BridgeObject that contains the bitwise-OR of the bit patterns of
"ref" and "bits". It is the user's responsibility to ensure "bits" doesn't
interfere with the reference identity of the resulting value. In other words,
it is undefined behavior unless:
castReferenceFromBridgeObject(castToBridgeObject(ref, bits)) === ref
This means "bits" must be zero if "ref" is a tagged pointer. If "ref" is a real
object pointer, "bits" must not have any non-spare bits set (unless they're
already set in the pointer value). The native discriminator bit may only be set
if the object is Swift-refcounted.
- Builtin.castReferenceFromBridgeObject<T>(bo: Builtin.BridgeObject) -> T
Extracts the reference from a BridgeObject.
- Builtin.castBitPatternFromBridgeObject(bo: Builtin.BridgeObject) -> Builtin.Word
Presents the bit pattern of a BridgeObject as a Word.
BridgeObject's bits are set up as follows on the various platforms:
i386, armv7:
No ObjC tagged pointers
Swift native refcounting flag bit: 0x0000_0001
Other available spare bits: 0x0000_0002
x86_64:
Reserved for ObjC tagged pointers: 0x8000_0000_0000_0001
Swift native refcounting flag bit: 0x0000_0000_0000_0002
Other available spare bits: 0x7F00_0000_0000_0004
arm64:
Reserved for ObjC tagged pointers: 0x8000_0000_0000_0000
Swift native refcounting flag bit: 0x4000_0000_0000_0000
Other available spare bits: 0x3F00_0000_0000_0007
TODO: BridgeObject doesn't present any extra inhabitants. It ought to at least provide null as an extra inhabitant for Optional.
Swift SVN r22880