1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

[NFC] Convert OptimizationRemarkEmitter old emit() calls to new closure

parameterized emit() calls

Summary: This is not functional change to adopt new emit() API added in r313691.

Reviewed By: anemet

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D38285

llvm-svn: 315476
This commit is contained in:
Vivek Pandya 2017-10-11 17:12:59 +00:00
parent da076b8a6c
commit aa23fb5991
23 changed files with 532 additions and 372 deletions

View File

@ -164,6 +164,21 @@ public:
.getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
}
/// \brief Take a lambda that returns a remark which will be emitted. Second
/// argument is only used to restrict this to functions.
template <typename T>
void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
// Avoid building the remark unless we know there are at least *some*
// remarks enabled. We can't currently check whether remarks are requested
// for the calling pass since that requires actually building the remark.
if (MF.getFunction()->getContext().getDiagnosticsOutputFile() ||
MF.getFunction()->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
auto R = RemarkBuilder();
emit(R);
}
}
private:
MachineFunction &MF;

View File

@ -1440,10 +1440,12 @@ bool CallAnalyzer::analyzeBlock(BasicBlock *BB,
if (IsRecursiveCall || ExposesReturnsTwice || HasDynamicAlloca ||
HasIndirectBr || HasFrameEscape) {
if (ORE)
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
<< NV("Callee", &F)
<< " has uninlinable pattern and cost is not fully computed");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
<< NV("Callee", &F)
<< " has uninlinable pattern and cost is not fully computed";
});
return false;
}
@ -1453,12 +1455,13 @@ bool CallAnalyzer::analyzeBlock(BasicBlock *BB,
if (IsCallerRecursive &&
AllocatedSize > InlineConstants::TotalAllocaSizeRecursiveCaller) {
if (ORE)
ORE->emit(
OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
<< NV("Callee", &F)
<< " is recursive and allocates too much stack space. Cost is "
"not fully computed");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
<< NV("Callee", &F)
<< " is recursive and allocates too much stack space. Cost is "
"not fully computed";
});
return false;
}

View File

@ -777,13 +777,15 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
if (Known.Zero.intersects(Known.One)) {
Known.resetAll();
if (Q.ORE) {
auto *CxtI = const_cast<Instruction *>(Q.CxtI);
OptimizationRemarkAnalysis ORA("value-tracking", "BadAssumption", CxtI);
Q.ORE->emit(ORA << "Detected conflicting code assumptions. Program may "
"have undefined behavior, or compiler may have "
"internal error.");
}
if (Q.ORE)
Q.ORE->emit([&]() {
auto *CxtI = const_cast<Instruction *>(Q.CxtI);
return OptimizationRemarkAnalysis("value-tracking", "BadAssumption",
CxtI)
<< "Detected conflicting code assumptions. Program may "
"have undefined behavior, or compiler may have "
"internal error.";
});
}
}

View File

@ -939,29 +939,32 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
// Emit a remark explaining why we didn't outline this candidate.
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator> C =
RepeatedSequenceLocs[0];
MachineOptimizationRemarkEmitter MORE(*(C.first->getMF()), nullptr);
MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
C.first->getDebugLoc(),
C.first->getParent());
R << "Did not outline " << NV("Length", StringLen) << " instructions"
<< " from " << NV("NumOccurrences", RepeatedSequenceLocs.size())
<< " locations."
<< " Instructions from outlining all occurrences ("
<< NV("OutliningCost", OF.getOutliningCost()) << ")"
<< " >= Unoutlined instruction count ("
<< NV("NotOutliningCost", StringLen * OF.OccurrenceCount) << ")"
<< " (Also found at: ";
MachineOptimizationRemarkEmitter MORE(
*(C.first->getParent()->getParent()), nullptr);
MORE.emit([&]() {
MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
C.first->getDebugLoc(),
C.first->getParent());
R << "Did not outline " << NV("Length", StringLen) << " instructions"
<< " from " << NV("NumOccurrences", RepeatedSequenceLocs.size())
<< " locations."
<< " Instructions from outlining all occurrences ("
<< NV("OutliningCost", OF.getOutliningCost()) << ")"
<< " >= Unoutlined instruction count ("
<< NV("NotOutliningCost", StringLen * OF.OccurrenceCount) << ")"
<< " (Also found at: ";
// Tell the user the other places the candidate was found.
for (unsigned i = 1, e = RepeatedSequenceLocs.size(); i < e; i++) {
R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
RepeatedSequenceLocs[i].first->getDebugLoc());
if (i != e - 1)
R << ", ";
}
// Tell the user the other places the candidate was found.
for (unsigned i = 1, e = RepeatedSequenceLocs.size(); i < e; i++) {
R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
RepeatedSequenceLocs[i].first->getDebugLoc());
if (i != e - 1)
R << ", ";
}
R << ")";
MORE.emit(R);
R << ")";
return R;
});
// Move to the next candidate.
continue;

View File

@ -960,11 +960,12 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
MFI.setStackSize(StackSize);
NumBytesStackSpace += StackSize;
MachineOptimizationRemarkAnalysis R(
DEBUG_TYPE, "StackSize", Fn.getFunction()->getSubprogram(), &Fn.front());
R << ore::NV("NumStackBytes", StackSize)
<< " stack bytes in function";
ORE->emit(R);
ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "StackSize",
Fn.getFunction()->getSubprogram(),
&Fn.front())
<< ore::NV("NumStackBytes", StackSize) << " stack bytes in function";
});
}
/// insertPrologEpilogCode - Scan the function for modified callee saved

View File

@ -2717,17 +2717,20 @@ void RAGreedy::reportNumberOfSplillsReloads(MachineLoop *L, unsigned &Reloads,
if (Reloads || FoldedReloads || Spills || FoldedSpills) {
using namespace ore;
MachineOptimizationRemarkMissed R(DEBUG_TYPE, "LoopSpillReload",
L->getStartLoc(), L->getHeader());
if (Spills)
R << NV("NumSpills", Spills) << " spills ";
if (FoldedSpills)
R << NV("NumFoldedSpills", FoldedSpills) << " folded spills ";
if (Reloads)
R << NV("NumReloads", Reloads) << " reloads ";
if (FoldedReloads)
R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads ";
ORE->emit(R << "generated in loop");
ORE->emit([&]() {
MachineOptimizationRemarkMissed R(DEBUG_TYPE, "LoopSpillReload",
L->getStartLoc(), L->getHeader());
if (Spills)
R << NV("NumSpills", Spills) << " spills ";
if (FoldedSpills)
R << NV("NumFoldedSpills", FoldedSpills) << " folded spills ";
if (Reloads)
R << NV("NumReloads", Reloads) << " reloads ";
if (FoldedReloads)
R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads ";
R << "generated in loop";
return R;
});
}
}

