summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
Commit message (Collapse)AuthorAgeFilesLines
* [PM/AA] Disable the core unsafe aspect of GlobalsModRef in the face ofChandler Carruth2015-07-171-6/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | basic changes to the IR such as folding pointers through PHIs, Selects, integer casts, store/load pairs, or outlining. This leaves the feature available behind a flag. This flag's default could be flipped if necessary, but the real-world performance impact of this particular feature of GMR may not be sufficiently significant for many folks to want to run the risk. Currently, the risk here is somewhat mitigated by half-hearted attempts to update GlobalsModRef when the rest of the optimizer changes something. However, I am currently trying to remove that update mechanism as it makes migrating the AA infrastructure to a form that can be readily shared between new and old pass managers very challenging. Without this update mechanism, it is possible that this still unlikely failure mode will start to trip people, and so I wanted to try to proactively avoid that. There is a lengthy discussion on the mailing list about why the core approach here is flawed, and likely would need to look totally different to be both reasonably effective and resilient to basic IR changes occuring. This patch is essentially the first of two which will enact the result of that discussion. The next patch will remove the current update mechanism. Thanks to lots of folks that helped look at this from different angles. Especial thanks to Michael Zolotukhin for doing some very prelimanary benchmarking of LTO without GlobalsModRef to get a rough idea of the impact we could be facing here. So far, it looks very small, but there are some concerns lingering from other benchmarking. The default here may get flipped if performance results end up pointing at this as a more significant issue. Also thanks to Pete and Gerolf for reviewing! Differential Revision: http://reviews.llvm.org/D11213 llvm-svn: 242512
* Add new constructors for LoopInfo/DominatorTree/BFI/BPICong Hou2015-07-162-0/+12
| | | | | | | | | | | | | | | | | Those new constructors make it more natural to construct an object for a function. For example, previously to build a LoopInfo for a function, we need four statements: DominatorTree DT; LoopInfo LI; DT.recalculate(F); LI.analyze(DT); Now we only need one statement: LoopInfo LI(DominatorTree(F)); http://reviews.llvm.org/D11274 llvm-svn: 242486
* Rename LoopInfo::Analyze() to LoopInfo::analyze() and turn its parameter ↵Cong Hou2015-07-161-2/+2
| | | | | | | | | | type to const&. The benefit of turning the parameter of LoopInfo::analyze() to const& is that it now can accept a rvalue. http://reviews.llvm.org/D11250 llvm-svn: 242426
* Fix memcheck interval ends for pointers with negative stridesSilviu Baranga2015-07-161-2/+18
| | | | | | | | | | | | | | | | | | | | | | | | Summary: The checking pointer grouping algorithm assumes that the starts/ends of the pointers are well formed (start <= end). The runtime memory checking algorithm also assumes this by doing: start0 < end1 && start1 < end0 to detect conflicts. This check only works if start0 <= end0 and start1 <= end1. This change correctly orders the interval ends by either checking the stride (if it is constant) or by using min/max SCEV expressions. Reviewers: anemet, rengolin Subscribers: rengolin, llvm-commits Differential Revision: http://reviews.llvm.org/D11149 llvm-svn: 242400
* [LAA] Split out a helper to check the pointer partitions, NFCAdam Nemet2015-07-161-4/+8
| | | | | | | | | This is made a static public member function to allow the transition of this logic from LAA to LoopDistribution. (Technically, it could be an implementation-local static function but then it would not be accessible from LoopDistribution.) llvm-svn: 242376
* Create a wrapper pass for BranchProbabilityInfo.Cong Hou2015-07-153-49/+63
| | | | | | | | This new wrapper pass is useful when we want to do branch probability analysis conditionally (e.g. only in PGO mode) but don't want to add one more pass dependence. http://reviews.llvm.org/D11241 llvm-svn: 242349
* Rename doFunction() in BFI to calculate() and change its parameters from ↵Cong Hou2015-07-151-1/+1
| | | | | | | | pointers to references. http://reviews.llvm.org/D11196 llvm-svn: 242322
* Analyze recursive PHI nodes in BasicAATobias Edler von Koch2015-07-151-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This patch allows phi nodes like %x = phi [ %incptr, ... ] [ %var, ... ] %incptr = getelementptr %x, 1 to be analyzed by BasicAliasAnalysis. In aliasPHI, we can detect incoming values that are recursive GEPs with a constant offset. Instead of trying to analyze a recursive GEP (and failing), we now ignore it and instead set the size of the memory referenced by the PHINode to UnknownSize. This represents all the possible memory locations the pointer represented by the PHINode could be advanced to by the GEP. For now, this new behavior is turned off by default to allow debugging of performance degradations seen with SPEC/x86 and Hexagon benchmarks. The flag -basicaa-recphi turns it on. Reviewers: hfinkel, sanjoy Subscribers: tobiasvk_caf, sanjoy, llvm-commits Differential Revision: http://reviews.llvm.org/D10368 llvm-svn: 242320
* [PM/AA] Fix *numerous* serious bugs in GlobalsModRef found byChandler Carruth2015-07-151-22/+31
| | | | | | | | | | | | | | | | | | | | | | | | | inspection. While we want to handle calls specially in this code because they should have been modeled by the call graph analysis that precedes it, we should *not* be re-implementing the predicates for whether an instruction reads or writes memory. Those are well defined already. Notably, at least the following issues seem to be clearly missed before: - Ordered atomic loads can "write" to memory by causing writes from other threads to become visible. Similarly for ordered atomic stores. - AtomicRMW instructions quite obviously both read and write to memory. - AtomicCmpXchg instructions also read and write to memory. - Fences read and write to memory. - Invokes of intrinsics or memory allocation functions. I don't have any test cases, and I suspect this has never really come up in the real world. But there is no reason why it wouldn't, and it makes the code simpler to do this the right way. While here, I've tried to make the loops significantly simpler as well and added helpful comments as to what is going on. llvm-svn: 242281
* [PM/AA] Cleanup some loops to be range-based. NFC.Chandler Carruth2015-07-151-20/+19
| | | | llvm-svn: 242275
* Create a wrapper pass for BlockFrequencyInfo.Wei Mi2015-07-142-33/+49
| | | | | | | | | | | | This is useful when we want to do block frequency analysis conditionally (e.g. only in PGO mode) but don't want to add one more pass dependence. Patch by congh. Approved by dexonsmith. Differential Revision: http://reviews.llvm.org/D11196 llvm-svn: 242248
* [LAA] Introduce RuntimePointerChecking::PointerInfo, NFCAdam Nemet2015-07-141-29/+33
| | | | | | | Turn this structure-of-arrays (i.e. the various pointer attributes) into array-of-structures. llvm-svn: 242219
* [LAA] Lift RuntimePointerCheck out of LoopAccessInfo, NFCAdam Nemet2015-07-141-43/+41
| | | | | | | | | I am planning to add more nested classes inside RuntimePointerCheck so all these triple-nesting would be hard to follow. Also rename it to RuntimePointerChecking (i.e. append 'ing'). llvm-svn: 242218
* [PM/AA] Reformat GlobalsModRef so that subsequent patches I make hereChandler Carruth2015-07-141-155/+160
| | | | | | don't continually introduce formatting deltas. NFC llvm-svn: 242129
* Cleanup after r241809 - remove uncessary call to std::sortSilviu Baranga2015-07-131-10/+5
| | | | | | | | | | | | | | Summary: The iteration order within a member of DepCands is deterministic and therefore we don't have to sort the accesses within a member. We also don't have to copy the indices of the pointers into a vector, since we can iterate over the members of the class. Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11145 llvm-svn: 242033
* Revert r241981 "Revert "Revert r236894 "[BasicAA] Fix zext & sext handling"""Manuel Klimek2015-07-131-199/+60
| | | | | | The repros from PR23626 still fail. llvm-svn: 242025
* [LSR] don't attempt to promote ephemeral values to indvarsJingyue Wu2015-07-131-1/+16
| | | | | | | | | | | | | | | | | Summary: This at least saves compile time. I also encountered a case where ephemeral values affect whether other variables are promoted, causing performance issues. It may be a bug in LSR, but I didn't manage to reduce it yet. Anyhow, I believe it's in general not worth considering ephemeral values in LSR. Reviewers: atrick, hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11115 llvm-svn: 242011
* [InstSimplify] Teach InstSimplify how to simplify extractelementDavid Majnemer2015-07-132-0/+100
| | | | llvm-svn: 242008
* [InstSimplify] Teach InstSimplify how to simplify extractvalueDavid Majnemer2015-07-131-0/+41
| | | | llvm-svn: 242007
* Revert "Revert r236894 "[BasicAA] Fix zext & sext handling""Hal Finkel2015-07-111-60/+199
| | | | | | | | | | | r236894 caused PR23626 (Clang miscompiles webkit's base64 decoder), and was reverted in r237984. This reapplies the patch with an additional test case for PR23626 and the associated fix (both scales and offsets in the BasicAliasAnalysis::constantOffsetHeuristic should initially be zero). Patch by Nick White, thanks! llvm-svn: 241981
* Move getStrideFromPointer and friends from LoopVectorize to VectorUtilsHal Finkel2015-07-111-0/+146
| | | | | | | | | | | | | | | | The following functions are moved from the LoopVectorizer to VectorUtils: - getGEPInductionOperand - stripGetElementPtr - getUniqueCastUse - getStrideFromPointer These used to be static functions in LoopVectorize, but will also be used by the upcoming loop versioning LICM transformation. Patch by Ashutosh Nema! llvm-svn: 241980
* Add argmemonly attribute.Igor Laevsky2015-07-111-0/+6
| | | | | | | | This change adds new attribute called "argmemonly". Function marked with this attribute can only access memory through it's argument pointers. This attribute directly corresponds to the "OnlyAccessesArgumentPointees" ModRef behaviour in alias analysis. Differential Revision: http://reviews.llvm.org/D10398 llvm-svn: 241979
* [PM/AA] Completely remove the AliasAnalysis::copyValue interface.Chandler Carruth2015-07-115-18/+0
| | | | | | | | | | | | | | | | | | | | | No in-tree alias analysis used this facility, and it was not called in any particularly rigorous way, so it seems unlikely to be correct. Note that one of the only stateful AA implementations in-tree, GlobalsModRef is completely broken currently (and any AA passes like it are equally broken) because Module AA passes are not effectively invalidated when a function pass that fails to update the AA stack runs. Ultimately, it doesn't seem like we know how we want to build stateful AA, and until then trying to support and maintain correctness for an untested API is essentially impossible. To that end, I'm planning to rip out all of the update API. It can return if and when we need it and know how to build it on top of the new pass manager and as part of *tested* stateful AA implementations in the tree. Differential Revision: http://reviews.llvm.org/D10889 llvm-svn: 241975
* [InstSimplify] Fold away ord/uno fcmps when nnan is present.Benjamin Kramer2015-07-101-8/+17
| | | | | | | This is important to fold away the slow case of complex multiplies emitted by clang. llvm-svn: 241911
* Revert the new EH instructionsDavid Majnemer2015-07-101-14/+0
| | | | | | This reverts commits r241888-r241891, I didn't mean to commit them. llvm-svn: 241893
* New EH representation for MSVC compatibilityDavid Majnemer2015-07-101-0/+14
| | | | | | | | | | | | | | | Summary: This introduces new instructions neccessary to implement MSVC-compatible exception handling support. Most of the middle-end and none of the back-end haven't been audited or updated to take them into account. Reviewers: rnk, JosephTremoulet, reames, nlewycky, rjmccall Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11041 llvm-svn: 241888
* [LAA] Fix grammar in debug outputAdam Nemet2015-07-091-1/+1
| | | | llvm-svn: 241867
* [LAA] Hide NeedRTCheck logic completely inside canCheckPtrAtRT, NFCAdam Nemet2015-07-091-31/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | Currently canCheckPtrAtRT returns two flags NeedRTCheck and CanDoRT. NeedRTCheck says whether we need checks and CanDoRT whether we can generate the checks. The idea is to encode three states with these: Need/Can: (1) false/dont-care: no checks are needed (2) true/false: we need checks but can't generate them (3) true/true: we need checks and we can generate them This is pretty unnecessary since the caller (analyzeLoop) is only interested in whether we can generate the checks if we actually need them (i.e. 1 or 3). So this change cleans up to return just that (CanDoRTIfNeeded) and pulls all the underlying logic into canCheckPtrAtRT. By doing all this, we simplify analyzeLoop which is the complex function in LAA. There is further room for improvement here by using RtCheck.Need directly rather than a new local variable NeedRTCheck but that's for a later patch. llvm-svn: 241866
* Don't rely on the DepCands iteration order when constructing checking ↵Silviu Baranga2015-07-091-4/+26
| | | | | | | | | | | | | | | | | | | pointer groups Summary: The checking pointer group construction algorithm relied on the iteration on DepCands. We would need the same leaders across runs and the same iteration order over the underlying std::set for determinism. This changes the algorithm to process the pointers in the order in which they were added to the runtime check, which is deterministic. We need to update the tests, since the order in which pointers appear has changed. No new tests were added, since it is impossible to test for non-determinism. Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11064 llvm-svn: 241809
* [LAA] Fix line break in commentAdam Nemet2015-07-091-1/+1
| | | | llvm-svn: 241785
* [LAA] Rename IsRTNeeded to IsRTCheckAnalysisNeededAdam Nemet2015-07-091-6/+17
| | | | | | | | | | | | The original name was too close to NeedRTCheck which is what the actual memcheck analysis returns. This flag, as the new name suggests, is only used to whether to initiate that analysis. Also a comment is added to answer one question I had about this code for a long time. Namely, how does this flag differ from isDependencyCheckNeeded since they are seemingly set at the same time. llvm-svn: 241784
* Make TargetTransformInfo keeping a reference to the Module DataLayoutMehdi Amini2015-07-091-3/+3
| | | | | | | | | | | | | | | | | | | | DataLayout is no longer optional. It was initialized with or without a DataLayout, and the DataLayout when supplied could have been the one from the TargetMachine. Summary: This change is part of a series of commits dedicated to have a single DataLayout during compilation by using always the one owned by the module. Reviewers: echristo Subscribers: jholewinski, llvm-commits, rafael, yaron.keren Differential Revision: http://reviews.llvm.org/D11021 From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 241774
* [LAA] Fix misleading use of word 'consecutive'Adam Nemet2015-07-091-3/+3
| | | | | | | Fix some places where the word consecutive is used but the code really means constant-stride (i.e. not just unit stride). llvm-svn: 241763
* [LAA] Revert a small part of r239295Adam Nemet2015-07-081-6/+20
| | | | | | | | | | | | | | | | This commit ([LAA] Fix estimation of number of memchecks) regressed the logic a bit. We shouldn't quit the analysis if we encounter a pointer without known bounds *unless* we actually need to emit a memcheck for it. The original code was using NumComparisons which is now computed differently. Instead I compute NeedRTCheck from NumReadPtrChecks and NumWritePtrChecks. As side note, I find the separation of NeedRTCheck and CanDoRT confusing, so I will try to merge them in a follow-up patch. llvm-svn: 241756
* [LAA] Add missing debug output after r239285Adam Nemet2015-07-081-1/+3
| | | | | | | | | r239285 ([LoopAccessAnalysis] Teach LAA to check the memory dependence between strided accesses.) introduced a new case under MemoryDepChecker::isDependent. We normally have debug output for each case. llvm-svn: 241707
* [LAA] Merge memchecks for accesses separated by a constant offsetSilviu Baranga2015-07-081-38/+215
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Often filter-like loops will do memory accesses that are separated by constant offsets. In these cases it is common that we will exceed the threshold for the allowable number of checks. However, it should be possible to merge such checks, sice a check of any interval againt two other intervals separated by a constant offset (a,b), (a+c, b+c) will be equivalent with a check againt (a, b+c), as long as (a,b) and (a+c, b+c) overlap. Assuming the loop will be executed for a sufficient number of iterations, this will be true. If not true, checking against (a, b+c) is still safe (although not equivalent). As long as there are no dependencies between two accesses, we can merge their checks into a single one. We use this technique to construct groups of accesses, and then check the intervals associated with the groups instead of checking the accesses directly. Reviewers: anemet Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10386 llvm-svn: 241673
* Allow constfolding of llvm.sin.* and llvm.cos.* intrinsicsKarthik Bhat2015-07-081-0/+6
| | | | | | | | This patch const folds llvm.sin.* and llvm.cos.* intrinsics whenever feasible. Differential Revision: http://reviews.llvm.org/D10836 llvm-svn: 241665
* Rename llvm.frameescape and llvm.framerecover to localescape and localrecoverReid Kleckner2015-07-071-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Initially, these intrinsics seemed like part of a family of "frame" related intrinsics, but now I think that's more confusing than helpful. Initially, the LangRef specified that this would create a new kind of allocation that would be allocated at a fixed offset from the frame pointer (EBP/RBP). We ended up dropping that design, and leaving the stack frame layout alone. These intrinsics are really about sharing local stack allocations, not frame pointers. I intend to go further and add an `llvm.localaddress()` intrinsic that returns whatever register (EBP, ESI, ESP, RBX) is being used to address locals, which should not be confused with the frame pointer. Naming suggestions at this point are welcome, I'm happy to re-run sed. Reviewers: majnemer, nicholas Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11011 llvm-svn: 241633
* IR: Do not consider available_externally linkage to be linker-weak.Peter Collingbourne2015-07-051-1/+1
| | | | | | | | | | | | | | | From the linker's perspective, an available_externally global is equivalent to an external declaration (per isDeclarationForLinker()), so it is incorrect to consider it to be a weak definition. Also clean up some logic in the dead argument elimination pass and clarify its comments to better explain how its behavior depends on linkage, introduce GlobalValue::isStrongDefinitionForLinker() and start using it throughout the optimizers and backend. Differential Revision: http://reviews.llvm.org/D10941 llvm-svn: 241413
* Delete whitespace at start of line.Yaron Keren2015-07-021-1/+1
| | | | llvm-svn: 241265
* Add a routine to TargetTransformInfo that will allow targets to lookEric Christopher2015-07-022-4/+10
| | | | | | | at the attributes on a function to determine whether or not to allow inlining. llvm-svn: 241220
* Move delinearization from SCEVAddRecExpr to ScalarEvolutionTobias Grosser2015-06-293-21/+25
| | | | | | | | | | The expressions we delinearize do not necessarily have to have a SCEVAddRecExpr at the outermost level. At this moment, the additional flexibility is not exploited in LLVM itself, but in Polly we will soon soonish use this functionality. For LLVM, this change should not affect existing functionality (which is covered by test/Analysis/Delinearization/) llvm-svn: 240952
* Teach InlineCost to account for a null check which can be folded awayPhilip Reames2015-06-261-17/+56
| | | | | | | | | | If we have a caller that knows a particular argument can never be null, we can exploit this fact while simplifying values in the inline cost analysis. This has the effect of reducing the cost for inlining when a null check is present in the callee, but the value is known non null in the caller. In particular, any dependent control flow can be discounted from the cost estimate. Note that we use the parameter attributes at the call site to memoize the analysis within the caller's code. The setting of this attribute is done in InstCombine, the inline cost analysis just consumes it. This is intentional and important because we want the inline cost analysis results to be easily cachable themselves. We're not currently doing so, but initial results on LTO indicate this will quickly become important. Differential Revision: http://reviews.llvm.org/D9129 llvm-svn: 240828
* Move VectorUtils from Transforms to Analysis to correct layering violationDavid Blaikie2015-06-263-1/+215
| | | | llvm-svn: 240804
* [LAA] Try to prove non-wrapping of pointers if SCEV cannotAdam Nemet2015-06-261-1/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Scalar evolution does not propagate the non-wrapping flags to values that are derived from a non-wrapping induction variable because the non-wrapping property could be flow-sensitive. This change is a first attempt to establish the non-wrapping property in some simple cases. The main idea is to look through the operations defining the pointer. As long as we arrive to a non-wrapping AddRec via a small chain of non-wrapping instruction, the pointer should not wrap either. I believe that this essentially is what Andy described in http://article.gmane.org/gmane.comp.compilers.llvm.cvs/220731 as the way forward. Reviewers: aschwaighofer, nadav, sanjoy, atrick Reviewed By: atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10472 llvm-svn: 240798
* Take alignment into account in isSafeToLoadUnconditionallyArtur Pilipenko2015-06-251-6/+20
| | | | | | | | Reviewed By: hfinkel Differential Revision: http://reviews.llvm.org/D10475 llvm-svn: 240636
* [LSR] canonicalize Prod*(1<<C) to Prod<<CJingyue Wu2015-06-241-5/+12
| | | | | | | | | | | | | | | | | | | | | Summary: Because LSR happens at a late stage where mul of a power of 2 is typically canonicalized to shl, this canonicalization emits code that can be better CSE'ed. Test Plan: Transforms/LoopStrengthReduce/shl.ll shows how this change makes GVN more powerful. Fixes some existing tests due to this change. Reviewers: sanjoy, majnemer, atrick Reviewed By: majnemer, atrick Subscribers: majnemer, llvm-commits Differential Revision: http://reviews.llvm.org/D10448 llvm-svn: 240573
* [CaptureTracking] Avoid long compilation time on large basic blocksBruno Cardoso Lopes2015-06-242-25/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CaptureTracking becomes very expensive in large basic blocks while calling PointerMayBeCaptured. PointerMayBeCaptured scans the BB the number of times equal to the number of uses of 'BeforeHere', which is currently capped at 20 and bails out with Tracker->tooManyUses(). The bottleneck here is the number of calls to PointerMayBeCaptured * the basic block scan. In a testcase with a 82k instruction BB, PointerMayBeCaptured is called 130k times, leading to 'shouldExplore' taking 527k runs, this currently takes ~12min. To fix this we locally (within PointerMayBeCaptured) number the instructions in the basic block using a DenseMap to cache instruction positions/numbers. We build the cache incrementally every time we need to scan an unexplored part of the BB, improving compile time to only take ~2min. This triggers in the flow: DeadStoreElimination -> MepDepAnalysis -> CaptureTracking. Side note: after multiple runs in the test-suite I've seen no performance nor compile time regressions, but could note a couple of compile time improvements: Performance Improvements - Compile Time Delta Previous Current StdDev SingleSource/Benchmarks/Misc-C++/bigfib -4.48% 0.8547 0.8164 0.0022 MultiSource/Benchmarks/TSVC/LoopRerolling-dbl/LoopRerolling-dbl -1.47% 1.3912 1.3707 0.0056 Differential Revision: http://reviews.llvm.org/D7010 llvm-svn: 240560
* Revert r240137 (Fixed/added namespace ending comments using clang-tidy. NFC)Alexander Kornienko2015-06-2325-38/+38
| | | | | | Apparently, the style needs to be agreed upon first. llvm-svn: 240390
* [PM/AA] Hoist the AliasResult enum out of the AliasAnalysis class.Chandler Carruth2015-06-2213-100/+90
| | | | | | | | | | | | | | | | | | | | | | | | | | | This will allow classes to implement the AA interface without deriving from the class or referencing an internal enum of some other class as their return types. Also, to a pretty fundamental extent, concepts such as 'NoAlias', 'MayAlias', and 'MustAlias' are first class concepts in LLVM and we aren't saving anything by scoping them heavily. My mild preference would have been to use a scoped enum, but that feature is essentially completely broken AFAICT. I'm extremely disappointed. For example, we cannot through any reasonable[1] means construct an enum class (or analog) which has scoped names but converts to a boolean in order to test for the possibility of aliasing. [1]: Richard Smith came up with a "solution", but it requires class templates, and lots of boilerplate setting up the enumeration multiple times. Something like Boost.PP could potentially bundle this up, but even that would be quite painful and it doesn't seem realistically worth it. The enum class solution would probably work without the need for a bool conversion. Differential Revision: http://reviews.llvm.org/D10495 llvm-svn: 240255
OpenPOWER on IntegriCloud