Commit Graph

175 Commits

Author SHA1 Message Date
Artur Pilipenko 21472910c1 [LVI] NFC. Extract LHS, RHS, Predicate locals in getValueFromCondition
llvm-svn: 278007
2016-08-08 14:08:37 +00:00
Artur Pilipenko 2e19f59304 [LVI] NFC. Sink a condition type check from the caller down to getValueFromCondition
This is a preparatory refactoring to support conditions other than ICmpInst.

llvm-svn: 277479
2016-08-02 16:20:48 +00:00
Artur Pilipenko 2a8f96f5bc [LVI] NFC. Fix a typo getValueFromFromCondition -> getValueFromCondition
llvm-svn: 277466
2016-08-02 14:44:32 +00:00
Justin Lebar 58b377e87d [LVI] Use DenseMap::find_as in LazyValueInfo.
Summary:
This lets us avoid creating and destroying a CallbackVH every time we
check the cache.

This is good for a 2% e2e speedup when compiling one of the large Eigen
tests at -O3.

FTR, I tried making the ValueCache hashtable one-level -- i.e., mapping
a pair (Value*, BasicBlock*) to a lattice value, and that didn't seem to
provide any additional improvement.  Saving a word in LVILatticeVal by
merging the Tag and Val fields also didn't yield a speedup.

Reviewers: reames

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D21951

llvm-svn: 276926
2016-07-27 22:33:36 +00:00
NAKAMURA Takumi bd072a9220 Trailing whitespace.
llvm-svn: 276596
2016-07-25 00:59:46 +00:00
NAKAMURA Takumi 4cb46e6747 Reformat blank lines.
llvm-svn: 274481
2016-07-04 01:26:33 +00:00
NAKAMURA Takumi f252951e90 Reformat comment lines.
llvm-svn: 274480
2016-07-04 01:26:27 +00:00
NAKAMURA Takumi 940cd9368d Untabify.
llvm-svn: 274479
2016-07-04 01:26:21 +00:00
NAKAMURA Takumi f4c6441b01 Reformat.
llvm-svn: 274478
2016-07-04 01:26:14 +00:00
Benjamin Kramer aa2091505f Apply clang-tidy's modernize-loop-convert to lib/Analysis.
Only minor manual fixes. No functionality change intended.

llvm-svn: 273816
2016-06-26 17:27:42 +00:00
Sean Silva 687019facb [PM] Port LVI to the new PM.
This is a bit gnarly since LVI is maintaining its own cache.
I think this port could be somewhat cleaner, but I'd rather not spend
too much time on it while we still have the old pass hanging around and
limiting how much we can clean things up.
Once the old pass is gone it will be easier (less time spent) to clean
it up anyway.

This is the last dependency needed for porting JumpThreading which I'll
do in a follow-up commit (there's no printer pass for LVI or anything to
test it, so porting a pass that depends on it seems best).

I've been mostly following:
r269370 / D18834 which ported Dependence Analysis
r268601 / D19839 which ported BPI

llvm-svn: 272593
2016-06-13 22:01:25 +00:00
Benjamin Kramer c321e53402 Apply most suggestions of clang-tidy's performance-unnecessary-value-param
Avoids unnecessary copies. All changes audited & pass tests with asan.
No functional change intended.

llvm-svn: 272190
2016-06-08 19:09:22 +00:00
Davide Italiano bd543d0a0b [LazyValueInfo] Simplify `return after else`. NFCI.
llvm-svn: 270779
2016-05-25 22:29:34 +00:00
John Regehr e1c481dccf [LVI] Add an API to LazyValueInfo so that it can export ConstantRanges
that it computes. Currently this is used for testing and precision
tuning, but it might be used by optimizations later.

Differential Revision: http://reviews.llvm.org/D19179

llvm-svn: 268291
2016-05-02 19:58:00 +00:00
Philip Reames c67651dd70 [LVI] Delete stale and misleading comment.
llvm-svn: 267661
2016-04-27 03:03:15 +00:00
Philip Reames 2ab964e263 [LVI] Add a comment explaining a subtle piece of code
Or at least, I didn't understand the implications the first several times I read it it.