View File

@ -247,10 +247,12 @@ bool StackProtector::RequiresStackProtector() {
OptimizationRemarkEmitter ORE(F);
if (F->hasFnAttribute(Attribute::StackProtectReq)) {
ORE.emit(OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to a function attribute or command-line switch");
<< " due to a function attribute or command-line switch";
});
NeedsProtector = true;
Strong = true; // Use the same heuristic as strong to determine SSPLayout
} else if (F->hasFnAttribute(Attribute::StackProtectStrong))
@ -264,29 +266,31 @@ bool StackProtector::RequiresStackProtector() {
for (const Instruction &I : BB) {
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
if (AI->isArrayAllocation()) {
OptimizationRemark Remark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
&I);
Remark
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to a call to alloca or use of a variable length array";
auto RemarkBuilder = [&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
&I)
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to a call to alloca or use of a variable length "
"array";
};
if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
// A call to alloca with size >= SSPBufferSize requires
// stack protectors.
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
ORE.emit(Remark);
ORE.emit(RemarkBuilder);
NeedsProtector = true;
} else if (Strong) {
// Require protectors for all alloca calls in strong mode.
Layout.insert(std::make_pair(AI, SSPLK_SmallArray));
ORE.emit(Remark);
ORE.emit(RemarkBuilder);
NeedsProtector = true;
}
} else {
// A call to alloca with a variable size requires protectors.
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
ORE.emit(Remark);
ORE.emit(RemarkBuilder);
NeedsProtector = true;
}
continue;
@ -296,11 +300,13 @@ bool StackProtector::RequiresStackProtector() {
if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
Layout.insert(std::make_pair(AI, IsLarge ? SSPLK_LargeArray
: SSPLK_SmallArray));
ORE.emit(OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to a stack allocated buffer or struct containing a "
"buffer");
"buffer";
});
NeedsProtector = true;
continue;
}
@ -308,11 +314,13 @@ bool StackProtector::RequiresStackProtector() {
if (Strong && HasAddressTaken(AI)) {
++NumAddrTaken;
Layout.insert(std::make_pair(AI, SSPLK_AddrOf));
ORE.emit(
OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken", &I)
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to the address of a local variable being taken");
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
&I)
<< "Stack protection applied to function "
<< ore::NV("Function", F)
<< " due to the address of a local variable being taken";
});
NeedsProtector = true;
}
}

View File

