aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LoopInfo.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-09-12Revert "[LoopInfo] Pointer to stack object may not be loop invariant in a ↵Weibo He1-17/+5
coroutine function (#149936)" (#157986) Since #156788 has resolved #149604, we can revert this workaround now.
2025-08-09[LoopInfo] Pointer to stack object may not be loop invariant in a coroutine ↵weiguozhi1-5/+17
function (#149936) A coroutine function may be split to ramp function and resume function, and they have different stack frames, so a pointer to stack objects may have different addresses depending on where it is used, so it's not a loop invariant. It temporarily fixes https://github.com/llvm/llvm-project/issues/149604.
2025-07-31Revert "[PGO] Add `llvm.loop.estimated_trip_count` metadata" (#151585)Joel E. Denny1-7/+3
Reverts llvm/llvm-project#148758 [As requested.](https://github.com/llvm/llvm-project/pull/148758#pullrequestreview-3076627201)
2025-07-31[PGO] Add `llvm.loop.estimated_trip_count` metadata (#148758)Joel E. Denny1-3/+7
This patch implements the `llvm.loop.estimated_trip_count` metadata discussed in [[RFC] Fix Loop Transformations to Preserve Block Frequencies](https://discourse.llvm.org/t/rfc-fix-loop-transformations-to-preserve-block-frequencies/85785). As [suggested in the RFC comments](https://discourse.llvm.org/t/rfc-fix-loop-transformations-to-preserve-block-frequencies/85785/4), it adds the new metadata to all loops at the time of profile ingestion and estimates each trip count from the loop's `branch_weights` metadata. As [suggested in the PR #128785 review](https://github.com/llvm/llvm-project/pull/128785#discussion_r2151091036), it does so via a new `PGOEstimateTripCountsPass` pass, which creates the new metadata for each loop but omits the value if it cannot estimate a trip count due to the loop's form. An important observation not previously discussed is that `PGOEstimateTripCountsPass` *often* cannot estimate a loop's trip count, but later passes can sometimes transform the loop in a way that makes it possible. Currently, such passes do not necessarily update the metadata, but eventually that should be fixed. Until then, if the new metadata has no value, `llvm::getLoopEstimatedTripCount` disregards it and tries again to estimate the trip count from the loop's current `branch_weights` metadata.
2025-07-14[llvm] Remove unused includes (NFC) (#148768)Kazu Hirata1-1/+0
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-05-27[llvm] annotate interfaces in llvm/Analysis for DLL export (#136623)Andrew Rogers1-2/+3
## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/Analysis` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS on Linux: - Add `#include "llvm/Support/Compiler.h"` to files where it was not auto-added by IDS due to no pre-existing block of include statements. - Add `LLVM_TEMPLATE_ABI` and `LLVM_EXPORT_TEMPLATE` to exported instantiated templates - Add `LLVM_ABI` to a subset of private class methods and fields that require export - Add `LLVM_ABI` to a small number of symbols that require export but are not declared in headers ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang
2025-04-21[LLVM] Cleanup pass initialization for Analysis passes (#135858)Rahul Joshi1-3/+1
- Do not call pass initialization from pass constructors. - Instead, pass initialization should happen in the `initializeAnalysis` function. - https://github.com/llvm/llvm-project/issues/111767
2025-01-24[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)Jeremy Morse1-1/+1
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to moveBefore use iterators. This patch adds a (guaranteed dereferenceable) iterator-taking moveBefore, and changes a bunch of call-sites where it's obviously safe to change to use it by just calling getIterator() on an instruction pointer. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer insertBefore, but not before adding concise documentation of what considerations are needed (very few).
2025-01-17Add option to print entire function instead of just the loops for loo… ↵Akshay Deodhar1-0/+12
(#123229) print-after-all is useful for diffing IR between two passes. When one of the two is a function pass, and the other is a loop pass, the diff becomes useless. Add an option which prints the entire function for loop passes.
2024-06-28[IR] Don't include Module.h in Analysis.h (NFC) (#97023)Nikita Popov1-0/+1
Replace it with a forward declaration instead. Analysis.h is pulled in by all passes, but not all passes need to access the module.
2024-06-25LoopInfo: introduce Loop::getLocStr; unify debug output (#93051)Ramkumar Ramachandra1-0/+11
Introduce a Loop::getLocStr stolen from LoopVectorize's static function getDebugLocString in order to have uniform debug output headers across LoopVectorize, LoopAccessAnalysis, and LoopDistribute. The motivation for this change is to have UpdateTestChecks recognize the headers and automatically generate CHECK lines for debug output, with minimal special-casing.
2024-06-06[LoopUnroll] Consider convergence control tokens when unrolling (#91715)Sameer Sahasrabuddhe1-0/+20
- There is no restriction on a loop with controlled convergent operations when the relevant tokens are defined and used within the loop. - When a token defined outside a loop is used inside (also called a loop convergence heart), unrolling is allowed only in the absence of remainder or runtime checks. - When a token defined inside a loop is used outside, such a loop is said to be "extended". This loop can only be unrolled by also duplicating the extended part lying outside the loop. Such unrolling is disabled for now. - Clean up loop hearts: When unrolling a loop with a heart, duplicating the heart will introduce multiple static uses of a convergence control token in a cycle that does not contain its definition. This violates the static rules for tokens, and needs to be cleaned up into a single occurrence of the intrinsic. - Spell out the initializer for UnrollLoopOptions to improve readability. Original implementation [D85605] by Nicolai Haehnle <nicolai.haehnle@amd.com>.
2024-05-07[Analysis, CodeGen, DebugInfo] Use StringRef::operator== instead of ↵Kazu Hirata1-1/+1
StringRef::equals (NFC) (#91304) I'm planning to remove StringRef::equals in favor of StringRef::operator==. - StringRef::operator==/!= outnumber StringRef::equals by a factor of 53 under llvm/ in terms of their usage. - The elimination of StringRef::equals brings StringRef closer to std::string_view, which has operator== but not equals. - S == "foo" is more readable than S.equals("foo"), especially for !Long.Expression.equals("str") vs Long.Expression != "str".
2024-02-03[Analysis] Use range-based for loops (NFC)Kazu Hirata1-6/+6
2024-01-26[Analysis] Use llvm::succ_empty and llvm::successors (NFC)Kazu Hirata1-6/+5
2024-01-03[LoopInfo][NewPM] Print function name in LoopPrinterPass (#76527)Björn Pettersson1-1/+3
The legacy pass manager printed the function name when printing loop info (via -analyze option). Like this: Printing analysis 'Natural Loop Information' for function 'func': Loop at depth 1 containing: ... Loop at depth 2 containing: ... Make sure we print such a first line including the function name also when using the new pass manager version of LoopPrinterPass. The format of the string is changed slightly, so now we say: Loop info for function 'func': Loop at depth 1 containing: ... Loop at depth 2 containing: ... This was originally requested in https://discourse.llvm.org/t/need-usage-help-w-new-pass-manager-for-opt-analysis-natural-loop-information/75874/7 and also mentioned in https://github.com/llvm/llvm-project/issues/76762
2023-12-11[llvm] Use StringRef::{starts,ends}_with (NFC) (#74956)Kazu Hirata1-1/+1
This patch replaces uses of StringRef::{starts,ends}with with StringRef::{starts,ends}_with for consistency with std::{string,string_view}::{starts,ends}_with in C++20. I'm planning to deprecate and eventually remove StringRef::{starts,ends}with.
2023-09-27[LoopIterator] Add const qualifier to LoopInfo (NFC)Nikita Popov1-1/+1
Loop iteration utilities do not change LoopInfo.
2023-04-24[LoopInfo] Move generic LoopInfo into own filesChristian Ulmann1-5/+4
This commit splits the generic part of `LoopInfo` into separate files. These new `GenericLoopInfo` files are located in `llvm/Support` to be inline with `GenericDomTree`. Furthermore, this change ensures that MLIR's Bazel build does not have to link against `LLVMAnalysis` just to use these template headers. Depends on D148219 Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D148235
2022-12-14[Analysis] llvm::Optional => std::optionalFangrui Song1-8/+8
2022-12-02[Analysis] Use std::nullopt instead of None (NFC)Kazu Hirata1-6/+6
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-19[Analysis] Teach getOptionalIntLoopAttribute to return std::optional (NFC)Kazu Hirata1-4/+4
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-10-14[Loop] Move block and loop dispo invalidation to makeLoopInvariant.Florian Hahn1-5/+9
makeLoopInvariant may recursively move its operands to make them invariant, before moving the passed in instruction. Those recursively moved instructions are currently missed when invalidating block and loop dispositions. To address this, move the invalidation code to Loop::makeLoopInvariant. Fixes #58314. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D135909
2022-07-19[LoopInfo] Allow cloning of callbrNikita Popov1-4/+1
After D129288, callbr is safe to clone without special handling. This permits optimizations like loop unroll and loop unswitch on loops containing callbrs. Fixes https://github.com/llvm/llvm-project/issues/41834. Differential Revision: https://reviews.llvm.org/D129993
2022-07-19[NFC] Introduce API to detect tokens penetrating LCSSA formMax Kazantsev1-7/+7
Following discussion in PR56243, we need to somehow detect the situation when token values penetrate LCSSA form for transforms that require that it is maintained by all values (for example, to sustain use-def dominance invarians). This patch introduces a parameter to LCSSA checkers to control their ignorance about tokens. Differential Revision: https://reviews.llvm.org/D129983 Reviewed By: efriedma
2022-06-18[llvm] Use value_or instead of getValueOr (NFC)Kazu Hirata1-3/+3
2022-04-06Fix warnings about variables that are set but only used in debug modeMartin Storsjö1-0/+1
Add void casts to mark the variables used, next to the places where they are used in assert or `LLVM_DEBUG()` expressions. Differential Revision: https://reviews.llvm.org/D123117
2022-03-01Cleanup includes: LLVMAnalysisserge-sans-paille1-4/+0
Number of lines output by preprocessor: before: 1065940348 after: 1065307662 Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D120659
2022-01-28[ScalarEvolution] Mark a loop as finite if in a willreturn functionWilliam S. Moses1-0/+4
A limited version of (https://reviews.llvm.org/D118090) that only marks a loop as finite if in a willreturn function. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D118429
2022-01-23[Analysis] Use default member initialization (NFC)Kazu Hirata1-3/+2
Identified with modernize-use-default-member-init.
2021-11-11[LoopInfo] Fix function getInductionVariableduanbo.db1-3/+4
The way function gets the induction variable is by judging whether StepInst or IndVar in the phi statement is one of the operands of CMP. But if the LatchCmpOp0/LatchCmpOp1 is a constant, the subsequent comparison may result in null == null, which is meaningless. This patch fixes the typo. Reviewed By: Whitney Differential Revision: https://reviews.llvm.org/D112980
2021-09-04[OpenMP][OpenMPIRBuilder] Implement loop unrolling.Michael Kruse1-0/+5
Recommit of 707ce34b06190e275572c3c46843036db1bab6d1. Don't introduce a dependency to the LLVMPasses component, instead register the required passes individually. Add methods for loop unrolling to the OpenMPIRBuilder class and use them in Clang if `-fopenmp-enable-irbuilder` is enabled. The unrolling methods are: * `unrollLoopFull` * `unrollLoopPartial` * `unrollLoopHeuristic` `unrollLoopPartial` and `unrollLoopHeuristic` can use compiler heuristics to automatically determine the unroll factor. If possible, that is if no CanonicalLoopInfo is required to pass to another method, metadata for LLVM's LoopUnrollPass is added. Otherwise the unroll factor is determined using the same heurstics as user by LoopUnrollPass. Not requiring a CanonicalLoopInfo, especially with `unrollLoopHeuristic` allows greater flexibility. With full unrolling and partial unrolling with known unroll factor, instead of duplicating instructions by the OpenMPIRBuilder, the full unroll is still delegated to the LoopUnrollPass. In case of partial unrolling the loop is first tiled using the existing `tileLoops` methods, then the inner loop fully unrolled using the same mechanism. Reviewed By: jdoerfert, kiranchandramohan Differential Revision: https://reviews.llvm.org/D107764
2021-09-02Revert "[OpenMP][OpenMPIRBuilder] Implement loop unrolling."Roman Lebedev1-5/+0
Breaks build with -DBUILD_SHARED_LIBS=ON ``` CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle): "LLVMFrontendOpenMP" of type SHARED_LIBRARY depends on "LLVMPasses" (weak) "LLVMipo" of type SHARED_LIBRARY depends on "LLVMFrontendOpenMP" (weak) "LLVMCoroutines" of type SHARED_LIBRARY depends on "LLVMipo" (weak) "LLVMPasses" of type SHARED_LIBRARY depends on "LLVMCoroutines" (weak) depends on "LLVMipo" (weak) At least one of these targets is not a STATIC_LIBRARY. Cyclic dependencies are allowed only among static libraries. CMake Generate step failed. Build files cannot be regenerated correctly. ``` This reverts commit 707ce34b06190e275572c3c46843036db1bab6d1.
2021-09-02[OpenMP][OpenMPIRBuilder] Implement loop unrolling.Michael Kruse1-0/+5
Add methods for loop unrolling to the OpenMPIRBuilder class and use them in Clang if `-fopenmp-enable-irbuilder` is enabled. The unrolling methods are: * `unrollLoopFull` * `unrollLoopPartial` * `unrollLoopHeuristic` `unrollLoopPartial` and `unrollLoopHeuristic` can use compiler heuristics to automatically determine the unroll factor. If possible, that is if no CanonicalLoopInfo is required to pass to another method, metadata for LLVM's LoopUnrollPass is added. Otherwise the unroll factor is determined using the same heurstics as user by LoopUnrollPass. Not requiring a CanonicalLoopInfo, especially with `unrollLoopHeuristic` allows greater flexibility. With full unrolling and partial unrolling with known unroll factor, instead of duplicating instructions by the OpenMPIRBuilder, the full unroll is still delegated to the LoopUnrollPass. In case of partial unrolling the loop is first tiled using the existing `tileLoops` methods, then the inner loop fully unrolled using the same mechanism. Reviewed By: jdoerfert, kiranchandramohan Differential Revision: https://reviews.llvm.org/D107764
2021-07-21[LoopFlatten][LoopInfo] Use Loop to identify latch compare instructionRosie Sumpter1-4/+4
Make getLatchCmpInst non-static and use it in LoopFlatten as a more robust way of identifying the compare. Differential Revision: https://reviews.llvm.org/D106256
2021-06-10[LI] Add a cover function for checking if a loop is mustprogress [nfc]Philip Reames1-0/+4
Essentially, the cover function simply combines the loop level check and the function level scope into one call. This simplifies several callers and is (subjectively) less error prone.
2021-06-10Move code for checking loop metadata into Analysis [nfc]Philip Reames1-0/+62
I need the mustprogress loop metadata in ScalarEvolution and it makes sense to keep all the accessors for quering loop metadate together.
2021-05-07[LoopNest] Consider loop nest with inner loop guard using outer loopWhitney Tsang1-5/+12
induction variable to be perfect This patch allow more conditional branches to be considered as loop guard, and so more loop nests can be considered perfect. Reviewed By: bmahjour, sidbav Differential Revision: https://reviews.llvm.org/D94717
2021-04-15[NewPM] Cleanup IR printing instrumentationArthur Eubanks1-1/+1
Being lazy with printing the banner seems hard to reason with, we should print it unconditionally first (it could also lead to duplicate banners if we have multiple functions in -filter-print-funcs). The printIR() functions were doing too many things. I separated out the call from PrintPassInstrumentation since we were essentially doing two completely separate things in printIR() from different callers. There were multiple ways to generate the name of some IR. That's all been moved to getIRName(). The printing of the IR name was also inconsistent, now it's always "IR Dump on $foo" where "$foo" is the name. For a function, it's the function name. For a loop, it's what's printed by Loop::print(), which is more detailed. For an SCC, it's the list of functions in parentheses. For a module it's "[module]", to differentiate between a possible SCC with a function called "module". To preserve D74814, we have to check if we're going to print anything at all first. This is unfortunate, but I would consider this a special case that shouldn't be handled in the core logic. Reviewed By: jamieschmeiser Differential Revision: https://reviews.llvm.org/D100231
2021-03-17[LCSSA] Extract a utility for deciding if a new use requires a new lcssa phi ↵Philip Reames1-0/+25
[NFC] (Triggered by a review comment on D98728, but otherwise unrelated.)
2021-02-22[Analysis] Use range-based for loops (NFC)Kazu Hirata1-6/+3
2021-02-14[llvm] Use llvm::is_contained (NFC)Kazu Hirata1-9/+1
2021-02-06[Analysis] Use range-based for loops (NFC)Kazu Hirata1-4/+3
2021-01-18[llvm] Use the default value of drop_begin (NFC)Kazu Hirata1-1/+1
2020-12-03[NewPM] Support --print-before/after in NPMArthur Eubanks1-0/+1
This changes --print-before/after to be a list of strings rather than legacy passes. (this also has the effect of not showing the entire list of passes in --help-hidden after --print-before/after, which IMO is great for making it less verbose). Currently PrintIRInstrumentation passes the class name rather than pass name to llvm::shouldPrintBeforePass(), meaning llvm::shouldPrintBeforePass() never functions as intended in the NPM. There is no easy way of converting class names to pass names outside of within an instance of PassBuilder. This adds a map of pass class names to their short names in PassRegistry.def within PassInstrumentationCallbacks. It is populated inside the constructor of PassBuilder, which takes a PassInstrumentationCallbacks. Add a pointer to PassInstrumentationCallbacks inside PrintIRInstrumentation and use the newly created map. This is a bit hacky, but I can't think of a better way since the short id to class name only exists within PassRegistry.def. This also doesn't handle passes not in PassRegistry.def but rather added via PassBuilder::registerPipelineParsingCallback(). llvm/test/CodeGen/Generic/print-after.ll doesn't seem very useful now with this change. Reviewed By: ychen, jamieschmeiser Differential Revision: https://reviews.llvm.org/D87216
2020-11-04[LangRef] Adds llvm.loop.mustprogress loop metadataAtmn Patel1-0/+16
This patch adds the llvm.loop.mustprogress loop metadata. This is to be added to loops where the frontend language requires that the loop makes observable interactions with the environment. This is the loop-level equivalent to the function attribute `mustprogress` defined in D86233. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D88464
2020-10-29[LCSSA] Doc for special treatment of PHIsStefanos Baziotis1-0/+4
Differential Revision: https://reviews.llvm.org/D89739
2020-10-26Avoid unnecessary uses of `MDNode::getTemporary`, NFCDuncan P. N. Exon Smith1-2/+1
This is a long-delayed follow-up to 5e5b85098dbeaea2cfa5d01695b5d2982634d7dd. `TempMDNode` includes a bunch of machinery for RAUW, and should only be used when necessary. RAUW wasn't being used in any of these cases... it was just a placeholder for a self-reference. Where the real node was using `MDNode::getDistinct`, just replace the temporary argument with `nullptr`. Where the real node was using `MDNode::get`, the `replaceOperandWith` call was "promoting" the node to a distinct one implicitly due to self-reference detection in `MDNode::handleChangedOperand`. The `TempMDNode` was serving a purpose by delaying uniquing, but it's way simpler to just call `MDNode::getDistinct` in the first place. Note that using a self-reference at all in these places is a hold-over from before `distinct` metadata existed. It was an old trick to create distinct nodes. It would be intrusive to change, including bitcode upgrades, etc., and it's harmless so I'm not sure there's much value in removing it from existing schemas. After this commit it still has a tiny memory cost (in the extra metadata operand) but no more overhead in construction. Differential Revision: https://reviews.llvm.org/D90079
2020-09-22[LoopInfo] empty() -> isInnermost(), add isOutermost()Stefanos Baziotis1-3/+3
Differential Revision: https://reviews.llvm.org/D82895
2020-04-17[NFC] Add missing 'const' notion to LCSSA-related functionsMax Kazantsev1-3/+4
These functions don't really do any changes to loop info or dominator tree. We should state this explicitly using 'const'.