llvm-svn: 267648
2016-04-27 01:02:25 +00:00
Philip Reames 3f83dbeed9 [LVI] Reduce compile time by lazily scanning blocks if needed
When encountering a non-local pointer, LVI would eagerly scan the block for dereferences of the given object to prove the pointer to be non null.  That's all well and good, but *then* we'd go recurse through our input blocks.  As a result, we could end up scanning each and every block we traverse, even if the final definition was obviously non null or we found a constant value somewhere up the chain.  The previous code papered over this by using the isKnownNonNull routine from value tracking.  This made the duplication less painful in the common case.

Instead, we know do the block scan only *after* we've gotten the recursive results back.  This lets us stop scanning individual blocks as soon as we've determined it to be non-null in any predecessor block and use our usual merge rules to propagate that information cheaply through successor blocks.  For a pointer which can be found non-null, this does strictly less work and sometimes substaintially so.

Note that the case where we *can't* prove something non-null is still the really expensive case.  We end up scanning each and every block looking for a dereference and never end up finding one.

llvm-svn: 267642
2016-04-27 00:30:55 +00:00
Philip Reames f105db4fc3 [LVI] Cut short search if we know we can't return a useful result
Previously we were recursing on our operands for unary and binary operators regardless of whether we knew how to reason about the operator in question.  This has the effect of doing a potentially large amount of work, only to throw it away.  By checking whether the operation is one LVI can handle, we can cut short the search and return the (overdefined) answer more quickly.  The quality of the results produced should not change.

llvm-svn: 267626
2016-04-26 23:27:33 +00:00
Philip Reames 053c2a6f25 [LVI] Apply transfer rule for overdefine inputs for binary operators
As pointed out by John Regehr over in http://reviews.llvm.org/D19485, LVI was being incredibly stupid about applying its transfer rules.  Rather than gathering local facts from the expression itself, it was simply giving up entirely if one of the inputs was overdefined.  This greatly impacts the precision of the overall analysis and makes it far more fragile as well.

This patch builds on 267609 which did the same thing for unary casts.

llvm-svn: 267620
2016-04-26 23:10:35 +00:00
Philip Reames e5030e85ea [LVI] A better fix for the assertion error introduced by 267609
Essentially, I was using the wrong size function.  For types which were sized, but not primitive, I wasn't getting a useful size for the operand and failed an assert.  I fixed this, and also added a guard that the input is a sized type.  Test case is for the original mistake.  I'm not sure how to actually exercise the sized type check.

llvm-svn: 267618
2016-04-26 22:52:30 +00:00
Philip Reames d5c62a0aad [LVI] Speculative fix for assertion seen in clang bots
I'll clean this up and add a test case shortly.  I want to make sure this does actually fix the bots; if not, I'll revert.

llvm-svn: 267617
2016-04-26 22:31:53 +00:00
Philip Reames 38c87c2e50 [LVI] Infer local facts from unary expressions
As pointed out by John Regehr over in http://reviews.llvm.org/D19485, LVI was being incredibly stupid about applying its transfer rules. Rather than gathering local facts from the expression itself, it was simply giving up entirely if one of the inputs was overdefined. This greatly impacts the precision of the overall analysis and makes it far more fragile as well.

This patch implements only the unary operation case. Once this is in, I'll implement the same for the binary operations.

Differential Revision: http://reviews.llvm.org/D19492

llvm-svn: 267609
2016-04-26 21:48:16 +00:00
Philip Reames 1918384155 [LVI] Make a precondition explicit rather than handling a case which never happens [NFC]
llvm-svn: 267481
2016-04-25 22:21:24 +00:00
Philip Reames 3bb2832900 [LVI] Clarify comments describing the lattice values
There has been much recent confusion about the partition in the lattice between constant and non-constant values.  Hopefully, documenting this will prevent confusion going forward.

llvm-svn: 267440
2016-04-25 18:48:43 +00:00
Philip Reames 6671577eb3 [LVI] Split solveBlockValueConstantRange into two [NFC]
This function handled both unary and binary operators.  Cloning and specializing leads to much easier to follow code with minimal duplicatation.