@ -384,11 +384,13 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction()
<< " Cost = " << IC.getCost()
<< ", outer Cost = " << TotalSecondaryCost << '\n');
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "IncreaseCostInOtherContexts",
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "IncreaseCostInOtherContexts",
Call)
<< "Not inlining. Cost of inlining " << NV("Callee", Callee)
<< " increases the cost of inlining " << NV("Caller", Caller)
<< " in other contexts");
<< " in other contexts";
});
// IC does not bool() to false, so get an InlineCost that will.
// This will not be inspected to make an error message.
@ -476,11 +478,13 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
if (Function *Callee = CS.getCalledFunction())
if (Callee->isDeclaration()) {
using namespace ore;
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller())
<< " because its definition is unavailable"
<< setIsVerbose());
<< setIsVerbose();
});
continue;
}
@ -572,27 +576,31 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas,
InlineHistoryID, InsertLifetime, AARGetter,
ImportedFunctionsStats)) {
ORE.emit(
OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", Caller));
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
Block)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", Caller);
});
continue;
}
++NumInlined;
if (OIC->isAlways())
ORE.emit(OptimizationRemark(DEBUG_TYPE, "AlwaysInline", DLoc, Block)
<< NV("Callee", Callee) << " inlined into "
<< NV("Caller", Caller) << " with cost=always");
else
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Inlined", DLoc, Block)
<< NV("Callee", Callee) << " inlined into "
<< NV("Caller", Caller)
<< " with cost=" << NV("Cost", OIC->getCost())
<< " (threshold=" << NV("Threshold", OIC->getThreshold())
<< ")";
});
ORE.emit([&]() {
bool AlwaysInline = OIC->isAlways();
StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block);
R << NV("Callee", Callee) << " inlined into ";
R << NV("Caller", Caller);
if (AlwaysInline)
R << " with cost=always";
else {
R << " with cost=" << NV("Cost", OIC->getCost());
R << " (threshold=" << NV("Threshold", OIC->getThreshold());
R << ")";
}
return R;
});
// If inlining this function gave us any new call sites, throw them
// onto our worklist to process. They are useful inline candidates.
@ -915,25 +923,31 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
using namespace ore;
if (!InlineFunction(CS, IFI)) {
ORE.emit(
OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
<< NV("Callee", &Callee) << " will not be inlined into "
<< NV("Caller", &F));
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
<< NV("Callee", &Callee) << " will not be inlined into "
<< NV("Caller", &F);
});
continue;
}
DidInline = true;
InlinedCallees.insert(&Callee);
if (OIC->isAlways())
ORE.emit(OptimizationRemark(DEBUG_TYPE, "AlwaysInline", DLoc, Block)
<< NV("Callee", &Callee) << " inlined into "
<< NV("Caller", &F) << " with cost=always");
else
ORE.emit(
OptimizationRemark(DEBUG_TYPE, "Inlined", DLoc, Block)
<< NV("Callee", &Callee) << " inlined into " << NV("Caller", &F)
<< " with cost=" << NV("Cost", OIC->getCost())
<< " (threshold=" << NV("Threshold", OIC->getThreshold()) << ")");
ORE.emit([&]() {
bool AlwaysInline = OIC->isAlways();
StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block);
R << NV("Callee", &Callee) << " inlined into ";
R << NV("Caller", &F);
if (AlwaysInline)
R << " with cost=always";
else {
R << " with cost=" << NV("Cost", OIC->getCost());
R << " (threshold=" << NV("Threshold", OIC->getThreshold());
R << ")";
}
return R;
});
// Add any new callsites to defined functions to the worklist.
if (!IFI.InlinedCallSites.empty()) {

View File

@ -499,26 +499,32 @@ bool PartialInlinerImpl::shouldPartialInline(
*GetAssumptionCache, GetBFI, PSI, &ORE);
if (IC.isAlways()) {
ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AlwaysInline", Call)
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "AlwaysInline", Call)
<< NV("Callee", Cloner.OrigFunc)
<< " should always be fully inlined, not partially");
<< " should always be fully inlined, not partially";
});
return false;
}
if (IC.isNever()) {
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
<< NV("Callee", Cloner.OrigFunc) << " not partially inlined into "
<< NV("Caller", Caller)
<< " because it should never be inlined (cost=never)");
<< " because it should never be inlined (cost=never)";
});
return false;
}
if (!IC) {
ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "TooCostly", Call)
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "TooCostly", Call)
<< NV("Callee", Cloner.OrigFunc) << " not partially inlined into "
<< NV("Caller", Caller) << " because too costly to inline (cost="
<< NV("Cost", IC.getCost()) << ", threshold="
<< NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")");
<< NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")";
});
return false;
}
const DataLayout &DL = Caller->getParent()->getDataLayout();
@ -529,23 +535,28 @@ bool PartialInlinerImpl::shouldPartialInline(
// Weighted saving is smaller than weighted cost, return false
if (NormWeightedSavings < WeightedOutliningRcost) {
ORE.emit(
OptimizationRemarkAnalysis(DEBUG_TYPE, "OutliningCallcostTooHigh", Call)
<< NV("Callee", Cloner.OrigFunc) << " not partially inlined into "
<< NV("Caller", Caller) << " runtime overhead (overhead="
<< NV("Overhead", (unsigned)WeightedOutliningRcost.getFrequency())
<< ", savings="
<< NV("Savings", (unsigned)NormWeightedSavings.getFrequency()) << ")"
<< " of making the outlined call is too high");
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "OutliningCallcostTooHigh",
Call)
<< NV("Callee", Cloner.OrigFunc) << " not partially inlined into "
<< NV("Caller", Caller) << " runtime overhead (overhead="
<< NV("Overhead", (unsigned)WeightedOutliningRcost.getFrequency())
<< ", savings="
<< NV("Savings", (unsigned)NormWeightedSavings.getFrequency())
<< ")"
<< " of making the outlined call is too high";
});
return false;
}
ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "CanBePartiallyInlined", Call)
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "CanBePartiallyInlined", Call)
<< NV("Callee", Cloner.OrigFunc) << " can be partially inlined into "
<< NV("Caller", Caller) << " with cost=" << NV("Cost", IC.getCost())
<< " (threshold="
<< NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")");
<< NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")";
});
return true;
}
@ -883,13 +894,15 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
DebugLoc DLoc;
BasicBlock *Block;
std::tie(DLoc, Block) = getOneDebugLoc(Cloner.ClonedFunc);
ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "OutlineRegionTooSmall",
ORE.emit([&]() {
return OptimizationRemarkAnalysis(DEBUG_TYPE, "OutlineRegionTooSmall",
DLoc, Block)
<< ore::NV("Function", Cloner.OrigFunc)
<< " not partially inlined into callers (Original Size = "
<< ore::NV("OutlinedRegionOriginalSize", Cloner.OutlinedRegionCost)
<< ", Size of call sequence to outlined function = "
<< ore::NV("NewSize", SizeCost) << ")");
<< ore::NV("NewSize", SizeCost) << ")";
});
return false;
}
@ -918,10 +931,12 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
if (!shouldPartialInline(CS, Cloner, WeightedRcost, ORE))
continue;
ORE.emit(
OptimizationRemark(DEBUG_TYPE, "PartiallyInlined", CS.getInstruction())
<< ore::NV("Callee", Cloner.OrigFunc) << " partially inlined into "
<< ore::NV("Caller", CS.getCaller()));
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "PartiallyInlined",
CS.getInstruction())
<< ore::NV("Callee", Cloner.OrigFunc) << " partially inlined into "
<< ore::NV("Caller", CS.getCaller());
});
InlineFunctionInfo IFI(nullptr, GetAssumptionCache, PSI);
InlineFunction(CS, IFI);

View File

@ -528,17 +528,18 @@ ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
bool FirstMark =
CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.get());
if (FirstMark) {
if (Discriminator)
ORE->emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AppliedSamples", &Inst)
<< "Applied " << ore::NV("NumSamples", *R)
<< " samples from profile (offset: "
<< ore::NV("LineOffset", LineOffset) << "."
<< ore::NV("Discriminator", Discriminator) << ")");
else
ORE->emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AppliedSamples", &Inst)
<< "Applied " << ore::NV("NumSamples", *R)
<< " samples from profile (offset: "
<< ore::NV("LineOffset", LineOffset) << ")");
ORE->emit([&]() {
OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
Remark << "Applied " << ore::NV("NumSamples", *R);
Remark << " samples from profile (offset: ";
Remark << ore::NV("LineOffset", LineOffset);
if (Discriminator) {
Remark << ".";
Remark << ore::NV("Discriminator", Discriminator);
}
Remark << ")";
return Remark;
});
}
DEBUG(dbgs() << " " << DLoc.getLine() << "."
<< DIL->getBaseDiscriminator() << ":" << Inst
@ -1324,9 +1325,11 @@ void SampleProfileLoader::propagateWeights(Function &F) {
DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n");
TI->setMetadata(llvm::LLVMContext::MD_prof,
MDB.createBranchWeights(Weights));
ORE->emit(OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
<< "most popular destination for conditional branches at "
<< ore::NV("CondBranchesLoc", BranchLoc));
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
<< "most popular destination for conditional branches at "
<< ore::NV("CondBranchesLoc", BranchLoc);
});
} else {
DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
}

View File

