[llvm] r362736 - [LV] Wrap LV illegality reporting in a function. NFC.
Renato Golin via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 6 12:15:52 PDT 2019
Author: rengolin
Date: Thu Jun 6 12:15:52 2019
New Revision: 362736
URL: http://llvm.org/viewvc/llvm-project?rev=362736&view=rev
Log:
[LV] Wrap LV illegality reporting in a function. NFC.
A function for loop vectorization illegality reporting has been
introduced:
void LoopVectorizationLegality::reportVectorizationFailure(
const StringRef DebugMsg, const StringRef OREMsg,
const StringRef ORETag, Instruction * const I) const;
The function prints a debug message when the debug for the compilation
unit is enabled as well as invokes the optimization report emitter to
generate a message with a specified tag. The function doesn't cover any
complicated logic when a custom lambda should be passed to the emitter,
only generating a message with a tag is supported.
The function always prints the instruction `I` after the debug message
whenever the instruction is specified, otherwise the debug message
ends with a dot: 'LV: Not vectorizing: Disabled/already vectorized.'
Patch by Pavel Samolysov <samolisov at gmail.com>
Modified:
llvm/trunk/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
llvm/trunk/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
Modified: llvm/trunk/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h?rev=362736&r1=362735&r2=362736&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h (original)
+++ llvm/trunk/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h Thu Jun 6 12:15:52 2019
@@ -371,18 +371,6 @@ private:
void addInductionPhi(PHINode *Phi, const InductionDescriptor &ID,
SmallPtrSetImpl<Value *> &AllowedExit);
- /// Create an analysis remark that explains why vectorization failed
- ///
- /// \p RemarkName is the identifier for the remark. If \p I is passed it is
- /// an instruction that prevents vectorization. Otherwise the loop is used
- /// for the location of the remark. \return the remark object that can be
- /// streamed to.
- OptimizationRemarkAnalysis
- createMissedAnalysis(StringRef RemarkName, Instruction *I = nullptr) const {
- return createLVMissedAnalysis(Hints->vectorizeAnalysisPassName(),
- RemarkName, TheLoop, I);
- }
-
/// If an access has a symbolic strides, this maps the pointer value to
/// the stride symbol.
const ValueToValueMap *getSymbolicStrides() {
@@ -393,6 +381,14 @@ private:
return LAI ? &LAI->getSymbolicStrides() : nullptr;
}
+ /// Reports a vectorization illegality: print \p DebugMsg for debugging
+ /// purposes along with the corresponding optimization remark \p RemarkName.
+ /// If \p I is passed it is an instruction that prevents vectorization.
+ /// Otherwise the loop is used for the location of the remark.
+ void reportVectorizationFailure(const StringRef DebugMsg,
+ const StringRef OREMsg, const StringRef ORETag,
+ Instruction *I = nullptr) const;
+
/// The loop that we evaluate.
Loop *TheLoop;
Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp?rev=362736&r1=362735&r2=362736&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp (original)
+++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp Thu Jun 6 12:15:52 2019
@@ -47,6 +47,16 @@ static const unsigned MaxInterleaveFacto
namespace llvm {
+static void debugVectorizationFailure(const StringRef DebugMsg,
+ Instruction *I) {
+ dbgs() << "LV: Not vectorizing: " << DebugMsg;
+ if (I != nullptr)
+ dbgs() << " " << *I;
+ else
+ dbgs() << '.';
+ dbgs() << '\n';
+}
+
OptimizationRemarkAnalysis createLVMissedAnalysis(const char *PassName,
StringRef RemarkName,
Loop *TheLoop,
@@ -433,6 +443,14 @@ bool LoopVectorizationLegality::isUnifor
return LAI->isUniform(V);
}
+void LoopVectorizationLegality::reportVectorizationFailure(
+ const StringRef DebugMsg, const StringRef OREMsg,
+ const StringRef ORETag, Instruction *I) const {
+ LLVM_DEBUG(debugVectorizationFailure(DebugMsg, I));
+ ORE->emit(createLVMissedAnalysis(Hints->vectorizeAnalysisPassName(),
+ ORETag, TheLoop, I) << OREMsg);
+}
+
bool LoopVectorizationLegality::canVectorizeOuterLoop() {
assert(!TheLoop->empty() && "We are not vectorizing an outer loop.");
// Store the result and return it at the end instead of exiting early, in case
@@ -445,9 +463,9 @@ bool LoopVectorizationLegality::canVecto
// not supported yet.
auto *Br = dyn_cast<BranchInst>(BB->getTerminator());
if (!Br) {
- LLVM_DEBUG(dbgs() << "LV: Unsupported basic block terminator.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("Unsupported basic block terminator",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -464,9 +482,9 @@ bool LoopVectorizationLegality::canVecto
!TheLoop->isLoopInvariant(Br->getCondition()) &&
!LI->isLoopHeader(Br->getSuccessor(0)) &&
!LI->isLoopHeader(Br->getSuccessor(1))) {
- LLVM_DEBUG(dbgs() << "LV: Unsupported conditional branch.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("Unsupported conditional branch",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -478,11 +496,9 @@ bool LoopVectorizationLegality::canVecto
// simple outer loops scenarios with uniform nested loops.
if (!isUniformLoopNest(TheLoop /*loop nest*/,
TheLoop /*context outer loop*/)) {
- LLVM_DEBUG(
- dbgs()
- << "LV: Not vectorizing: Outer loop contains divergent loops.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("Outer loop contains divergent loops",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -491,10 +507,9 @@ bool LoopVectorizationLegality::canVecto
// Check whether we are able to set up outer loop induction.
if (!setupOuterLoopInductions()) {
- LLVM_DEBUG(
- dbgs() << "LV: Not vectorizing: Unsupported outer loop Phi(s).\n");
- ORE->emit(createMissedAnalysis("UnsupportedPhi")
- << "Unsupported outer loop Phi(s)");
+ reportVectorizationFailure("Unsupported outer loop Phi(s)",
+ "Unsupported outer loop Phi(s)",
+ "UnsupportedPhi");
if (DoExtraAnalysis)
Result = false;
else
@@ -599,10 +614,9 @@ bool LoopVectorizationLegality::canVecto
// Check that this PHI type is allowed.
if (!PhiTy->isIntegerTy() && !PhiTy->isFloatingPointTy() &&
!PhiTy->isPointerTy()) {
- LLVM_DEBUG(dbgs()
- << "LV: Not vectorizing: Found a non-int non-pointer PHI.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood", Phi)
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("Found a non-int non-pointer PHI",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
return false;
}
@@ -620,9 +634,9 @@ bool LoopVectorizationLegality::canVecto
// We only allow if-converted PHIs with exactly two incoming values.
if (Phi->getNumIncomingValues() != 2) {
- ORE->emit(createMissedAnalysis("CFGNotUnderstood", Phi)
- << "control flow not understood by vectorizer");
- LLVM_DEBUG(dbgs() << "LV: Found an invalid PHI.\n");
+ reportVectorizationFailure("Found an invalid PHI",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood", Phi);
return false;
}
@@ -671,10 +685,10 @@ bool LoopVectorizationLegality::canVecto
continue;
}
- ORE->emit(createMissedAnalysis("NonReductionValueUsedOutsideLoop", Phi)
- << "value that could not be identified as "
- "reduction is used outside the loop");
- LLVM_DEBUG(dbgs() << "LV: Found an unidentified PHI." << *Phi << "\n");
+ reportVectorizationFailure("Found an unidentified PHI",
+ "value that could not be identified as "
+ "reduction is used outside the loop",
+ "NonReductionValueUsedOutsideLoop", Phi);
return false;
} // end of PHI handling
@@ -701,16 +715,16 @@ bool LoopVectorizationLegality::canVecto
// but it's hard to provide meaningful yet generic advice.
// Also, should this be guarded by allowExtraAnalysis() and/or be part
// of the returned info from isFunctionVectorizable()?
- ORE->emit(createMissedAnalysis("CantVectorizeLibcall", CI)
- << "library call cannot be vectorized. "
- "Try compiling with -fno-math-errno, -ffast-math, "
- "or similar flags");
+ reportVectorizationFailure("Found a non-intrinsic callsite",
+ "library call cannot be vectorized. "
+ "Try compiling with -fno-math-errno, -ffast-math, "
+ "or similar flags",
+ "CantVectorizeLibcall", CI);
} else {
- ORE->emit(createMissedAnalysis("CantVectorizeCall", CI)
- << "call instruction cannot be vectorized");
+ reportVectorizationFailure("Found a non-intrinsic callsite",
+ "call instruction cannot be vectorized",
+ "CantVectorizeLibcall", CI);
}
- LLVM_DEBUG(
- dbgs() << "LV: Found a non-intrinsic callsite.\n");
return false;
}
@@ -722,10 +736,9 @@ bool LoopVectorizationLegality::canVecto
for (unsigned i = 0, e = CI->getNumArgOperands(); i != e; ++i)
if (hasVectorInstrinsicScalarOpd(IntrinID, i)) {
if (!SE->isLoopInvariant(PSE.getSCEV(CI->getOperand(i)), TheLoop)) {
- ORE->emit(createMissedAnalysis("CantVectorizeIntrinsic", CI)
- << "intrinsic instruction cannot be vectorized");
- LLVM_DEBUG(dbgs() << "LV: Found unvectorizable intrinsic " << *CI
- << "\n");
+ reportVectorizationFailure("Found unvectorizable intrinsic",
+ "intrinsic instruction cannot be vectorized",
+ "CantVectorizeIntrinsic", CI);
return false;
}
}
@@ -736,9 +749,9 @@ bool LoopVectorizationLegality::canVecto
if ((!VectorType::isValidElementType(I.getType()) &&
!I.getType()->isVoidTy()) ||
isa<ExtractElementInst>(I)) {
- ORE->emit(createMissedAnalysis("CantVectorizeInstructionReturnType", &I)
- << "instruction return type cannot be vectorized");
- LLVM_DEBUG(dbgs() << "LV: Found unvectorizable type.\n");
+ reportVectorizationFailure("Found unvectorizable type",
+ "instruction return type cannot be vectorized",
+ "CantVectorizeInstructionReturnType", &I);
return false;
}
@@ -746,8 +759,9 @@ bool LoopVectorizationLegality::canVecto
if (auto *ST = dyn_cast<StoreInst>(&I)) {
Type *T = ST->getValueOperand()->getType();
if (!VectorType::isValidElementType(T)) {
- ORE->emit(createMissedAnalysis("CantVectorizeStore", ST)
- << "store instruction cannot be vectorized");
+ reportVectorizationFailure("Store instruction cannot be vectorized",
+ "store instruction cannot be vectorized",
+ "CantVectorizeStore", ST);
return false;
}
@@ -773,23 +787,27 @@ bool LoopVectorizationLegality::canVecto
AllowedExit.insert(&I);
continue;
}
- ORE->emit(createMissedAnalysis("ValueUsedOutsideLoop", &I)
- << "value cannot be used outside the loop");
+ reportVectorizationFailure("Value cannot be used outside the loop",
+ "value cannot be used outside the loop",
+ "ValueUsedOutsideLoop", &I);
return false;
}
} // next instr.
}
if (!PrimaryInduction) {
- LLVM_DEBUG(dbgs() << "LV: Did not find one integer induction var.\n");
if (Inductions.empty()) {
- ORE->emit(createMissedAnalysis("NoInductionVariable")
- << "loop induction variable could not be identified");
+ reportVectorizationFailure("Did not find one integer induction var",
+ "loop induction variable could not be identified",
+ "NoInductionVariable");
return false;
} else if (!WidestIndTy) {
- ORE->emit(createMissedAnalysis("NoIntegerInductionVariable")
- << "integer loop induction variable could not be identified");
+ reportVectorizationFailure("Did not find one integer induction var",
+ "integer loop induction variable could not be identified",
+ "NoIntegerInductionVariable");
return false;
+ } else {
+ LLVM_DEBUG(dbgs() << "LV: Did not find one integer induction var.\n");
}
}
@@ -815,11 +833,9 @@ bool LoopVectorizationLegality::canVecto
return false;
if (LAI->hasDependenceInvolvingLoopInvariantAddress()) {
- ORE->emit(createMissedAnalysis("CantVectorizeStoreToLoopInvariantAddress")
- << "write to a loop invariant address could not "
- "be vectorized");
- LLVM_DEBUG(
- dbgs() << "LV: Non vectorizable stores to a uniform address\n");
+ reportVectorizationFailure("Stores to a uniform address",
+ "write to a loop invariant address could not be vectorized",
+ "CantVectorizeStoreToLoopInvariantAddress");
return false;
}
Requirements->addRuntimePointerChecks(LAI->getNumRuntimePointerChecks());
@@ -901,8 +917,9 @@ bool LoopVectorizationLegality::blockCan
bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
if (!EnableIfConversion) {
- ORE->emit(createMissedAnalysis("IfConversionDisabled")
- << "if-conversion is disabled");
+ reportVectorizationFailure("If-conversion is disabled",
+ "if-conversion is disabled",
+ "IfConversionDisabled");
return false;
}
@@ -926,21 +943,26 @@ bool LoopVectorizationLegality::canVecto
for (BasicBlock *BB : TheLoop->blocks()) {
// We don't support switch statements inside loops.
if (!isa<BranchInst>(BB->getTerminator())) {
- ORE->emit(createMissedAnalysis("LoopContainsSwitch", BB->getTerminator())
- << "loop contains a switch statement");
+ reportVectorizationFailure("Loop contains a switch statement",
+ "loop contains a switch statement",
+ "LoopContainsSwitch", BB->getTerminator());
return false;
}
// We must be able to predicate all blocks that need to be predicated.
if (blockNeedsPredication(BB)) {
if (!blockCanBePredicated(BB, SafePointes)) {
- ORE->emit(createMissedAnalysis("NoCFGForSelect", BB->getTerminator())
- << "control flow cannot be substituted for a select");
+ reportVectorizationFailure(
+ "Control flow cannot be substituted for a select",
+ "control flow cannot be substituted for a select",
+ "NoCFGForSelect", BB->getTerminator());
return false;
}
} else if (BB != Header && !canIfConvertPHINodes(BB)) {
- ORE->emit(createMissedAnalysis("NoCFGForSelect", BB->getTerminator())
- << "control flow cannot be substituted for a select");
+ reportVectorizationFailure(
+ "Control flow cannot be substituted for a select",
+ "control flow cannot be substituted for a select",
+ "NoCFGForSelect", BB->getTerminator());
return false;
}
}
@@ -968,10 +990,9 @@ bool LoopVectorizationLegality::canVecto
// We must have a loop in canonical form. Loops with indirectbr in them cannot
// be canonicalized.
if (!Lp->getLoopPreheader()) {
- LLVM_DEBUG(dbgs()
- << "LV: Not vectorizing: Loop doesn't have a legal pre-header.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("Loop doesn't have a legal pre-header",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -980,10 +1001,9 @@ bool LoopVectorizationLegality::canVecto
// We must have a single backedge.
if (Lp->getNumBackEdges() != 1) {
- LLVM_DEBUG(dbgs()
- << "LV: Not vectorizing: The loop must have a single backedge.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("The loop must have a single backedge",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -992,10 +1012,9 @@ bool LoopVectorizationLegality::canVecto
// We must have a single exiting block.
if (!Lp->getExitingBlock()) {
- LLVM_DEBUG(dbgs()
- << "LV: Not vectorizing: The loop must have an exiting block.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("The loop must have an exiting block",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -1006,10 +1025,9 @@ bool LoopVectorizationLegality::canVecto
// checked at the end of each iteration. With that we can assume that all
// instructions in the loop are executed the same number of times.
if (Lp->getExitingBlock() != Lp->getLoopLatch()) {
- LLVM_DEBUG(dbgs()
- << "LV: Not vectorizing: The exiting block is not the loop latch.\n");
- ORE->emit(createMissedAnalysis("CFGNotUnderstood")
- << "loop control flow is not understood by vectorizer");
+ reportVectorizationFailure("The exiting block is not the loop latch",
+ "loop control flow is not understood by vectorizer",
+ "CFGNotUnderstood");
if (DoExtraAnalysis)
Result = false;
else
@@ -1070,7 +1088,9 @@ bool LoopVectorizationLegality::canVecto
assert(UseVPlanNativePath && "VPlan-native path is not enabled.");
if (!canVectorizeOuterLoop()) {
- LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Unsupported outer loop.\n");
+ reportVectorizationFailure("Unsupported outer loop",
+ "unsupported outer loop",
+ "UnsupportedOuterLoop");
// TODO: Implement DoExtraAnalysis when subsequent legal checks support
// outer loops.
return false;
@@ -1120,10 +1140,9 @@ bool LoopVectorizationLegality::canVecto
SCEVThreshold = PragmaVectorizeSCEVCheckThreshold;
if (PSE.getUnionPredicate().getComplexity() > SCEVThreshold) {
- ORE->emit(createMissedAnalysis("TooManySCEVRunTimeChecks")
- << "Too many SCEV assumptions need to be made and checked "
- << "at runtime");
- LLVM_DEBUG(dbgs() << "LV: Too many SCEV checks needed.\n");
+ reportVectorizationFailure("Too many SCEV checks needed",
+ "Too many SCEV assumptions need to be made and checked at runtime",
+ "TooManySCEVRunTimeChecks");
if (DoExtraAnalysis)
Result = false;
else
@@ -1142,20 +1161,20 @@ bool LoopVectorizationLegality::canFoldT
LLVM_DEBUG(dbgs() << "LV: checking if tail can be folded by masking.\n");
if (!PrimaryInduction) {
- ORE->emit(createMissedAnalysis("NoPrimaryInduction")
- << "Missing a primary induction variable in the loop, which is "
- << "needed in order to fold tail by masking as required.");
- LLVM_DEBUG(dbgs() << "LV: No primary induction, cannot fold tail by "
- << "masking.\n");
+ reportVectorizationFailure(
+ "No primary induction, cannot fold tail by masking",
+ "Missing a primary induction variable in the loop, which is "
+ "needed in order to fold tail by masking as required.",
+ "NoPrimaryInduction");
return false;
}
// TODO: handle reductions when tail is folded by masking.
if (!Reductions.empty()) {
- ORE->emit(createMissedAnalysis("ReductionFoldingTailByMasking")
- << "Cannot fold tail by masking in the presence of reductions.");
- LLVM_DEBUG(dbgs() << "LV: Loop has reductions, cannot fold tail by "
- << "masking.\n");
+ reportVectorizationFailure(
+ "Loop has reductions, cannot fold tail by masking",
+ "Cannot fold tail by masking in the presence of reductions.",
+ "ReductionFoldingTailByMasking");
return false;
}
@@ -1166,10 +1185,10 @@ bool LoopVectorizationLegality::canFoldT
Instruction *UI = cast<Instruction>(U);
if (TheLoop->contains(UI))
continue;
- ORE->emit(createMissedAnalysis("LiveOutFoldingTailByMasking")
- << "Cannot fold tail by masking in the presence of live outs.");
- LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking, loop has an "
- << "outside user for : " << *UI << '\n');
+ reportVectorizationFailure(
+ "Cannot fold tail by masking, loop has an outside user for",
+ "Cannot fold tail by masking in the presence of live outs.",
+ "LiveOutFoldingTailByMasking", UI);
return false;
}
}
@@ -1181,9 +1200,10 @@ bool LoopVectorizationLegality::canFoldT
// do not need predication such as the header block.
for (BasicBlock *BB : TheLoop->blocks()) {
if (!blockCanBePredicated(BB, SafePointers)) {
- ORE->emit(createMissedAnalysis("NoCFGForSelect", BB->getTerminator())
- << "control flow cannot be substituted for a select");
- LLVM_DEBUG(dbgs() << "LV: Cannot fold tail by masking as required.\n");
+ reportVectorizationFailure(
+ "Cannot fold tail by masking as required",
+ "control flow cannot be substituted for a select",
+ "NoCFGForSelect", BB->getTerminator());
return false;
}
}
More information about the llvm-commits
mailing list