llvm-svn: 267438
2016-04-25 18:30:31 +00:00
Philip Reames a0c9f6e736 [LVI] Fix a bug which prevented use of !range metadata within a query
The diff is relatively large since I took a chance to rearrange the code I had to touch in a more obvious way, but the key bit is merely using the !range metadata when we can't analyze the instruction further.  The previous !range metadata code was essentially just dead since no binary operator or cast will have !range metadata (per Verifier) and it was otherwise dropped on the floor.

llvm-svn: 262751
2016-03-04 22:27:39 +00:00
Philip Reames 70b391864d Suppress an uncovered switch warning [NFC]
llvm-svn: 262109
2016-02-27 05:18:30 +00:00
Philip Reames adf0e35308 [LVI] Extend select handling to catch min/max/clamp idioms
Most of this is fairly straight forward. Add handling for min/max via existing matcher utility and ConstantRange routines.  Add handling for clamp by exploiting condition constraints on inputs.  

Note that I'm only handling two constant ranges at this point. It would be reasonable to consider treating overdefined as a full range if the instruction is typed as an integer, but that should be a separate change.

Differential Revision: http://reviews.llvm.org/D17184

llvm-svn: 262085
2016-02-26 22:53:59 +00:00
Benjamin Kramer 2337c1fe13 [LVI] Move ConstantRanges instead of copying.
No functional change intended. Copying small (<= 64 bits) APInts isn't
expensive but bloats code by generating the slow path everywhere. Moving
doesn't care about the size of the value.

llvm-svn: 261426
2016-02-20 10:40:34 +00:00
Philip Reames 845435c86a Revert 260705, it appears to be causing pr26628
The root issue appears to be a confusion around what makeNoWrapRegion actually does.   It seems likely we need two versions of this function with slightly different semantics.

llvm-svn: 260981
2016-02-16 17:14:30 +00:00
Philip Reames 2b9100dfbd [LVI] Exploit nsw/nuw when computing constant ranges
As the title says. Modelled after similar code in SCEV.

This is useful when analysing induction variables in loops which have been canonicalized by other passes. I wrote the tests as non-loops specifically to avoid the generality introduced in http://reviews.llvm.org/D17174. While that can handle many induction variables without *needing* to exploit nsw, there's no reason not to use it if we've already proven it.

Differential Revision: http://reviews.llvm.org/D17177

llvm-svn: 260705
2016-02-12 19:05:16 +00:00
Philip Reames 854a84c0b0 [LVI] Improve select handling to use condition
This patches teaches LVI to recognize clamp idioms (e.g. select(a > 5, a, 5) will always produce something greater than 5.

The tests end up being somewhat simplistic because trying to exercise the case I actually care about (a loop with a range check on a clamped secondary induction variable) ends up tripping across a couple of other imprecisions in the analysis. Ah, the joys of LVI...

Differential Revision: http://reviews.llvm.org/D16827

llvm-svn: 260627
2016-02-12 00:09:18 +00:00
Philip Reames bb781b46e2 [LVI] Handle constants defensively
There's nothing preventing callers of LVI from asking for lattice values representing a Constant.  In fact, given that several callers are walking back through PHI nodes and trying to simplify predicates, such queries are actually quite common.  This is mostly harmless today, but we start volatiling assertions if we add new calls to getBlockValue in otherwise reasonable places.

Note that this change is not NFC.  Specifically:
1) The result returned through getValueAt will now be more precise.  In principle, this could trigger any latent infinite optimization loops in callers, but in practice, we're unlikely to see this.
2) The result returned through getBlockValueAt is potentially weakened for non-constants that were previously queried.  With the old code, you had the possibility that a later query might bypass the cache and discover some information the original query did not.  I can't find a scenario which actually causes this to happen, but it was in principle possible.  On the other hand, this may end up reducing compile time when the same value is queried repeatedly.  

llvm-svn: 260439
2016-02-10 21:46:32 +00:00
Philip Reames b7571043f2 [LVI] Fix debug output
Due to staleness in a patch I committed yesterday, the debug output was reporting overdefined cases as being undefined.  Confusing to say the least.  The mistake appears to have only effected the debug output thankfully.