@ -277,38 +277,48 @@ ICallPromotionFunc::getPromotionCandidatesForCallSite(
if (ICPInvokeOnly && dyn_cast<CallInst>(Inst)) {
DEBUG(dbgs() << " Not promote: User options.\n");
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst)
<< " Not promote: User options");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst)
<< " Not promote: User options";
});
break;
}
if (ICPCallOnly && dyn_cast<InvokeInst>(Inst)) {
DEBUG(dbgs() << " Not promote: User option.\n");
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst)
<< " Not promote: User options");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst)
<< " Not promote: User options";
});
break;
}
if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
DEBUG(dbgs() << " Not promote: Cutoff reached.\n");
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "CutOffReached", Inst)
<< " Not promote: Cutoff reached");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "CutOffReached", Inst)
<< " Not promote: Cutoff reached";
});
break;
}
Function *TargetFunction = Symtab->getFunction(Target);
if (TargetFunction == nullptr) {
DEBUG(dbgs() << " Not promote: Cannot find the target\n");
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", Inst)
<< "Cannot promote indirect call: target not found");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", Inst)
<< "Cannot promote indirect call: target not found";
});
break;
}
const char *Reason = nullptr;
if (!isLegalToPromote(Inst, TargetFunction, &Reason)) {
using namespace ore;
ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", Inst)
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", Inst)
<< "Cannot promote indirect call to "
<< NV("TargetFunction", TargetFunction) << " with count of "
<< NV("Count", Count) << ": " << Reason);
<< NV("Count", Count) << ": " << Reason;
});
break;
}
@ -604,10 +614,12 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
using namespace ore;
if (ORE)
ORE->emit(OptimizationRemark(DEBUG_TYPE, "Promoted", Inst)
<< "Promote indirect call to " << NV("DirectCallee", DirectCallee)
<< " with count " << NV("Count", Count) << " out of "
<< NV("TotalCount", TotalCount));
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Promoted", Inst)
<< "Promote indirect call to " << NV("DirectCallee", DirectCallee)
<< " with count " << NV("Count", Count) << " out of "
<< NV("TotalCount", TotalCount);
});
return NewInst;
}

View File

@ -1510,8 +1510,10 @@ void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
OS.flush();
Function *F = TI->getParent()->getParent();
OptimizationRemarkEmitter ORE(F);
ORE.emit(OptimizationRemark(DEBUG_TYPE, "pgo-instrumentation", TI)
<< BrCondStr << " is true with probability : " << BranchProbStr);
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "pgo-instrumentation", TI)
<< BrCondStr << " is true with probability : " << BranchProbStr;
});
}
}

View File

@ -382,14 +382,14 @@ bool MemOPSizeOpt::perform(MemIntrinsic *MI) {
DEBUG(dbgs() << *DefaultBB << "\n");
DEBUG(dbgs() << *MergeBB << "\n");
{
ORE.emit([&]() {
using namespace ore;
ORE.emit(OptimizationRemark(DEBUG_TYPE, "memopt-opt", MI)
return OptimizationRemark(DEBUG_TYPE, "memopt-opt", MI)
<< "optimized " << NV("Intrinsic", StringRef(getMIName(MI)))
<< " with count " << NV("Count", SumForOpt) << " out of "
<< NV("Total", TotalCount) << " for " << NV("Versions", Version)
<< " versions");
}
<< " versions";
});
return true;
}

View File

@ -1276,8 +1276,10 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
if (V->getType()->isPtrOrPtrVectorTy())
MD->invalidateCachedPointerInfo(V);
markInstructionForDeletion(LI);
ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadPRE", LI)
<< "load eliminated by PRE");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "LoadPRE", LI)
<< "load eliminated by PRE";
});
++NumPRELoad;
return true;
}
@ -1286,10 +1288,12 @@ static void reportLoadElim(LoadInst *LI, Value *AvailableValue,
OptimizationRemarkEmitter *ORE) {
using namespace ore;
ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
<< "load of type " << NV("Type", LI->getType()) << " eliminated"
<< setExtraArgs() << " in favor of "
<< NV("InfavorOfValue", AvailableValue));
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
<< "load of type " << NV("Type", LI->getType()) << " eliminated"
<< setExtraArgs() << " in favor of "
<< NV("InfavorOfValue", AvailableValue);
});
}
/// Attempt to eliminate a load whose dependencies are

View File

@ -612,10 +612,12 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
// Check loop-invariant address because this may also be a sinkable load
// whose address is not necessarily loop-invariant.
if (ORE && Invalidated && CurLoop->isLoopInvariant(LI->getPointerOperand()))
ORE->emit(OptimizationRemarkMissed(
DEBUG_TYPE, "LoadWithLoopInvariantAddressInvalidated", LI)
<< "failed to move load with loop-invariant address "
"because the loop may invalidate its value");
ORE->emit([&]() {
return OptimizationRemarkMissed(
DEBUG_TYPE, "LoadWithLoopInvariantAddressInvalidated", LI)
<< "failed to move load with loop-invariant address "
"because the loop may invalidate its value";
});
return !Invalidated;
} else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@ -814,8 +816,10 @@ static bool sink(Instruction &I, const LoopInfo *LI, const DominatorTree *DT,
const LoopSafetyInfo *SafetyInfo,
OptimizationRemarkEmitter *ORE) {
DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n");
ORE->emit(OptimizationRemark(DEBUG_TYPE, "InstSunk", &I)
<< "sinking " << ore::NV("Inst", &I));
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "InstSunk", &I)
<< "sinking " << ore::NV("Inst", &I);
});
bool Changed = false;
if (isa<LoadInst>(I))
++NumMovedLoads;
@ -887,8 +891,10 @@ static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
auto *Preheader = CurLoop->getLoopPreheader();
DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": " << I
<< "\n");
ORE->emit(OptimizationRemark(DEBUG_TYPE, "Hoisted", &I)
<< "hoisting " << ore::NV("Inst", &I));
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Hoisted", &I) << "hoisting "
<< ore::NV("Inst", &I);
});
// Metadata can be dependent on conditions we are hoisting above.
// Conservatively strip all metadata on the instruction unless we were
@ -938,10 +944,12 @@ static bool isSafeToExecuteUnconditionally(Instruction &Inst,
if (!GuaranteedToExecute) {
auto *LI = dyn_cast<LoadInst>(&Inst);
if (LI && CurLoop->isLoopInvariant(LI->getPointerOperand()))
ORE->emit(OptimizationRemarkMissed(
DEBUG_TYPE, "LoadWithLoopInvariantAddressCondExecuted", LI)
<< "failed to hoist load with loop-invariant address "
"because load is conditionally executed");
ORE->emit([&]() {
return OptimizationRemarkMissed(
DEBUG_TYPE, "LoadWithLoopInvariantAddressCondExecuted", LI)
<< "failed to hoist load with loop-invariant address "
"because load is conditionally executed";
});
}
return GuaranteedToExecute;
@ -1257,9 +1265,11 @@ bool llvm::promoteLoopAccessesToScalars(
// Otherwise, this is safe to promote, lets do it!
DEBUG(dbgs() << "LICM: Promoting value stored to in loop: " << *SomePtr
<< '\n');
ORE->emit(
OptimizationRemark(DEBUG_TYPE, "PromoteLoopAccessesToScalar", LoopUses[0])
<< "Moving accesses to memory location out of the loop");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "PromoteLoopAccessesToScalar",
LoopUses[0])
<< "Moving accesses to memory location out of the loop";
});
++NumPromoted;
// Grab a debug location for the inserted loads/stores; given that the

