a fixed size of 16 bytes. 3 pointers is the magic value in
swift: many, many things are better if we can handle three
pointers efficiently.
Swift SVN r2147
which defeated the optimization which formed "retainThree" tail calls. Restructure
and generalize this optimization to handle the new and old forms. Through
the combination of the two, we now form 19 of them on the stdlib. Before I broke
things, we only formed 14 of them.
Swift SVN r2124
This makes the two phases independently testable, but is also the
right thing to do: previously we'd form swift_retain early enough
that inlining would inline them from previously optimized callees
into callers, and this would block some mid-level optimizations
from doing nice things (because swift_retain isn't no-escape).
It's a small thing, but doing this allows us to eliminate a few
more "and x, 9223372036854775807"'s from the stdlib. We also
end up doing a lot less optimizations because we do them early
instead of only having the optimizations exposed after inlining
deeply.
Swift SVN r2114
don't mod/ref any state to swift code. This allows the general LLVM optimizer to be
*much* more aggressive. For example, on swift.swift, GVN deletes 15% more instructions,
jump threading folds 2.4X more terminators, SCCP removes 3.3X more instructions, and 2
more retain/release pairs are removed by the ARC optimizer.
Swift SVN r2113
relevant pieces (a swift_retain_noreturn + some copies). This pessimizes
test2 in rdar://11563395 to generate the same code as test1 in that radar.
Swift SVN r2092
type is either a protocol type or a protocol composition type. The
long form of this query returns the minimal set of protocol
declarations required by that existential type.
Use the new isExistentialType() everywhere that we previously checked
just for ProtocolType, implementing the appropriate rules. Among other
things, this includes:
- Type coercion
- Subtyping relationship
- Checking of explicit protocol conformance
- Member name lookup
Note the FIXME for IR generation; we need to decide how we want to
encode the witnesses for the different protocols.
This is most of <rdar://problem/11548207>.
Swift SVN r2086
protocol conformance types, e.g., 'protocol<P, Q>'. A few things
people *might* want to scream about, or at least scrutinize:
- The parsing of the '<' and '>' is odd, because '<' and '>' aren't
tokens, but are part of the operator grammar. Neither are '>>',
'>>>', '<>', etc., which also come up and need to be parsed
here. Rather than turning anything starting with '<' or '>' into a
different kind of token, I instead parse the initial '<' or '>'
from an operator token and leave the rest of the token as the
remaining operator.
- The canonical form of a protocol-composition type is minimized by
removing any protocols in the list that were inherited by other
protocols in the list, then sorting it. If a singleton list is
left, then the canonical type is simply that protocol type.
- It's a little unfortunate that we now have two existential types
in the system (ProtocolType and ProtocolCompositionType), because
many places will have to check both. Once ProtocolCompositionTypes
are working, we should consider whether it makes sense to remove
ProtocolType.
Still to come: name lookup, coercions.
Swift SVN r2066
don't escape and are only stored to. This is common because other general
LLVM optimizations often forward propagate all the loads out of an object,
making it pointless. This implements rdar://11542745, compiling that example
to:
define void @_T1t1PFT_T_() nounwind {
entry:
tail call void @putchar(i32 32) nounwind
ret void
}
and rdar://11542766 (eliminating the temporary forced onto the stack by &&), compiling
it into:
define i32 @_T1t4testFT1aNSs4Char_NSs6UInt32(i32 %a) nounwind {
entry:
%a.off = add i32 %a, -33
%0 = icmp ult i32 %a.off, 95
%return_value.0.0 = select i1 %0, i32 4, i32 7
ret i32 %return_value.0.0
}
This also deletes 19 objects in the stdlib, though it wildly changes inlining
behavior, so it is hard to exactly measure the impact.
Swift SVN r2052
swift_retain calls. The pertinent difference is that the former can be
marked nocapture, allowing general LLVM optimizations more flexibility.
With this change, early-cse is able to zap 9 more instructions, and 3
more functions are able to be marked nocapture by functionattrs in the
stdlib.
Swift SVN r2043
swift_retain_noresult calls for the duration of optimization. When we're done
hacking on the function, we rewrite all the retain_noresult calls *back* into
swift_retain calls. No functionality change here.
Swift SVN r2039
them from the stdlib: ine from Format.printString.String, and one from Char.printFormatted.
This is also enough to resolve rdar://11542743, allowing us to optimize:
func maxtest(x : Int) -> Int {
return max(x, 0)
}
into:
define i64 @_T1t7maxtestFT1xNSs5Int64_S0_(i64 %x) nounwind {
entry:
%0 = icmp sgt i64 %x, 0
%x.y.i = select i1 %0, i64 %x, i64 0
ret i64 %x.y.i
}
Instead of the mess of retains and releases shown in 11542743.
Swift SVN r2037
cannot affect the lifetime of o1 in a way we care about. This allows
eliminating 5 more retain/release pairs from the stdlib, including
from String(Int128, radix)->String, String(Double)->String,
and the slice reduce methods.
Swift SVN r2036
until we find a retain of the same object. If we find one, zap both. This is good
enough to delete 22 retain/release pairs out of the stdlib, including the one at the
end of String.subscript(rng : IntRange) -> String, which motivated rdar://11537101.
Swift SVN r2035
1. First thing, canonicalize the input IR so that nothing uses the result of
swift_retain, making it easier to reason about pointers.
<nothing in between yet>
2. Last thing, optimize register pressure by making use of the return value
of swift_retain where possible.
#1 is a pessimization, but is fixed (optimally!) by #2. Our implementation
of #2 is more powerful than the ObjC ARC optimizers corresponding stuff, because
we insert PHI nodes etc in cases where there isn't a strictly dominating retain
of a use. Ours is also much simpler :)
Swift SVN r2030