summaryrefslogtreecommitdiffstats
path: root/polly/lib/Analysis
Commit message (Collapse)AuthorAgeFilesLines
...
* [DependenceInfo] Replace use of deprecated isl_dim_n_out [NFC]Siddharth Bhat2017-03-171-1/+2
| | | | | | Change isl_dim_n_out to isl_map_dim(*, isl_dim_out) llvm-svn: 298075
* [DependenceInfo] Track may-writes and build flow information inSiddharth Bhat2017-03-171-0/+3
| | | | | | | | | | | | Dependences::calculateDependences. This ensures that we handle may-writes correctly when building dependence information. Also add a test case checking correctness of may-write information. Not handling it before was an oversight. Differential Revision: https://reviews.llvm.org/D31075 llvm-svn: 298074
* [ScopInfo] Do not take inbounds assumptions [NFC]Tobias Grosser2017-03-171-0/+7
| | | | | | | For experiments it is sometimes helpful to not take any inbounds assumptions. Add a new option "-polly-ignore-inbounds" which does precisely this. llvm-svn: 298073
* [ScopInfo] Do not try to eliminate parameter dimensions that do not existTobias Grosser2017-03-171-1/+2
| | | | | | | | | | In subsequent changes we will make Polly a little bit more lazy in adding parameter dimensions to different sets. As a result, not all parameters will always be part of the parameter space. This change ensures that we do not use the '-1' returned when a parameter dimension cannot be found, but instead just do not try to eliminate the anyhow non-existing dimension. llvm-svn: 298054
* [ScopInfo] Do not expand getDomains() to full parameter space.Tobias Grosser2017-03-171-1/+2
| | | | | | | | | | | | | | | Since several years, isl can perform most operations on sets with differing parameter spaces, by expanding the parameter space on demand relying using named isl ids to distinguish different parameter dimensions. By not always expanding to full dimensionality the set remain smaller and can likely be operated on faster. This change by itself did not yet result in measurable performance benefits, but it is a step into the right direction needed to ensure that subsequent changes indeed can work with lower-dimensional sets and these sets do not get blown up by accident when later intersected with the domain context. llvm-svn: 298053
* Update to isl-0.18-387-g3fa6191Tobias Grosser2017-03-161-1/+1
| | | | | | This is a normal / regular maintenance update. llvm-svn: 297999
* Set Dependences::RED to be non-null once Dependences::calculateDependences()Siddharth Bhat2017-03-161-0/+1
| | | | | | | occurs, even if there is no actual reduction. This ensures correctness with isl operations. llvm-svn: 297981
* [ScopInfo] Introduce ScopStmt::getSurroundingLoop(). NFC.Michael Kruse2017-03-152-46/+53
| | | | | | | | | | | | | | Introduce ScopStmt::getSurroundingLoop() to replace getFirstNonBoxedLoopFor. getSurroundingLoop() returns the precomputed surrounding/first non-boxed loop. Except in ScopDetection, the list of boxed loops is only used to get the surrounding loop. getFirstNonBoxedLoopFor also requires LoopInfo at every use which is not necessarily available everywhere where we may want to use it. Differential Revision: https://reviews.llvm.org/D30985 llvm-svn: 297899
* [Simplify] Add -polly-simplify pass.Michael Kruse2017-03-101-0/+13
| | | | | | | | | | | | | | | | | This new pass removes unnecessary accesses and writes. It currently supports 2 simplifications, but more are planned. It removes write accesses that write a loaded value back to the location it was loaded from. It is a typical artifact from DeLICM. Removing it will get rid of bogus dependencies later in dependency analysis. It also removes statements without side-effects. ScopInfo already removes these, but the removal of unnecessary writes can result in more side-effect free statements. Differential Revision: https://reviews.llvm.org/D30820 llvm-svn: 297473
* [ScopDetect/Info] Allow unconditional hoisting of loads from dereferenceable ↵Tobias Grosser2017-03-092-1/+15
| | | | | | | | | | | | ptrs In case LLVM pointers are annotated with !dereferencable attributes/metadata or LLVM can look at the allocation from which a pointer is derived, we can know that dereferencing pointers is safe and can be done unconditionally. We use this information to proof certain pointers as save to hoist and then hoist them unconditionally. llvm-svn: 297375
* [ScopDetection] Only allow SCoP-wide available base pointers.Michael Kruse2017-03-081-17/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Simplify ScopDetection::isInvariant(). Essentially deny everything that is defined within the SCoP and is not load-hoisted. The previous understanding of "invariant" has a few holes: - Expressions without side-effects with only invariant arguments, but are defined withing the SCoP's region with the exception of selects and PHIs. These should be part of the index expression derived by ScalarEvolution and not of the base pointer. - Function calls with that are !mayHaveSideEffects() (typically functions with "readnone nounwind" attributes). An example is given below. @C = external global i32 declare float* @getNextBasePtr(float*) readnone nounwind ... %ptr = call float* @getNextBasePtr(float* %A, float %B) The call might return: * %A, so %ptr aliases with it in the SCoP * %B, so %ptr aliases with it in the SCoP * @C, so %ptr aliases with it in the SCoP * a new pointer everytime it is called, such as malloc() * a pointer into the allocated block of one of the aforementioned * any of the above, at random at each call Hence and contrast to a comment in the base_pointer.ll regression test, %ptr is not necessarily the same all the time. It might also alias with anything and no AliasAnalysis can tell otherwise if the definition is external. It is hence not suitable in the role of a base pointer. The practical problem with base pointers defined in SCoP statements is that it is not available globally in the SCoP. The statement instance must be executed first before the base pointer can be used. This is no problem if the base pointer is transferred as a scalar value between statements. Uses of MemoryAccess::setNewAccessRelation may add a use of the base pointer anywhere in the array. setNewAccessRelation is used by JSONImporter, DeLICM and D28518. Indeed, BlockGenerator currently assumes that base pointers are available globally and generates invalid code for new access relation (referring to the base pointer of the original code) if not, even if the base pointer would be available in the statement. This could be fixed with some added complexity and restrictions. The ExprBuilder must lookup the local BBMap and code that call setNewAccessRelation must check whether the base pointer is available first. The code would still be incorrect in the presence of aliasing. There is the switch -polly-ignore-aliasing to explicitly allow this, but it is hardly a justification for the additional complexity. It would still be mostly useless because in most cases either getNextBasePtr() has external linkage in which case the readnone nounwind attributes cannot be derived in the translation unit itself, or is defined in the same translation unit and gets inlined. Reviewed By: grosser Differential Revision: https://reviews.llvm.org/D30695 llvm-svn: 297281
* [ScopDetection] Require LoadInst base pointers to be hoisted.Michael Kruse2017-03-071-4/+13
| | | | | | | | | | | | | | | | | | Only when load-hoisted we can be sure the base pointer is invariant during the SCoP's execution. Most of the time it would be added to the required hoists for the alias checks anyway, except with -polly-ignore-aliasing, -polly-use-runtime-alias-checks=0 or if AliasAnalysis is already sure it doesn't alias with anything (for instance if there is no other pointer to alias with). Two more parts in Polly assume that this load-hoisting took place: - setNewAccessRelation() which contains an assert which tests this. - BlockGenerator which would use to the base ptr from the original code if not load-hoisted (if the access expression is regenerated) Differential Revision: https://reviews.llvm.org/D30694 llvm-svn: 297195
* [ScopInfo] Avoid infinite loop during schedule constructionTobias Grosser2017-03-071-3/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | Our current scop modeling enters an infinite loop when trying to model code that has unreachable instructions (e.g., test/ScopInfo/BoundChecks/single-loop.ll), as the number of basic blocks returned by the LLVM Loop* does not include unreachable basic blocks that branch off from the core loop body. This arises for example in the following piece of code: for (i = 0; i < N; i++) { if (i > 1024) abort(); <- this abort might be translated to an unreachable A[i] = ... } This patch adds these unreachable basic blocks in our per loop basic block count to ensure that the schedule construction does not assume a loop has been processed completely, despite certain unreachable basic blocks still remaining. The infinite loop is only observable in combination with https://reviews.llvm.org/D12676 or a similar patch. llvm-svn: 297156
* [ScopDetection] Do not detect scops that exit to an unreachableTobias Grosser2017-03-072-1/+26
| | | | | | | | | | | | | | | Scops that exit with an unreachable are today still permitted, but make little sense to optimize. We therefore can already skip them during scop detection. This speeds up scop detection in certain cases and also ensures that bugpoint does not introduce unreachables when reducing test cases. In practice this change should have little impact, as the performance of unreachable code is unlikely to matter. This commit is part of a series that makes Polly more robust in the presence of unreachables. llvm-svn: 297151
* [ScopDetection] Do not allow required-invariant loads in non-affine regionTobias Grosser2017-03-021-1/+7
| | | | | | | | | | These loads cannot be savely hoisted as the condition guarding the non-affine region cannot be duplicated to also protect the hoisted load later on. Today they are dropped in ScopInfo. By checking for this early, we do not even try to model them and possibly can still optimize smaller regions not containing this specific required-invariant load. llvm-svn: 296744
* [ScopInfo] Disable memory folding in case it results in multi-disjunct relationsTobias Grosser2017-03-011-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multi-disjunct access maps can easily result in inbound assumptions which explode in case of many memory accesses and many parameters. This change reduces compilation time of some larger kernel from over 15 minutes to less than 16 seconds. Interesting is the test case test/ScopInfo/multidim_param_in_subscript.ll which has a memory access [n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0, -1 + n - i1] } which requires folding, but where only a single disjunct remains. We can still model this test case even when only using limited memory folding. For people only reading commit messages, here the comment that explains what memory folding is: To recover memory accesses with array size parameters in the subscript expression we post-process the delinearization results. We would normally recover from an access A[exp0(i) * N + exp1(i)] into an array A[][N] the 2D access A[exp0(i)][exp1(i)]. However, another valid delinearization is A[exp0(i) - 1][exp1(i) + N] which - depending on the range of exp1(i) - may be preferrable. Specifically, for cases where we know exp1(i) is negative, we want to choose the latter expression. As we commonly do not have any information about the range of exp1(i), we do not choose one of the two options, but instead create a piecewise access function that adds the (-1, N) offsets as soon as exp1(i) becomes negative. For a 2D array such an access function is created by applying the piecewise map: [i,j] -> [i, j] : j >= 0 [i,j] -> [i-1, j+N] : j < 0 After this patch we generate only the first case, except for situations where we can proove the first case to be invalid and can consequently select the second without introducing disjuncts. llvm-svn: 296679
* [ScopInfo] Simplify inbounds assumptions under domain constraintsTobias Grosser2017-02-281-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Without this simplification for a loop nest: void foo(long n1_a, long n1_b, long n1_c, long n1_d, long p1_b, long p1_c, long p1_d, float A_1[][p1_b][p1_c][p1_d]) { for (long i = 0; i < n1_a; i++) for (long j = 0; j < n1_b; j++) for (long k = 0; k < n1_c; k++) for (long l = 0; l < n1_d; l++) A_1[i][j][k][l] += i + j + k + l; } the assumption: n1_a <= 0 or (n1_a > 0 and n1_b <= 0) or (n1_a > 0 and n1_b > 0 and n1_c <= 0) or (n1_a > 0 and n1_b > 0 and n1_c > 0 and n1_d <= 0) or (n1_a > 0 and n1_b > 0 and n1_c > 0 and n1_d > 0 and p1_b >= n1_b and p1_c >= n1_c and p1_d >= n1_d) is taken rather than the simpler assumption: p9_b >= n9_b and p9_c >= n9_c and p9_d >= n9_d. The former is less strict, as it allows arbitrary values of p1_* in case, the loop is not executed at all. However, in practice these precise constraints explode when combined across different accesses and loops. For now it seems to make more sense to take less precise, but more scalable constraints by default. In case we find a practical example where more precise constraints are needed, we can think about allowing such precise constraints in specific situations where they help. This change speeds up the new test case from taking very long (waited at least a minute, but it probably takes a lot more) to below a second. llvm-svn: 296456
* [DependenceInfo] Remove unused variable. NFC.Michael Kruse2017-02-231-1/+0
| | | | llvm-svn: 295987
* [DependenceInfo] Use references instead of double pointers. NFC.Michael Kruse2017-02-231-18/+18
| | | | | | | Non-const references are the more C++-ish way to modify a variable passed by the caller. llvm-svn: 295986
* [DependenceInfo] Rename StmtScheduleDomain -> TaggedStmtDomain. NFC.Michael Kruse2017-02-231-15/+14
| | | | llvm-svn: 295985
* [DependenceInfo] Simplify use of StmtSchedule's domain [NFC]Michael Kruse2017-02-231-21/+21
| | | | | | | | | | | | | | | | | Once a StmtSchedule is created, only its domain is used anywhere within DependenceInfo::calculateDependences. So, we choose to return the wrapped domain of the union_map rather than the entire union_map. However, we still build the union_map first within collectInfo(). It is cleaner to first build the entire union_map and then pull the domain out in one shot, rather than repeatedly extracting the domain in bits and pieces from accdom. Contributed-by: Siddharth Bhat <siddu.druid@gmail.com> Differential Revision: https://reviews.llvm.org/D30208 llvm-svn: 295984
* Remove all references to PostDominators. NFC.Michael Kruse2017-02-231-1/+0
| | | | | | | | | Marking a pass as preserved is necessary if any Polly pass uses it, even if it is not preserved within the generated code. Not marking it would cause the the Polly pass chain to be interrupted. It is not used by any Polly pass anymore, hence we can remove all references to it. llvm-svn: 295983
* [DependenceInfo] Simplify creation and subsequent use of AccessSchedule [NFC]Tobias Grosser2017-02-211-31/+22
| | | | | | | | | | | | | | We only ever use the wrapped domain of AccessSchedule, so stop creating an entire union_map and then pulling the domain out. Reviewers: grosser Tags: #polly Contributed-by: Siddharth Bhat <siddu.druid@gmail.com> Differential Revision: https://reviews.llvm.org/D30179 llvm-svn: 295726
* [ScopInfo] Count read-only arrays when computing complexity of alias checkTobias Grosser2017-02-181-1/+3
| | | | | | | | | | | Instead of counting the number of read-only accesses, we now count the number of distinct read-only array references when checking if a run-time alias check may be too complex. The run-time alias check is quadratic in the number of base pointers, not the number of accesses. Before this change we accidentally skipped SPEC's lbm test case. llvm-svn: 295567
* [DependenceInfo] Pull out statement [NFC]Tobias Grosser2017-02-181-3/+2
| | | | | | This simplifies the code slightly. llvm-svn: 295551
* [Dependences] Compute reduction dependences on schedule tree [NFC]Tobias Grosser2017-02-181-39/+27
| | | | | | | | | | | | | | | | | | | This change gets rid of the need for zero padding, makes the reduction computation code more similar to the normal dependence computation, and also better documents what we do at the moment. Making the dependence computation for reductions a little bit easier to understand will hopefully help us to further reduce code duplication. This reduces the time spent only in the reduction dependence pass from 260ms to 150ms for test/DependenceInfo/reduction_sequence.ll. This is a reduction of over 40% in dependence computation time. This change was inspired by discussions with Michael Kruse, Utpal Bora, Siddharth Bhat, and Johannes Doerfert. It can hopefully lay the base for further cleanups of the reduction code. llvm-svn: 295550
* Drop leftover debug statementTobias Grosser2017-02-171-1/+0
| | | | llvm-svn: 295444
* [ScopInfo] Add statistics to count loops after scop modelingTobias Grosser2017-02-172-9/+47
| | | | llvm-svn: 295431
* [ScopDetection] Compute the maximal loop depth correctlyTobias Grosser2017-02-171-1/+1
| | | | | | | Before this change, we obtained loop depth numbers that were deeper then the actual loop depth. llvm-svn: 295430
* [ScopInfo] Do not try to fold array dimensions of size zeroTobias Grosser2017-02-171-0/+4
| | | | | | | | | | Trying to fold such kind of dimensions will result in a division by zero, which crashes the compiler. As such arrays are likely to invalidate the scop anyhow (but are not illegal in LLVM-IR), there is no point in trying to optimize the array layout. Hence, we just avoid the folding of constant dimensions of size zero. llvm-svn: 295415
* [ScopInfo] Rename MaxDisjunctions -> MaxDisjuncts [NFC]Tobias Grosser2017-02-161-8/+8
| | | | | | | There is only a single disjunction. However, we bound the number of 'disjuncts' in this disjunction. Name the variable accordingly. llvm-svn: 295362
* [ScopInfo] Bound the number of disjuncts in contextTobias Grosser2017-02-161-0/+8
| | | | | | | | | Before this change wrapping range metadata resulted in exponential growth of the context, which made context construction of large scops very slow. Instead, we now just do not model the range information precisely, in case the number of disjuncts in the context has already reached a certain limit. llvm-svn: 295360
* [ScopInfo] Use uppercase variable name [NFC]Tobias Grosser2017-02-161-5/+5
| | | | llvm-svn: 295350
* [ScopInfo] Always derive upper and lower bounds for parametersTobias Grosser2017-02-161-13/+22
| | | | | | | | | | | | | | | | | | | | Commit r230230 introduced the use of range metadata to derive bounds for parameters, instead of just looking at the type of the parameter. As part of this commit support for wrapping ranges was added, where the lower bound of a parameter is larger than the upper bound: { 255 < p || p < 0 } However, at the same time, for wrapping ranges support for adding bounds given by the size of the containing type has acidentally been dropped. As a result, the range of the parameters was not guaranteed to be bounded any more. This change makes sure we always add the bounds given by the size of the type and then additionally add bounds based on signed wrapping, if available. For a parameter p with a type size of 32 bit, the valid range is then: { -2147483648 <= p <= 2147483647 and (255 < p or p < 0) } llvm-svn: 295349
* [ScopDetectDiagnostics] Do not format unnamed array namesTobias Grosser2017-02-121-1/+1
| | | | | | | | | | | | | Formatting unnamed array names is expensive in LLVM as the this requires deriving the numbered virtual instruction name (e.g., %12) for an llvm::Value, which is currently not implemented efficiently. As instruction numberes anyhow do not really carry a lot of information for the user, we just print 'unknown' instead. This change reduces the scop detection time from 24 to 19 seconds, for one of our large-scale inputs. This is a reduction by 21%. llvm-svn: 294894
* [ScopDetection] Add statistics to count the maximal number of scops in loopTobias Grosser2017-02-121-0/+7
| | | | llvm-svn: 294893
* Do not use wrapping ranges to bound non-affine accessesTobias Grosser2017-02-121-0/+6
| | | | | | | | | | | | | When deriving the range of valid values of a scalar evolution expression might be a range [12, 8), where the upper bound is smaller than the lower bound and where the range is expected to possibly wrap around. We theoretically could model such a range as a union of two non-wrapping ranges, but do not do this as of yet. Instead, we just do not derive any bounds. Before this change, we could have obtained bounds where the maximal possible value is strictly smaller than the minimal possible value, which is incorrect and also caused assertions during scop modeling. llvm-svn: 294891
* [ScopInfo] Use original base address when building ScopArrayInfo [NFC]Tobias Grosser2017-02-101-2/+2
| | | | | | | | | This change clarfies that we want to indeed use the original base address when creating the ScopArrayInfo that corresponds to a given memory access. This change prepares for https://reviews.llvm.org/D28518. llvm-svn: 294734
* [ScopInfo] Use getAccessValue to obtain the accessed valueTobias Grosser2017-02-101-1/+1
| | | | | | | | | | | | | | | This replaces the use of getOriginalAddrPtr, a value that is stored in ScopArrayInfo and might at some point not be unique any more. However, the access value is defined to be unique. This change is an update on r294576, which only clarified that we need the original memory access, but where we still remained dependent to have one base pointer per scop. This change removes unnecessary uses of MemoryAddress::getOriginalBaseAddr() in preparation for https://reviews.llvm.org/D28518. llvm-svn: 294733
* [ScopInfo] Use MemoryAccess::getScopArrayInfo() interface to access Array [NFC]Tobias Grosser2017-02-091-3/+2
| | | | | | | | | | | | | | By using the public interface MemoryAccess::getScopArrayInfo() we avoid the direct access to the ScopArrayInfoMap and as a result also do not need to use the BasePtr as key. This change makes the code cleaner. The const-cast we introduce is a little ugly. We may consider to drop const correctness for getScopArrayInfo() at some point. This change removes unnecessary uses of MemoryAddress::getBaseAddr() in preparation for https://reviews.llvm.org/D28518. llvm-svn: 294655
* [ScopInfo] Use types instead of 'auto' and use more descriptive variable ↵Tobias Grosser2017-02-091-8/+10
| | | | | | | | | | names [NFC] LLVM's coding conventions suggest to use auto only in obvious cases. Hence, we move this code to actually declare the types used. We also replace the variable name 'SAI', with the name 'Array', as this improves readability. llvm-svn: 294654
* [ScopInfo] Use ScopArrayInfo instead of base addressTobias Grosser2017-02-091-11/+11
| | | | | | | | | | | | When building alias groups, we sort different ScopArrays into unrelated groups. Historically we identified arrays through their base pointer, as no ScopArrayInfo class was yet available. This change changes the alias group construction to reference arrays through their ScopArrayInfo object. This change removes unnecessary uses of MemoryAddress::getBaseAddr() in preparation for https://reviews.llvm.org/D28518. llvm-svn: 294649
* [ScopInfo] Expect the OriginalBaseAddr when looking at underlying ↵Tobias Grosser2017-02-091-3/+3
| | | | | | | | | | | | | | | | instructions [NFC] During SCoP construction we sometimes inspect the underlying IR by looking at the base address of a MemoryAccess. In such cases, we always want the original base address. Make this clear by calling getOriginalBaseAddr(). This is a non-functional change as getBaseAddr maps to getOriginalBaseAddr at the moment. This change removes unnecessary uses of MemoryAddress::getBaseAddr() in preparation for https://reviews.llvm.org/D28518. llvm-svn: 294576
* [ScopInfo] Remove unnecessary indirection through SCEV [NFC]Tobias Grosser2017-02-091-8/+4
| | | | | | | | | The base address of a memory access is already an llvm::Value. Hence, there is no need to go through SCEV, but we can directly work with the llvm::Value. Also use 'Value *' instead of 'auto' for cases where the type is not obvious. llvm-svn: 294575
* [DependenceInfo] Use ScopArrayInfo to keep track of arrays [NFC]Tobias Grosser2017-02-091-4/+4
| | | | | | | | | | | | | | When computing reduction dependences we first identify all ScopArrays which are part of reductions and then only compute for these ScopArrays the more detailed data dependences that allow us to identify reductions and optimize across them. Instead of using the base pointer as identifier of a ScopArray, it is clearer and more understandable to directly use the ScopArray as identifier. This change implements such a switch. This change removes unnecessary uses of MemoryAddress::getBaseAddr() in preparation for https://reviews.llvm.org/D28518. llvm-svn: 294567
* Update to recent formatting changesTobias Grosser2017-02-011-3/+2
| | | | llvm-svn: 293756
* Fix format after recent clang-format change.Daniel Jasper2017-02-011-3/+2
| | | | llvm-svn: 293753
* [ScopDetectionDiagnostic] Add meaningfull enduser message for regions with ↵Tobias Grosser2017-01-261-0/+4
| | | | | | | | | | | entry block Before this change the user only saw "Unspecified Error", when a region contained the entry block. Now we report: "Scop contains function entry (not yet supported)." llvm-svn: 293169
* ScopDetectionDiagnostics: Also emit diagnostics in case no debug info is ↵Tobias Grosser2017-01-261-0/+3
| | | | | | | | available In this case, we just use the start of the scop as the debug location. llvm-svn: 293165
* Relax assert when setting access functions with invariant base pointersTobias Grosser2017-01-171-4/+12
| | | | | | | | | | | | | | | | | | | | | | | | | Summary: Instead of forbidding such access functions completely, we verify that their base pointer has been hoisted and only assert in case the base pointer was not hoisted. I was trying for a little while to get a test case that ensures the assert is correctly fired in case of invariant load hoisting being disabled, but I could not find a good way to do so, as llvm-lit immediately aborts if a command yields a non-zero return value. As we do not generally test our asserts, not having a test case here seems OK. This resolves http://llvm.org/PR31494 Suggested-by: Michael Kruse <llvm@meinersbur.de> Reviewers: efriedma, jdoerfert, Meinersbur, gareevroman, sebpop, zinob, huihuiz, pollydev Reviewed By: Meinersbur Differential Revision: https://reviews.llvm.org/D28798 llvm-svn: 292213
OpenPOWER on IntegriCloud