View File

@ -327,8 +327,10 @@ bool LoopDataPrefetch::runOnLoop(Loop *L) {
++NumPrefetches;
DEBUG(dbgs() << " Access: " << *PtrValue << ", SCEV: " << *LSCEV
<< "\n");
ORE->emit(OptimizationRemark(DEBUG_TYPE, "Prefetched", MemI)
<< "prefetched memory access");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Prefetched", MemI)
<< "prefetched memory access";
});
MadeChange = true;
}

View File

@ -755,9 +755,11 @@ public:
++NumLoopsDistributed;
// Report the success.
ORE->emit(OptimizationRemark(LDIST_NAME, "Distribute", L->getStartLoc(),
L->getHeader())
<< "distributed loop");
ORE->emit([&]() {
return OptimizationRemark(LDIST_NAME, "Distribute", L->getStartLoc(),
L->getHeader())
<< "distributed loop";
});
return true;
}
@ -769,11 +771,13 @@ public:
DEBUG(dbgs() << "Skipping; " << Message << "\n");
// With Rpass-missed report that distribution failed.
ORE->emit(
OptimizationRemarkMissed(LDIST_NAME, "NotDistributed", L->getStartLoc(),
L->getHeader())
<< "loop not distributed: use -Rpass-analysis=loop-distribute for more "
"info");
ORE->emit([&]() {
return OptimizationRemarkMissed(LDIST_NAME, "NotDistributed",
L->getStartLoc(), L->getHeader())
<< "loop not distributed: use -Rpass-analysis=loop-distribute for "
"more "
"info";
});
// With Rpass-analysis report why. This is on by default if distribution
// was requested explicitly.

View File

