Files
llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp
Yaxun (Sam) Liu 822f549e98 [IR] Add source location filtering to pass dumps (#203393)
Large dumps from `-print-after-all` can be hard to use when only a few
source lines matter. Function filtering can still print too much and can
miss code after inlining.

Add `-filter-print-source-locs` to limit IR and machine-function dumps
to matching debug locations. The option accepts file names or paths with
selected lines and ranges. It also follows inlined locations and works
with legacy and new pass managers.
2026-09-03 22:16:29 -04:00

175 lines
6.6 KiB
C++

//===-- MachineFunctionPass.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the definitions of the MachineFunctionPass members.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CycleAnalysis.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LazyBranchProbabilityInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/CodeGen/DroppedVariableStatsMIR.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
using namespace ore;
static cl::opt<bool> DroppedVarStatsMIR(
"dropped-variable-stats-mir", cl::Hidden,
cl::desc("Dump dropped debug variables stats for MIR passes"),
cl::init(false));
Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
const std::string &Banner) const {
return createMachineFunctionPrinterPass(O, Banner);
}
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (F.hasAvailableExternallyLinkage())
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
MachineFunctionProperties &MFProps = MF.getProperties();
#ifndef NDEBUG
if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
errs() << "MachineFunctionProperties required by " << getPassName()
<< " pass are not met by function " << F.getName() << ".\n"
<< "Required properties: ";
RequiredProperties.print(errs());
errs() << "\nCurrent properties: ";
MFProps.print(errs());
errs() << "\n";
reportFatalUsageError("MachineFunctionProperties check failed");
}
#endif
// Collect the MI count of the function before the pass.
unsigned CountBefore, CountAfter;
// Check if the user asked for size remarks.
bool ShouldEmitSizeRemarks =
F.getParent()->shouldEmitInstrCountChangedRemark();
// If we want size remarks, collect the number of MachineInstrs in our
// MachineFunction before the pass runs.
if (ShouldEmitSizeRemarks)
CountBefore = MF.getInstructionCount();
MFProps.reset(ClearedProperties);
bool RV;
if (DroppedVarStatsMIR) {
DroppedVariableStatsMIR DroppedVarStatsMF;
auto PassName = getPassName();
DroppedVarStatsMF.runBeforePass(PassName, &MF);
RV = runOnMachineFunction(MF);
DroppedVarStatsMF.runAfterPass(PassName, &MF);
} else {
RV = runOnMachineFunction(MF);
}
if (ShouldEmitSizeRemarks) {
// We wanted size remarks. Check if there was a change to the number of
// MachineInstrs in the module. Emit a remark if there was a change.
CountAfter = MF.getInstructionCount();
if (CountBefore != CountAfter) {
MachineOptimizationRemarkEmitter MORE(MF, nullptr);
MORE.emit([&]() {
int64_t Delta = static_cast<int64_t>(CountAfter) -
static_cast<int64_t>(CountBefore);
MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
MF.getFunction().getSubprogram(),
&MF.front());
R << NV("Pass", getPassName())
<< ": Function: " << NV("Function", F.getName()) << ": "
<< "MI Instruction count changed from "
<< NV("MIInstrsBefore", CountBefore) << " to "
<< NV("MIInstrsAfter", CountAfter)
<< "; Delta: " << NV("Delta", Delta);
return R;
});
}
}
MFProps.set(SetProperties);
return RV;
}
bool MachineFunctionPass::printIRUnit(raw_ostream &OS, Function &F) {
// available_externally functions are not codegen'd (see runOnFunction).
if (F.hasAvailableExternallyLinkage())
return false;
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
bool SourceLocFilterEmpty = isSourceLocFilterEmpty();
if (!isFunctionInPrintList(MF.getName()))
return false;
if (!SourceLocFilterEmpty && none_of(MF, [](const MachineBasicBlock &MBB) {
return any_of(MBB, [](const MachineInstr &MI) {
return isSourceLocInPrintList(MI.getDebugLoc());
});
}))
return false;
MF.print(OS);
return true;
}
void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfoWrapperPass>();
AU.addPreserved<MachineModuleInfoWrapperPass>();
// MachineFunctionPass preserves all LLVM IR passes, but there's no
// high-level way to express this. Instead, just list a bunch of
// passes explicitly. This does not include setPreservesCFG,
// because CodeGen overloads that to mean preserving the MachineBasicBlock
// CFG in addition to the LLVM IR CFG.
AU.addPreserved<BasicAAWrapperPass>();
AU.addPreserved<DominanceFrontierWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.addPreserved<PostDominatorTreeWrapperPass>();
AU.addPreserved<BranchProbabilityInfoWrapperPass>();
AU.addPreserved<LazyBranchProbabilityInfoPass>();
AU.addPreserved<LazyBlockFrequencyInfoPass>();
AU.addPreserved<AAResultsWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addPreserved<IVUsersWrapperPass>();
AU.addPreserved<LoopInfoWrapperPass>();
AU.addPreserved<CycleInfoWrapperPass>();
AU.addPreserved<MemoryDependenceWrapperPass>();
AU.addPreserved<ScalarEvolutionWrapperPass>();
AU.addPreserved<SCEVAAWrapperPass>();
FunctionPass::getAnalysisUsage(AU);
}