llvm-svn: 259594
2016-02-02 22:43:08 +00:00
Philip Reames ed8cd0d36e [LVI] Code motion only [NFC]
I introduced a declaration in 259583 to keep the diff readable.  This change just moves the definition up to remove the declaration again.

llvm-svn: 259585
2016-02-02 22:03:19 +00:00
Philip Reames d1f829d374 [LVI] Refactor to use newly introduced intersect utility
This patch uses the newly introduced 'intersect' utility (from 259461: [LVI] Introduce an intersect operation on lattice values) to simplify existing code in LVI.

While not introducing any new concepts, this change is probably not NFC.  The common 'intersect' function is more powerful that the ad-hoc implementations we'd had in a couple of places.  Given that, we may see optimizations triggering a bit more often.

llvm-svn: 259583
2016-02-02 21:57:37 +00:00
Philip Reames 44456b8963 [LVI] Introduce an intersect operation on lattice values
LVI has several separate sources of facts - edge local conditions, recursive queries, assumes, and control independent value facts - which all apply to the same value at the same location. The existing implementation was very conservative about exploiting all of these facts at once.

This change introduces an "intersect" function specifically to abstract the action of picking a good set of facts from all of the separate facts given. At the moment, this function is relatively simple (i.e. mostly just reuses the bits which were already there), but even the minor additions reveal the inherent power. For example, JumpThreading is now capable of doing an inductive proof that a particular value is always positive and removing a half range check.

I'm currently only using the new intersect function in one place. If folks are happy with the direction of the work, I plan on making a series of small changes without review to replace mergeIn with intersect at all the appropriate places.

Differential Revision: http://reviews.llvm.org/D14476

llvm-svn: 259461
2016-02-02 03:15:40 +00:00
Philip Reames 2c275cc686 [LVI] Fix a latent bug in getValueAt
This routine was returning Undefined for most queries.  This was utterly wrong.  Amusingly, we do not appear to have any callers of this which are actually trying to exploit unreachable code or this would have broken the world.

A better approach would be to explicit describe the intersection of facts.  That's blocked behind http://reviews.llvm.org/D14476 and I wanted to fix the current bug.

llvm-svn: 259446
2016-02-02 00:45:30 +00:00
Philip Reames 13f7324b86 [LVI] Remove overly tight assert from 259429
I'll submit a test case shortly which covers this, but it's causing clang self host problems in the builders so I wanted to get it removed.

llvm-svn: 259432
2016-02-01 23:21:11 +00:00
Philip Reames c0bdb0c1e5 [LVI] Add select handling
Teach LVI to handle select instructions in the exact same way it handles PHI nodes.  This is useful since various parts of the optimizer convert PHI nodes into selects and we don't want these transformations to cause inferior optimization.  

Note that this patch does nothing to exploit the implied constraint on the inputs represented by the select condition itself.  That will be a later patch and is blocked on http://reviews.llvm.org/D14476

llvm-svn: 259429
2016-02-01 22:57:53 +00:00
Akira Hatanaka 2992beec00 [LazyValueInfo] Stop inserting overdefined values into ValueCache to
reduce memory usage.

Previously, LazyValueInfoCache inserted overdefined lattice values into
both ValueCache and OverDefinedCache. This wasn't necessary and was
causing LazyValueInfo to use an excessive amount of memory in some cases.

This patch changes LazyValueInfoCache to insert overdefined values only
into OverDefinedCache. The memory usage decreases by 70 to 75% when one
of the files in llvm is compiled.

rdar://problem/11388615

Differential revision: http://reviews.llvm.org/D15391

llvm-svn: 255320
2015-12-11 00:49:47 +00:00
Philip Reames aeefae0cc5 [LVI] Update a comment to clarify what's actually happening and why
llvm-svn: 252033
2015-11-04 01:47:04 +00:00
Philip Reames 70efccd7dd Fix an unused variable warning which broke the clang-cmake-mips builder
llvm-svn: 251614
2015-10-29 04:21:49 +00:00
Philip Reames eb3e9dad7f [LVI/CVP] Teach LVI about range metadata
Somewhat shockingly for an analysis pass which is computing constant ranges, LVI did not understand the ranges provided by range metadata.