@ -596,10 +596,12 @@ struct LoopInterchange : public FunctionPass {
return false;
}
ORE->emit(OptimizationRemark(DEBUG_TYPE, "Interchanged",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Loop interchanged with enclosing loop.");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Interchanged",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Loop interchanged with enclosing loop.";
});
LoopInterchangeTransform LIT(OuterLoop, InnerLoop, SE, LI, DT,
LoopNestExit, LIL.hasInnerLoopReduction());
@ -772,12 +774,13 @@ bool LoopInterchangeLegality::currentLimitations() {
if (!findInductionAndReductions(InnerLoop, Inductions, Reductions)) {
DEBUG(dbgs() << "Only inner loops with induction or reduction PHI nodes "
<< "are supported currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"UnsupportedPHIInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with induction or reduction PHI nodes can be"
" interchange currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnsupportedPHIInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with induction or reduction PHI nodes can be"
" interchange currently.";
});
return true;
}
@ -785,12 +788,13 @@ bool LoopInterchangeLegality::currentLimitations() {
if (Inductions.size() != 1) {
DEBUG(dbgs() << "We currently only support loops with 1 induction variable."
<< "Failed to interchange due to current limitation\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"MultiInductionInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with 1 induction variable can be "
"interchanged currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "MultiInductionInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with 1 induction variable can be "
"interchanged currently.";
});
return true;
}
if (Reductions.size() > 0)
@ -801,12 +805,13 @@ bool LoopInterchangeLegality::currentLimitations() {
if (!findInductionAndReductions(OuterLoop, Inductions, Reductions)) {
DEBUG(dbgs() << "Only outer loops with induction or reduction PHI nodes "
<< "are supported currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"UnsupportedPHIOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with induction or reduction PHI nodes can be"
" interchanged currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnsupportedPHIOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with induction or reduction PHI nodes can be"
" interchanged currently.";
});
return true;
}
@ -815,35 +820,38 @@ bool LoopInterchangeLegality::currentLimitations() {
if (!Reductions.empty()) {
DEBUG(dbgs() << "Outer loops with reductions are not supported "
<< "currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"ReductionsOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Outer loops with reductions cannot be interchangeed "
"currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "ReductionsOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Outer loops with reductions cannot be interchangeed "
"currently.";
});
return true;
}
// TODO: Currently we handle only loops with 1 induction variable.
if (Inductions.size() != 1) {
DEBUG(dbgs() << "Loops with more than 1 induction variables are not "
<< "supported currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"MultiIndutionOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with 1 induction variable can be "
"interchanged currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "MultiIndutionOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with 1 induction variable can be "
"interchanged currently.";
});
return true;
}
// TODO: Triangular loops are not handled for now.
if (!isLoopStructureUnderstood(InnerInductionVar)) {
DEBUG(dbgs() << "Loop structure not understood by pass\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"UnsupportedStructureInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Inner loop structure not understood currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "UnsupportedStructureInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Inner loop structure not understood currently.";
});
return true;
}
@ -852,24 +860,26 @@ bool LoopInterchangeLegality::currentLimitations() {
getLoopLatchExitBlock(OuterLoopLatch, OuterLoopHeader);
if (!LoopExitBlock || !containsSafePHI(LoopExitBlock, true)) {
DEBUG(dbgs() << "Can only handle LCSSA PHIs in outer loops currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"NoLCSSAPHIOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with LCSSA PHIs can be interchange "
"currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoLCSSAPHIOuter",
OuterLoop->getStartLoc(),
OuterLoop->getHeader())
<< "Only outer loops with LCSSA PHIs can be interchange "
"currently.";
});
return true;
}
LoopExitBlock = getLoopLatchExitBlock(InnerLoopLatch, InnerLoopHeader);
if (!LoopExitBlock || !containsSafePHI(LoopExitBlock, false)) {
DEBUG(dbgs() << "Can only handle LCSSA PHIs in inner loops currently.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"NoLCSSAPHIOuterInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with LCSSA PHIs can be interchange "
"currently.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoLCSSAPHIOuterInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Only inner loops with LCSSA PHIs can be interchange "
"currently.";
});
return true;
}
@ -894,11 +904,12 @@ bool LoopInterchangeLegality::currentLimitations() {
if (!InnerIndexVarInc) {
DEBUG(dbgs() << "Did not find an instruction to increment the induction "
<< "variable.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"NoIncrementInInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "The inner loop does not increment the induction variable.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoIncrementInInner",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "The inner loop does not increment the induction variable.";
});
return true;
}
@ -917,12 +928,13 @@ bool LoopInterchangeLegality::currentLimitations() {
if (!I.isIdenticalTo(InnerIndexVarInc)) {
DEBUG(dbgs() << "Found unsupported instructions between induction "
<< "variable increment and branch.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"UnsupportedInsBetweenInduction",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Found unsupported instruction between induction variable "
"increment and branch.");
ORE->emit([&]() {
return OptimizationRemarkMissed(
DEBUG_TYPE, "UnsupportedInsBetweenInduction",
InnerLoop->getStartLoc(), InnerLoop->getHeader())
<< "Found unsupported instruction between induction variable "
"increment and branch.";
});
return true;
}
@ -933,11 +945,12 @@ bool LoopInterchangeLegality::currentLimitations() {
// current limitation.
if (!FoundInduction) {
DEBUG(dbgs() << "Did not find the induction variable.\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"NoIndutionVariable",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Did not find the induction variable.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoIndutionVariable",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Did not find the induction variable.";
});
return true;
}
return false;
@ -951,11 +964,12 @@ bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,
DEBUG(dbgs() << "Failed interchange InnerLoopId = " << InnerLoopId
<< " and OuterLoopId = " << OuterLoopId
<< " due to dependence\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"Dependence",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Cannot interchange loops due to dependences.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "Dependence",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Cannot interchange loops due to dependences.";
});
return false;
}
@ -1003,12 +1017,13 @@ bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,
// Check if the loops are tightly nested.
if (!tightlyNested(OuterLoop, InnerLoop)) {
DEBUG(dbgs() << "Loops not tightly nested\n");
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"NotTightlyNested",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Cannot interchange loops because they are not tightly "
"nested.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotTightlyNested",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Cannot interchange loops because they are not tightly "
"nested.";
});
return false;
}
@ -1105,14 +1120,15 @@ bool LoopInterchangeProfitability::isProfitable(unsigned InnerLoopId,
if (isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix))
return true;
ORE->emit(OptimizationRemarkMissed(DEBUG_TYPE,
"InterchangeNotProfitable",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Interchanging loops is too costly (cost="
<< ore::NV("Cost", Cost) << ", threshold="
<< ore::NV("Threshold", LoopInterchangeCostThreshold) <<
") and it does not improve parallelism.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "InterchangeNotProfitable",
InnerLoop->getStartLoc(),
InnerLoop->getHeader())
<< "Interchanging loops is too costly (cost="
<< ore::NV("Cost", Cost) << ", threshold="
<< ore::NV("Threshold", LoopInterchangeCostThreshold)
<< ") and it does not improve parallelism.";
});
return false;
}

View File

@ -842,11 +842,14 @@ static bool computeUnrollCount(
}
if (UP.Count < 2) {
if (PragmaEnableUnroll)
ORE->emit(
OptimizationRemarkMissed(DEBUG_TYPE, "UnrollAsDirectedTooLarge",
L->getStartLoc(), L->getHeader())
<< "Unable to unroll loop as directed by unroll(enable) pragma "
"because unrolled size is too large.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
"UnrollAsDirectedTooLarge",
L->getStartLoc(), L->getHeader())
<< "Unable to unroll loop as directed by unroll(enable) "
"pragma "
"because unrolled size is too large.";
});
UP.Count = 0;
}
} else {
@ -856,22 +859,27 @@ static bool computeUnrollCount(
UP.Count = UP.MaxCount;
if ((PragmaFullUnroll || PragmaEnableUnroll) && TripCount &&
UP.Count != TripCount)
ORE->emit(
OptimizationRemarkMissed(DEBUG_TYPE, "FullUnrollAsDirectedTooLarge",
L->getStartLoc(), L->getHeader())
<< "Unable to fully unroll loop as directed by unroll pragma because "
"unrolled size is too large.");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
"FullUnrollAsDirectedTooLarge",
L->getStartLoc(), L->getHeader())
<< "Unable to fully unroll loop as directed by unroll pragma "
"because "
"unrolled size is too large.";
});
return ExplicitUnroll;
}
assert(TripCount == 0 &&
"All cases when TripCount is constant should be covered here.");
if (PragmaFullUnroll)
ORE->emit(
OptimizationRemarkMissed(DEBUG_TYPE,
"CantFullUnrollAsDirectedRuntimeTripCount",
L->getStartLoc(), L->getHeader())
<< "Unable to fully unroll loop as directed by unroll(full) pragma "
"because loop has a runtime trip count.");
ORE->emit([&]() {
return OptimizationRemarkMissed(
DEBUG_TYPE, "CantFullUnrollAsDirectedRuntimeTripCount",
L->getStartLoc(), L->getHeader())
<< "Unable to fully unroll loop as directed by unroll(full) "
"pragma "
"because loop has a runtime trip count.";
});
// 6th priority is runtime unrolling.
// Don't unroll a runtime trip count loop when it is disabled.
@ -922,17 +930,19 @@ static bool computeUnrollCount(
<< OrigCount << " to " << UP.Count << ".\n");
using namespace ore;
if (PragmaCount > 0 && !UP.AllowRemainder)
ORE->emit(
OptimizationRemarkMissed(DEBUG_TYPE,
"DifferentUnrollCountFromDirected",
L->getStartLoc(), L->getHeader())
<< "Unable to unroll loop the number of times directed by "
"unroll_count pragma because remainder loop is restricted "
"(that could architecture specific or because the loop "
"contains a convergent instruction) and so must have an unroll "
"count that divides the loop trip multiple of "
<< NV("TripMultiple", TripMultiple) << ". Unrolling instead "
<< NV("UnrollCount", UP.Count) << " time(s).");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
"DifferentUnrollCountFromDirected",
L->getStartLoc(), L->getHeader())
<< "Unable to unroll loop the number of times directed by "
"unroll_count pragma because remainder loop is restricted "
"(that could architecture specific or because the loop "
"contains a convergent instruction) and so must have an "
"unroll "
"count that divides the loop trip multiple of "
<< NV("TripMultiple", TripMultiple) << ". Unrolling instead "
<< NV("UnrollCount", UP.Count) << " time(s).";
});
}
if (UP.Count > UP.MaxCount)

