[llvm] 0736d1c - [ARM][MVE] Tail-predication: some more comments and debug messages. NFC.
Sjoerd Meijer via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 02:34:56 PDT 2020
Author: Sjoerd Meijer
Date: 2020-04-22T10:34:23+01:00
New Revision: 0736d1ccf32ba4e6fe860942d8a6d05f964f058e
URL: https://github.com/llvm/llvm-project/commit/0736d1ccf32ba4e6fe860942d8a6d05f964f058e
DIFF: https://github.com/llvm/llvm-project/commit/0736d1ccf32ba4e6fe860942d8a6d05f964f058e.diff
LOG: [ARM][MVE] Tail-predication: some more comments and debug messages. NFC.
Finding the loop tripcount is the first crucial step in preparing a loop for
tail-predication, and this adds a debug message if a tripcount cannot be found.
And while I was at it, I added some more comments here and there.
Differential Revision: https://reviews.llvm.org/D78485
Added:
Modified:
llvm/lib/Target/ARM/MVETailPredication.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/MVETailPredication.cpp b/llvm/lib/Target/ARM/MVETailPredication.cpp
index 26b71ba5b600..9325dd26bba7 100644
--- a/llvm/lib/Target/ARM/MVETailPredication.cpp
+++ b/llvm/lib/Target/ARM/MVETailPredication.cpp
@@ -8,8 +8,17 @@
//
/// \file
/// Armv8.1m introduced MVE, M-Profile Vector Extension, and low-overhead
-/// branches to help accelerate DSP applications. These two extensions can be
-/// combined to provide implicit vector predication within a low-overhead loop.
+/// branches to help accelerate DSP applications. These two extensions,
+/// combined with a new form of predication called tail-predication, can be used
+/// to provide implicit vector predication within a low-overhead loop.
+/// This is implicit because the predicate of active/inactive lanes is
+/// calculated by hardware, and thus does not need to be explicitly passed
+/// to vector instructions. The instructions responsible for this are the
+/// DLSTP and WLSTP instructions, which setup a tail-predicated loop and the
+/// the total number of data elements processed by the loop. The loop-end
+/// LETP instruction is responsible for decrementing and setting the remaining
+/// elements to be processed and generating the mask of active lanes.
+///
/// The HardwareLoops pass inserts intrinsics identifying loops that the
/// backend will attempt to convert into a low-overhead loop. The vectorizer is
/// responsible for generating a vectorized loop in which the lanes are
@@ -21,10 +30,16 @@
/// - A loop containing multiple VCPT instructions, predicating multiple VPT
/// blocks of instructions operating on
diff erent vector types.
///
-/// This pass inserts the inserts the VCTP intrinsic to represent the effect of
-/// tail predication. This will be picked up by the ARM Low-overhead loop pass,
-/// which performs the final transformation to a DLSTP or WLSTP tail-predicated
-/// loop.
+/// This pass:
+/// 1) Pattern matches the scalar iteration count produced by the vectoriser.
+/// The scalar loop iteration count represents the number of elements to be
+/// processed.
+/// TODO: this could be emitted using an intrinsic, similar to the hardware
+/// loop intrinsics, so that we don't need to pattern match this here.
+/// 2) Inserts the VCTP intrinsic to represent the effect of
+/// tail predication. This will be picked up by the ARM Low-overhead loop
+/// pass, which performs the final transformation to a DLSTP or WLSTP
+/// tail-predicated loop.
#include "ARM.h"
#include "ARMSubtarget.h"
@@ -58,16 +73,17 @@ namespace {
// Bookkeeping for pattern matching the loop trip count and the number of
// elements processed by the loop.
struct TripCountPattern {
- // The Predicate used by the masked loads/stores, i.e. an icmp instruction
- // which calculates active/inactive lanes
+ // An icmp instruction that calculates a predicate of active/inactive lanes
+ // used by the masked loads/stores.
Instruction *Predicate = nullptr;
- // The add instruction that increments the IV
+ // The add instruction that increments the IV.
Value *TripCount = nullptr;
// The number of elements processed by the vector loop.
Value *NumElements = nullptr;
+ // Other instructions in the icmp chain that calculate the predicate.
VectorType *VecTy = nullptr;
Instruction *Shuffle = nullptr;
Instruction *Induction = nullptr;
@@ -117,8 +133,9 @@ class MVETailPredication : public LoopPass {
/// loop will process if it is a runtime value.
bool ComputeRuntimeElements(TripCountPattern &TCP);
- /// Is the icmp that generates an i1 vector, based upon a loop counter
- /// and a limit that is defined outside the loop.
+ /// Return whether this is the icmp that generates an i1 vector, based
+ /// upon a loop counter and a limit that is defined outside the loop,
+ /// that generates the active/inactive lanes required for tail-predication.
bool isTailPredicate(TripCountPattern &TCP);
/// Insert the intrinsic to represent the effect of tail predication.
@@ -241,6 +258,7 @@ bool MVETailPredication::runOnLoop(Loop *L, LPPassManager&) {
return true;
}
+ LLVM_DEBUG(dbgs() << "ARM TP: Can't tail-predicate this loop.\n");
return false;
}
@@ -563,10 +581,10 @@ static bool Cleanup(DenseMap<Instruction*, Instruction*> &NewPredicates,
if (I->hasNUsesOrMore(1))
continue;
- for (auto &U : I->operands()) {
+ for (auto &U : I->operands())
if (auto *OpI = dyn_cast<Instruction>(U))
MaybeDead.insert(OpI);
- }
+
I->dropAllReferences();
Dead.insert(I);
}
@@ -638,30 +656,47 @@ bool MVETailPredication::TryConvert(Value *TripCount) {
SetVector<Instruction*> Predicates;
DenseMap<Instruction*, Instruction*> NewPredicates;
+#ifndef NDEBUG
+ // For debugging purposes, use this to indicate we have been able to
+ // pattern match the scalar loop trip count.
+ bool FoundScalarTC = false;
+#endif
+
for (auto *I : MaskedInsts) {
Intrinsic::ID ID = I->getIntrinsicID();
+ // First, find the icmp used by this masked load/store.
unsigned PredOp = ID == Intrinsic::masked_load ? 2 : 3;
auto *Predicate = dyn_cast<Instruction>(I->getArgOperand(PredOp));
if (!Predicate || Predicates.count(Predicate))
continue;
+ // Step 1: using this icmp, now calculate the number of elements
+ // processed by this loop.
TripCountPattern TCP(Predicate, TripCount, getVectorType(I));
-
if (!(ComputeConstElements(TCP) || ComputeRuntimeElements(TCP)))
continue;
+ LLVM_DEBUG(FoundScalarTC = true);
+
if (!isTailPredicate(TCP)) {
- LLVM_DEBUG(dbgs() << "ARM TP: Not tail predicate: " << *Predicate << "\n");
+ LLVM_DEBUG(dbgs() << "ARM TP: Not an icmp that generates tail predicate: "
+ << *Predicate << "\n");
continue;
}
- LLVM_DEBUG(dbgs() << "ARM TP: Found tail predicate: " << *Predicate << "\n");
+ LLVM_DEBUG(dbgs() << "ARM TP: Found icmp generating tail predicate: "
+ << *Predicate << "\n");
Predicates.insert(Predicate);
+
+ // Step 2: emit the VCTP intrinsic representing the effect of TP.
InsertVCTPIntrinsic(TCP, NewPredicates);
}
- if (!NewPredicates.size())
+ if (!NewPredicates.size()) {
+ LLVM_DEBUG(if (!FoundScalarTC)
+ dbgs() << "ARM TP: Can't determine loop itertion count\n");
return false;
+ }
// Now clean up.
ClonedVCTPInExitBlock = Cleanup(NewPredicates, Predicates, L);
More information about the llvm-commits
mailing list