diff options
author | Joel E. Denny <jdenny.ornl@gmail.com> | 2025-07-31 12:28:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-31 12:28:25 -0400 |
commit | f7b65011de519b1bd987892475db61f99dde44ce (patch) | |
tree | 5550563d8ac0f12271a6cb7d948ba559f4301b78 /llvm/lib/IR/Verifier.cpp | |
parent | 3e579d93ab50952628a51bda05f3a39f6a5a631c (diff) | |
download | llvm-f7b65011de519b1bd987892475db61f99dde44ce.zip llvm-f7b65011de519b1bd987892475db61f99dde44ce.tar.gz llvm-f7b65011de519b1bd987892475db61f99dde44ce.tar.bz2 |
[PGO] Add `llvm.loop.estimated_trip_count` metadata (#148758)
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.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 3ff9895..924b5da 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -121,6 +121,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/ModRef.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/LoopUtils.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -1071,6 +1072,21 @@ void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) { } } + // Check llvm.loop.estimated_trip_count. + if (MD.getNumOperands() > 0 && + MD.getOperand(0).equalsStr(LLVMLoopEstimatedTripCount)) { + Check(MD.getNumOperands() == 1 || MD.getNumOperands() == 2, + "Expected one or two operands", &MD); + if (MD.getNumOperands() == 2) { + auto *Count = dyn_cast_or_null<ConstantAsMetadata>(MD.getOperand(1)); + Check(Count && Count->getType()->isIntegerTy() && + cast<IntegerType>(Count->getType())->getBitWidth() <= 32, + "Expected optional second operand to be an integer constant of " + "type i32 or smaller", + &MD); + } + } + // Check these last, so we diagnose problems in operands first. Check(!MD.isTemporary(), "Expected no forward declarations!", &MD); Check(MD.isResolved(), "All nodes should be resolved!", &MD); |