View File

@ -255,8 +255,10 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls,
}
if (SafeToTail) {
using namespace ore;
ORE->emit(OptimizationRemark(DEBUG_TYPE, "tailcall-readnone", CI)
<< "marked as tail call candidate (readnone)");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "tailcall-readnone", CI)
<< "marked as tail call candidate (readnone)";
});
CI->setTailCall();
Modified = true;
continue;
@ -301,8 +303,10 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls,
if (Visited[CI->getParent()] != ESCAPED) {
// If the escape point was part way through the block, calls after the
// escape point wouldn't have been put into DeferredTails.
ORE->emit(OptimizationRemark(DEBUG_TYPE, "tailcall", CI)
<< "marked as tail call candidate");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "tailcall", CI)
<< "marked as tail call candidate";
});
CI->setTailCall();
Modified = true;
} else {
@ -554,8 +558,10 @@ static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret,
Function *F = BB->getParent();
using namespace ore;
ORE->emit(OptimizationRemark(DEBUG_TYPE, "tailcall-recursion", CI)
<< "transforming tail recursion into loop");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "tailcall-recursion", CI)
<< "transforming tail recursion into loop";
});
// OK! We can transform this tail call. If this is the first one found,
// create the new entry block, allowing us to branch back to the old entry.

View File

