The problem here is the infamous one direction known safe. I was
hesitant to turn it off before b/c of the potential for regressions
without an actual bug from users hitting the problem. This is that bug ;
).
The main performance impact of having known safe in both directions is
that often times it is very difficult to find two releases without a use
in-between them since we are so conservative with determining potential
uses. The one direction known safe gets around that problem by taking
advantage of many situations where we have two retains in a row,
allowing us to avoid that problem. That being said, the one direction
known safe is unsafe. Consider the following situation:
retain(x)
retain(x)
call(x)
call(x)
release(x)
Then we know the following about the reference count of x:
// rc(x) == N (for some N).
retain(x)
// rc(x) == N+1
retain(x)
// rc(x) == N+2
call A(x)
call B(x)
// rc(x) >= 1 (since we can not release a deallocated pointer).
release(x)
// rc(x) >= 0
That is all the information that we can know statically. That means that
we know that A(x), B(x) together can release (x) at most N+1 times. Lets
say that we remove the inner retain, release pair.
// rc(x) == N (for some N).
retain(x)
// rc(x) == N+1
call A(x)
call B(x)
// rc(x) >= 1
release(x)
// rc(x) >= 0
We knew before that A(x), B(x) could release x up to N+1 times meaning
that rc(x) may be zero at the release(x). That is not safe. On the other
hand, consider the following situation where we have a must use of
release(x) that x must be kept alive for after the release(x)**. Then we
know that:
// rc(x) == N (for some N).
retain(x)
// rc(x) == N+1
retain(x)
// rc(x) == N+2
call A(x)
call B(x)
// rc(x) >= 2 (since we know that we are going to release x and that that release can not be the last use of x).
release(x)
// rc(x) >= 1 (since we can not deallocate the pointer since we have a must use after x).
…
// rc(x) >= 1
use(x)
Thus we know that statically the calls to A(x), B(x) can together only
release rc(x) N times. Thus if we remove the inner retain, release pair:
// rc(x) == N (for some N).
retain(x)
// rc(x) == N+1
call A(x)
call B(x)
// rc(x) >= 1
…
// rc(x) >= 1
use(x)
We are still safe unless in the final … there are unbalanced retains,
releases which would have caused the program to blow up anyways even
before optimization occurred. The simplest form of must use is an
additional release that has not been paired up with any retain (if we
had paired the release with a retain and removed it we would not have
the additional use). This fits nicely into the ARC framework since
basically what you do is say that given any nested releases regardless
of what is in between, the inner release is known safe. This enables us to get
back the lost performance.
<rdar://problem/19023795>
llvm-svn: 232351
This code was casting regions of a memory buffer to a couple of
different structs. This is wrong in a few ways:
1. It breaks aliasing rules.
2. If the buffer isn't aligned, it hits undefined behaviour.
3. It completely ignores endianness differences.
4. The structs being defined for this aren't specifying their padding
properly, so this doesn't even represent the data properly on some
platforms.
This commit is mostly NFC, except that it fixes reading coverage for
32 bit binaries as a side effect of getting rid of the mispadded
structs. I've included a test for that.
I've also baked in that we only handle little endian more explicitly,
since that was true in practice already. I'll fix this to handle
endianness properly in a followup commit.
llvm-svn: 232346
The information gathering part of the patch stores a bit more information
than what is strictly necessary for these 2 sections. The rest will
become useful when we start emitting __apple_* type accelerator tables.
llvm-svn: 232342
The gotSymbol need not be a global static variable. Apart from this reason, This
variable was creating an issue with self hosting lld, as there seems to be an
issue running global initializers, when initializing the guard for this static
variable.
Program received signal SIGTRAP, Trace/breakpoint trap.
llvm-svn: 232341
Also, after looking at the raw_svector_stream internals, increase the
size of the SmallString used with it to prevent heap allocation.
Issue found by the Asan bot.
llvm-svn: 232335
After much bike shed discussions, we seem to agree to a few loose
but relevant guidelines on how to prepare a commit message. It also
points the attribution section to the new commit messages section
to deduplicate information.
llvm-svn: 232334
This code comes with a lot of cruft that is meant to mimic darwin's
dsymutil behavior. A much simpler approach (described in the numerous
FIXMEs that I put in there) gives the right output for the vast
majority of cases. The extra corner cases that are handled differently
need to be investigated: they seem to correctly handle debug info that
is in the input, but that info looks suspicious in the first place.
Anyway, the current code needs to handle this, but I plan to revisit it
as soon as the big round of validation against the classic dsymutil is
over.
llvm-svn: 232333
No need to emit a DW_LNS_advance_pc with a 0 increment. Found out while
comparing dsymutil's and LLVM's line table encoding. Not a correctenss
fix, just a small encoding size optimization.
I'm not sure how to generate a sequence that triggers this, and moreover
llvm-dwardump doesn't dump the line table program, thus the effort
involved in creating a testcase for this trivial patch seemed out of
proportion.
llvm-svn: 232332
Though common, there is no requirement that fenv_t and fexcept_t are
structure and integer types, respectively. fexcept_t is a structure on
CloudABI.
llvm-svn: 232329
This fixes tests on clang-3.4
AFAICT, these flags have the same affect and -fstandalone-debug wasn't
added until after clang-3.4
Committed to try to fix buildbot
Differential Revision: http://reviews.llvm.org/D8347
llvm-svn: 232326
This basically creates a wrapper around an 'int' that poses as an iterator.
While that looks a bit counter-intuitive it works just fine because iterator
operations and basic integer arithmetic works in exactly the same way.
Remove the manual integer wrapping code and reduce the reliance on iterator
internals in the implementation. No functionality change intended.
llvm-svn: 232322
The current enum detection is overly aggressive. As NestingLevel only
applies per line (?) it classifies many if not most object literals as
enum declarations and adds superfluous line breaks into them. This
change narrows the heuristic by requiring an assignment just before the
open brace and requiring the line to start with an identifier.
Patch by Martin Probst. Thank you.
llvm-svn: 232320
Qualifiers are located next to the TypeDescriptor in order to properly
ensure that a pointer type can only be caught by a more qualified catch
handler. This means that a catch handler of type 'const int *' requires
an RTTI object for 'int *'. We got this correct for 'throw' but not for
'catch'.
N.B. We don't currently have the means to store the qualifiers because
LLVM's EH strategy is tailored to the Itanium scheme. The Itanium ABI
stores qualifiers inside the type descriptor in such a way that the
manner of qualification is stored in addition to the pointee type's
descriptor. Perhaps the best way of modeling this for the MS ABI is
using an aggregate type to bundle the qualifiers with the descriptor?
This is tricky because we want to make it clear to the optimization
passes which catch handlers invalidate other handlers.
My current thoughts on a design for this is along the lines of:
{ { TypeDescriptor* TD, i32 QualifierFlags }, i32 MiscFlags }
The idea is that the inner most aggregate is all that is needed to
communicate that one catch handler might supercede another. The
'MiscFlags' field would be used to hold the bitpattern for the notion
that the 'catch' handler does not need to invoke a copy-constructor
because we are catching by reference.
llvm-svn: 232318
Use an overload instead of a default argument for `Metadata::dump()`.
The latter seems to require calling `dump(nullptr)` explicitly when
using a debugger, where as the former doesn't.
Other than utility for debugging, there's NFC here.
llvm-svn: 232315
The misc-static-assert check will not warn on assert(false), assert(False),
assert(FALSE); where false / False / FALSE are macros expanding to the false or
0 literals.
Also added corresponding test cases.
http://reviews.llvm.org/D8328
Patch by Szabolcs Sipos!
llvm-svn: 232306
The C++ standard reserves all identifiers starting with an underscore
followed by an uppercase letter for the implementation for any use.
llvm-svn: 232302