As part of this change, I included a change to CVP primarily because doing so made it much easier to write small self contained test cases. CVP was previously only handling the non-local operand case, but given that LVI can sometimes figure out information about instructions standalone, I don't see any reason to restrict this.  There could possibly be a compile time impact from this, but I suspect it should be minimal.  If anyone has an example which substaintially regresses, please let me know.  I could restrict the block local handling to ICmps feeding Terminator instructions if needed.  

Note that this patch continues a somewhat bad practice in LVI. In many cases, we know facts about values, and separate context sensitive facts about values. LVI makes no effort to distinguish and will frequently cache the same value fact repeatedly for different contexts. I would like to change this, but that's a large enough change that I want it to go in separately with clear documentation of what's changing. Other examples of this include the non-null handling, and arguments.

As a meta comment: the entire motivation of this change was being able to write smaller (aka reasonable sized) test cases for a future patch teaching LVI about select instructions.

Differential Revision: http://reviews.llvm.org/D13543

llvm-svn: 251606
2015-10-29 03:57:17 +00:00
Igor Laevsky 0fa4819dd8 [LazyValueInfo] Report nonnull range for nonnull pointers
Currently LazyValueInfo will report only alloca's as having nonnull range. 
For loads with !nonnull metadata it will bailout with no additional information. 
Same is true for calls returning nonnull pointers.

This change extends LazyValueInfo to handle additional nonnull instructions.

Differential Revision: http://reviews.llvm.org/D12932

llvm-svn: 247985
2015-09-18 13:01:48 +00:00
Philip Reames bb11d62a5a [LazyValueInfo] Look through Phi nodes when trying to prove a predicate
If asked to prove a predicate about a value produced by a PHI node, LazyValueInfo was unable to do so even if the predicate was known to be true for each input to the PHI. This prevented JumpThreading from eliminating a provably redundant branch.

The problematic test case looks something like this:
ListNode *p = ...;
while (p != null) {
  if (!p) return;
  x = g->x; // unrelated
  p = p->next
}

The null check at the top of the loop is redundant since the value of 'p' is null checked on entry to the loop and before executing the backedge. This resulted in us a) executing an extra null check per iteration and b) not being able to LICM unrelated loads after the check since we couldn't prove they would execute or that their dereferenceability wasn't effected by the null check on the first iteration.

Differential Revision: http://reviews.llvm.org/D12383

llvm-svn: 246465
2015-08-31 18:31:48 +00:00
Bruno Cardoso Lopes 7a1483e7d1 [LVI] Use a SmallVector instead of SmallPtrSet. NFC
llvm-svn: 245739
2015-08-21 21:18:26 +00:00
Bruno Cardoso Lopes ed6b9bfeab [LVI] Avoid iterator invalidation in LazyValueInfoCache::threadEdge
Do that by copying out the elements to another SmallPtrSet.
Follow up from r245309.

llvm-svn: 245590
2015-08-20 18:24:54 +00:00
Bruno Cardoso Lopes 1846ea3c71 [LVI] Use a SmallDenseMap instead of std::map for ValueCacheEntryTy
Historically there seems to be some resistance regarding the change to DenseMap
(r147980). However, I couldn't find cases of iterator invalidation for
ValueCacheEntryTy, but only for ValueCache, which I left untouched.

This reduces 20s on an internal testcase. Follow up from r245309.

Differential Revision: http://reviews.llvm.org/D11651

rdar://problem/21320066

llvm-svn: 245314
2015-08-18 16:54:36 +00:00
Bruno Cardoso Lopes 6ac4ea4d29 [LVI] Improve LazyValueInfo compile time performance
Changes in LoopUnroll in the past six months exposed scalability
issues in LazyValueInfo when used from JumpThreading. One internal test
that used to take 20s under -O2 now takes 6min.

This commit change the OverDefinedCache from
DenseSet<std::pair<AssertingVH<BasicBlock>, Value*>> to
DenseMap<AssertingVH<BasicBlock>, SmallPtrSet<Value *, 4>>
and reduces compile time down to 1m40s.

Differential Revision: http://reviews.llvm.org/D11651

rdar://problem/21320066

llvm-svn: 245309
2015-08-18 16:34:27 +00:00