@ -460,18 +460,22 @@ LoopUnrollResult llvm::UnrollLoop(
// Report the unrolling decision.
if (CompletelyUnroll) {
DEBUG(dbgs() << "COMPLETELY UNROLLING loop %" << Header->getName()
<< " with trip count " << TripCount << "!\n");
ORE->emit(OptimizationRemark(DEBUG_TYPE, "FullyUnrolled", L->getStartLoc(),
L->getHeader())
<< "completely unrolled loop with "
<< NV("UnrollCount", TripCount) << " iterations");
<< " with trip count " << TripCount << "!\n");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "FullyUnrolled", L->getStartLoc(),
L->getHeader())
<< "completely unrolled loop with " << NV("UnrollCount", TripCount)
<< " iterations";
});
} else if (PeelCount) {
DEBUG(dbgs() << "PEELING loop %" << Header->getName()
<< " with iteration count " << PeelCount << "!\n");
ORE->emit(OptimizationRemark(DEBUG_TYPE, "Peeled", L->getStartLoc(),
L->getHeader())
<< " peeled loop by " << NV("PeelCount", PeelCount)
<< " iterations");
ORE->emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "Peeled", L->getStartLoc(),
L->getHeader())
<< " peeled loop by " << NV("PeelCount", PeelCount)
<< " iterations";
});
} else {
auto DiagBuilder = [&]() {
OptimizationRemark Diag(DEBUG_TYPE, "PartialUnrolled", L->getStartLoc(),

View File

@ -485,8 +485,10 @@ Value *LibCallSimplifier::optimizeStringLength(CallInst *CI, IRBuilder<> &B,
uint64_t LenTrue = GetStringLength(SI->getTrueValue(), CharSize);
uint64_t LenFalse = GetStringLength(SI->getFalseValue(), CharSize);
if (LenTrue && LenFalse) {
ORE.emit(OptimizationRemark("instcombine", "simplify-libcalls", CI)
<< "folded strlen(select) to select of constants");
ORE.emit([&]() {
return OptimizationRemark("instcombine", "simplify-libcalls", CI)
<< "folded strlen(select) to select of constants";
});
return B.CreateSelect(SI->getCondition(),
ConstantInt::get(CI->getType(), LenTrue - 1),
ConstantInt::get(CI->getType(), LenFalse - 1));

View File

@ -1248,25 +1248,29 @@ public:
/// Dumps all the hint information.
void emitRemarkWithHints() const {
using namespace ore;
if (Force.Value == LoopVectorizeHints::FK_Disabled)
ORE.emit(OptimizationRemarkMissed(LV_NAME, "MissedExplicitlyDisabled",
ORE.emit([&]() {
if (Force.Value == LoopVectorizeHints::FK_Disabled)
return OptimizationRemarkMissed(LV_NAME, "MissedExplicitlyDisabled",
TheLoop->getStartLoc(),
TheLoop->getHeader())
<< "loop not vectorized: vectorization is explicitly disabled");
else {
OptimizationRemarkMissed R(LV_NAME, "MissedDetails",
TheLoop->getStartLoc(), TheLoop->getHeader());
R << "loop not vectorized";
if (Force.Value == LoopVectorizeHints::FK_Enabled) {
R << " (Force=" << NV("Force", true);
if (Width.Value != 0)
R << ", Vector Width=" << NV("VectorWidth", Width.Value);
if (Interleave.Value != 0)
R << ", Interleave Count=" << NV("InterleaveCount", Interleave.Value);
R << ")";
<< "loop not vectorized: vectorization is explicitly disabled";
else {
OptimizationRemarkMissed R(LV_NAME, "MissedDetails",
TheLoop->getStartLoc(),
TheLoop->getHeader());
R << "loop not vectorized";
if (Force.Value == LoopVectorizeHints::FK_Enabled) {
R << " (Force=" << NV("Force", true);
if (Width.Value != 0)
R << ", Vector Width=" << NV("VectorWidth", Width.Value);
if (Interleave.Value != 0)
R << ", Interleave Count="
<< NV("InterleaveCount", Interleave.Value);
R << ")";
}
return R;
}
ORE.emit(R);
}
});
}
unsigned getWidth() const { return Width.Value; }
@ -2277,12 +2281,14 @@ public:
const char *PassName = Hints.vectorizeAnalysisPassName();
bool Failed = false;
if (UnsafeAlgebraInst && !Hints.allowReordering()) {
ORE.emit(
OptimizationRemarkAnalysisFPCommute(PassName, "CantReorderFPOps",
UnsafeAlgebraInst->getDebugLoc(),
UnsafeAlgebraInst->getParent())
<< "loop not vectorized: cannot prove it is safe to reorder "
"floating-point operations");
ORE.emit([&]() {
return OptimizationRemarkAnalysisFPCommute(
PassName, "CantReorderFPOps",
UnsafeAlgebraInst->getDebugLoc(),
UnsafeAlgebraInst->getParent())
<< "loop not vectorized: cannot prove it is safe to reorder "
"floating-point operations";
});
Failed = true;
}
@ -2293,11 +2299,13 @@ public:
NumRuntimePointerChecks > VectorizerParams::RuntimeMemoryCheckThreshold;
if ((ThresholdReached && !Hints.allowReordering()) ||
PragmaThresholdReached) {
ORE.emit(OptimizationRemarkAnalysisAliasing(PassName, "CantReorderMemOps",
ORE.emit([&]() {
return OptimizationRemarkAnalysisAliasing(PassName, "CantReorderMemOps",
L->getStartLoc(),
L->getHeader())
<< "loop not vectorized: cannot prove it is safe to reorder "
"memory operations");
"memory operations";
});
DEBUG(dbgs() << "LV: Too many memory checks needed.\n");
Failed = true;
}
@ -5742,9 +5750,10 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
InterleaveInfo.setLAI(LAI);
const OptimizationRemarkAnalysis *LAR = LAI->getReport();
if (LAR) {
OptimizationRemarkAnalysis VR(Hints->vectorizeAnalysisPassName(),
"loop not vectorized: ", *LAR);
ORE->emit(VR);
ORE->emit([&]() {
return OptimizationRemarkAnalysis(Hints->vectorizeAnalysisPassName(),
"loop not vectorized: ", *LAR);
});
}
if (!LAI->canVectorizeMemory())
return false;
@ -8573,24 +8582,32 @@ bool LoopVectorizePass::processLoop(Loop *L) {
const char *VAPassName = Hints.vectorizeAnalysisPassName();
if (!VectorizeLoop && !InterleaveLoop) {
// Do not vectorize or interleaving the loop.
ORE->emit(OptimizationRemarkMissed(VAPassName, VecDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< VecDiagMsg.second);
ORE->emit(OptimizationRemarkMissed(LV_NAME, IntDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< IntDiagMsg.second);
ORE->emit([&]() {
return OptimizationRemarkMissed(VAPassName, VecDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< VecDiagMsg.second;
});
ORE->emit([&]() {
return OptimizationRemarkMissed(LV_NAME, IntDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< IntDiagMsg.second;
});
return false;
} else if (!VectorizeLoop && InterleaveLoop) {
DEBUG(dbgs() << "LV: Interleave Count is " << IC << '\n');
ORE->emit(OptimizationRemarkAnalysis(VAPassName, VecDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< VecDiagMsg.second);
ORE->emit([&]() {
return OptimizationRemarkAnalysis(VAPassName, VecDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< VecDiagMsg.second;
});
} else if (VectorizeLoop && !InterleaveLoop) {
DEBUG(dbgs() << "LV: Found a vectorizable loop (" << VF.Width << ") in "
<< DebugLocStr << '\n');
ORE->emit(OptimizationRemarkAnalysis(LV_NAME, IntDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< IntDiagMsg.second);
ORE->emit([&]() {
return OptimizationRemarkAnalysis(LV_NAME, IntDiagMsg.first,
L->getStartLoc(), L->getHeader())
<< IntDiagMsg.second;
});
} else if (VectorizeLoop && InterleaveLoop) {
DEBUG(dbgs() << "LV: Found a vectorizable loop (" << VF.Width << ") in "
<< DebugLocStr << '\n');
@ -8608,10 +8625,12 @@ bool LoopVectorizePass::processLoop(Loop *L) {
&CM);
LVP.executePlan(Unroller, DT);
ORE->emit(OptimizationRemark(LV_NAME, "Interleaved", L->getStartLoc(),
L->getHeader())
<< "interleaved loop (interleaved count: "
<< NV("InterleaveCount", IC) << ")");
ORE->emit([&]() {
return OptimizationRemark(LV_NAME, "Interleaved", L->getStartLoc(),
L->getHeader())
<< "interleaved loop (interleaved count: "
<< NV("InterleaveCount", IC) << ")";
});
} else {
// If we decided that it is *legal* to vectorize the loop, then do it.
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
@ -8626,11 +8645,13 @@ bool LoopVectorizePass::processLoop(Loop *L) {
AddRuntimeUnrollDisableMetaData(L);
// Report the vectorization decision.
ORE->emit(OptimizationRemark(LV_NAME, "Vectorized", L->getStartLoc(),
L->getHeader())
<< "vectorized loop (vectorization width: "
<< NV("VectorizationFactor", VF.Width)
<< ", interleaved count: " << NV("InterleaveCount", IC) << ")");
ORE->emit([&]() {
return OptimizationRemark(LV_NAME, "Vectorized", L->getStartLoc(),
L->getHeader())
<< "vectorized loop (vectorization width: "
<< NV("VectorizationFactor", VF.Width)
<< ", interleaved count: " << NV("InterleaveCount", IC) << ")";
});
}
// Mark the loop as already vectorized to avoid vectorizing again.