Skip to content

Commit

Permalink
!fixup address comments, thanks!
Browse files Browse the repository at this point in the history
  • Loading branch information
fhahn committed Jul 26, 2024
1 parent d5bcc97 commit 6f1b14d
Showing 1 changed file with 32 additions and 40 deletions.
72 changes: 32 additions & 40 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,23 +890,19 @@ static void debugVectorizationMessage(const StringRef Prefix,
/// \p PassName is the name of the pass (e.g. can be AlwaysPrint). \p
/// RemarkName is the identifier for the remark. If \p I is passed it is an
/// instruction that prevents vectorization. Otherwise \p TheLoop is used for
/// the location of the remark. \return the remark object that can be
/// streamed to.
/// the location of the remark. If \p DL is passed, use it as debug location for
/// the remark. \return the remark object that can be streamed to.
static OptimizationRemarkAnalysis
createLVAnalysis(const char *PassName, StringRef RemarkName, Loop *TheLoop,
Instruction *I, DebugLoc DL = {}) {
Value *CodeRegion = TheLoop->getHeader();
if (!DL)
Value *CodeRegion = I ? I->getParent() : TheLoop->getHeader();
// If debug location is attached to the instruction, use it. Otherwise if DL
// was not provided, use the loop's.
if (I && I->getDebugLoc())
DL = I->getDebugLoc();
else if (!DL)
DL = TheLoop->getStartLoc();

if (I) {
CodeRegion = I->getParent();
// If there is no debug location attached to the instruction, revert back to
// using the loop's.
if (I->getDebugLoc())
DL = I->getDebugLoc();
}

return OptimizationRemarkAnalysis(PassName, RemarkName, DL, CodeRegion);
}

Expand Down Expand Up @@ -946,7 +942,8 @@ void reportVectorizationFailure(const StringRef DebugMsg,

/// Reports an informative message: print \p Msg for debugging purposes as well
/// as an optimization remark. Uses either \p I as location of the remark, or
/// otherwise \p TheLoop.
/// otherwise \p TheLoop. If \p DL is passed, use it as debug location for the
/// remark. If \p DL is passed, use it as debug location for the remark.
static void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag,
OptimizationRemarkEmitter *ORE,
Loop *TheLoop, Instruction *I = nullptr,
Expand Down Expand Up @@ -1542,9 +1539,7 @@ class LoopVectorizationCostModel {
/// Returns the expected execution cost. The unit of the cost does
/// not matter because we use the 'cost' units to compare different
/// vector widths. The cost that is returned is *not* normalized by
/// the factor width. If \p Invalid is not nullptr, this function
/// will add a pair(Instruction*, ElementCount) to \p Invalid for
/// each instruction that has an Invalid cost for the given VF.
/// the factor width.
InstructionCost expectedCost(ElementCount VF);

bool hasPredStores() const { return NumPredStores > 0; }
Expand Down Expand Up @@ -4354,22 +4349,18 @@ bool LoopVectorizationPlanner::isMoreProfitable(

void LoopVectorizationPlanner::emitInvalidCostRemarks(
OptimizationRemarkEmitter *ORE) {
if (VPlans.empty())
return;

using RecipeVFPair = std::pair<VPRecipeBase *, ElementCount>;
LLVMContext &LLVMCtx = OrigLoop->getHeader()->getContext();
SmallVector<RecipeVFPair> InvalidCosts;
for (const auto &Plan : VPlans) {
for (ElementCount VF : Plan->vectorFactors()) {
LLVMContext &LLVMCtx = OrigLoop->getHeader()->getContext();
VPCostContext CostCtx(CM.TTI, Legal->getWidestInductionType(), LLVMCtx,
CM);
auto Iter = vp_depth_first_deep(Plan->getVectorLoopRegion()->getEntry());
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(Iter)) {
for (auto &R : *VPBB) {
if (R.cost(VF, CostCtx).isValid())
continue;
InvalidCosts.emplace_back(&R, VF);
if (!R.cost(VF, CostCtx).isValid())
InvalidCosts.emplace_back(&R, VF);
}
}
}
Expand All @@ -4379,15 +4370,14 @@ void LoopVectorizationPlanner::emitInvalidCostRemarks(

// Emit a report of VFs with invalid costs in the loop.

// Group the remarks per instruction, keeping the instruction order from
// InvalidCosts.
// Group the remarks per recipe, keeping the recipe order from InvalidCosts.
DenseMap<VPRecipeBase *, unsigned> Numbering;
unsigned I = 0;
for (auto &Pair : InvalidCosts)
if (!Numbering.count(Pair.first))
Numbering[Pair.first] = I++;

// Sort the list, first on instruction(number) then on VF.
// Sort the list, first on recipe(number) then on VF.
sort(InvalidCosts, [&Numbering](RecipeVFPair &A, RecipeVFPair &B) {
if (Numbering[A.first] != Numbering[B.first])
return Numbering[A.first] < Numbering[B.first];
Expand All @@ -4397,11 +4387,11 @@ void LoopVectorizationPlanner::emitInvalidCostRemarks(
std::make_tuple(RHS.isScalable(), RHS.getKnownMinValue());
});

// For a list of ordered instruction-vf pairs:
// [(load, vf1), (load, vf2), (store, vf1)]
// Group the instructions together to emit separate remarks for:
// load (vf1, vf2)
// store (vf1)
// For a list of ordered recipe-VF pairs:
// [(load, VF1), (load, VF2), (store, VF1)]
// group the recipes together to emit separate remarks for:
// load (VF1, VF2)
// store (VF1)
auto Tail = ArrayRef<RecipeVFPair>(InvalidCosts);
auto Subset = ArrayRef<RecipeVFPair>();
do {
Expand Down Expand Up @@ -4430,11 +4420,11 @@ void LoopVectorizationPlanner::emitInvalidCostRemarks(
: Instruction::Store;
});

// If the next instruction is different, or if there are no other pairs,
// If the next recipe is different, or if there are no other pairs,
// emit a remark for the collated subset. e.g.
// [(load, vf1), (load, vf2))]
// [(load, VF1), (load, VF2))]
// to emit:
// remark: invalid costs for 'load' at VF=(vf, vf2)
// remark: invalid costs for 'load' at VF=(VF1, VF2)
if (Subset == Tail || Tail[Subset.size()].first != R) {
std::string OutString;
raw_string_ostream OS(OutString);
Expand All @@ -4443,12 +4433,14 @@ void LoopVectorizationPlanner::emitInvalidCostRemarks(
for (const auto &Pair : Subset)
OS << (Pair.second == Subset.front().second ? "" : ", ") << Pair.second;
OS << "):";
if (Opcode == Instruction::Call)
OS << " call to "
<< R->getOperand(R->getNumOperands() - 1)
->getLiveInIRValue()
->getName();
else
if (Opcode == Instruction::Call) {
auto *WidenCall = dyn_cast<VPWidenCallRecipe>(R);
Function *CalledFn =
WidenCall ? WidenCall->getCalledScalarFunction()
: cast<Function>(R->getOperand(R->getNumOperands() - 1)
->getLiveInIRValue());
OS << " call to " << CalledFn->getName();
} else
OS << " " << Instruction::getOpcodeName(Opcode);
OS.flush();
reportVectorizationInfo(OutString, "InvalidCost", ORE, OrigLoop, nullptr,
Expand Down

0 comments on commit 6f1b14d

Please sign in to comment.