Index: include/llvm/Analysis/OptimizationDiagnosticInfo.h =================================================================== --- include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -281,5 +281,11 @@ /// \brief Run the analysis pass over a function and produce BFI. Result run(Function &F, FunctionAnalysisManager &AM); }; + +namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &io, DiagnosticInfoOptimizationCommonBase *&OptDiag); +}; +} } #endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H Index: include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h =================================================================== --- /dev/null +++ include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h @@ -0,0 +1,188 @@ +//===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Optimization diagnostic interfaces for machine passes. It's packaged as an +// analysis pass so that by using this service passes become dependent on MBFI +// as well. MBFI is used to compute the "hotness" of the diagnostic message. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H +#define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H + +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" + +namespace llvm { +class MachineBasicBlock; +class MachineBlockFrequencyInfo; + +/// \brief Common features for diagnostics dealing with optimization remarks +/// that are used IR passes. +class MachineOptimizationRemarkBase + : public DiagnosticInfoOptimizationCommonBase { +public: + MachineOptimizationRemarkBase(enum DiagnosticKind Kind, const char *PassName, + StringRef RemarkName, const DebugLoc &DLoc, + MachineBasicBlock *MBB) + : DiagnosticInfoOptimizationCommonBase( + Kind, DS_Remark, PassName, RemarkName, + *MBB->getParent()->getFunction(), DLoc), + MBB(MBB) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_MachineOptimizationRemark; + } + + MachineBasicBlock *getBlock() { return MBB; } + +private: + MachineBasicBlock *MBB; +}; + +/// Diagnostic information for applied optimization remarks. +class MachineOptimizationRemark : public MachineOptimizationRemarkBase { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass=, then the diagnostic will + /// be emitted. \p RemarkName is a textual identifier for the remark. \p + /// DLoc is the debug location and \p MBB is the block that the optimization + /// operates in. + MachineOptimizationRemark(const char *PassName, StringRef RemarkName, + const DebugLoc &DLoc, MachineBasicBlock *MBB) + : MachineOptimizationRemarkBase(DK_MachineOptimizationRemark, PassName, + RemarkName, DLoc, MBB) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_MachineOptimizationRemark; + } + + /// \see DiagnosticInfoOptimizationCommonBase::isEnabled. + bool isEnabled() const override { + return OptimizationRemark::isEnabled(getPassName()); + } +}; + +/// Diagnostic information for missed-optimization remarks. +class MachineOptimizationRemarkMissed : public MachineOptimizationRemarkBase { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-missed=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark. \p DLoc is the debug location and \p MBB is the block that the + /// optimization operates in. + MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName, + const DebugLoc &DLoc, MachineBasicBlock *MBB) + : MachineOptimizationRemarkBase(DK_MachineOptimizationRemarkMissed, + PassName, RemarkName, DLoc, MBB) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_MachineOptimizationRemarkMissed; + } + + /// \see DiagnosticInfoOptimizationCommonBase::isEnabled. + bool isEnabled() const override { + return OptimizationRemarkMissed::isEnabled(getPassName()); + } +}; + +/// Diagnostic information for optimization analysis remarks. +class MachineOptimizationRemarkAnalysis : public MachineOptimizationRemarkBase { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-analysis=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark. \p DLoc is the debug location and \p MBB is the block that the + /// optimization operates in. + MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, + const DebugLoc &DLoc, + MachineBasicBlock *MBB) + : MachineOptimizationRemarkBase(DK_MachineOptimizationRemarkAnalysis, + PassName, RemarkName, DLoc, MBB) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_MachineOptimizationRemarkAnalysis; + } + + /// \see DiagnosticInfoOptimizationCommonBase::isEnabled. + bool isEnabled() const override { + return OptimizationRemarkAnalysis::isEnabled(getPassName()); + } +}; + +/// The optimization diagnostic interface. +/// +/// It allows reporting when optimizations are performed and when they are not +/// along with the reasons for it. Hotness information of the corresponding +/// code region can be included in the remark if DiagnosticHotnessRequested is +/// enabled in the LLVM context. +class MachineOptimizationRemarkEmitter { +public: + MachineOptimizationRemarkEmitter(MachineFunction *MF, + MachineBlockFrequencyInfo *MBFI) + : MF(MF), MBFI(MBFI) {} + + /// The new interface to emit remarks. + void emit(DiagnosticInfoOptimizationCommonBase &OptDiag); + + /// \brief Whether we allow for extra compile-time budget to perform more + /// analysis to produce fewer false positives. + /// + /// This is useful when reporting missed optimizations. In this case we can + /// use the extra analysis (1) to filter trivial false positives or (2) to + /// provide more context so that non-trivial false positives can be quickly + /// detected by the user. + bool allowExtraAnalysis() const { + // For now, only allow this with -fsave-optimization-record since the -Rpass + // options are handled in the front-end. + return MF->getFunction()->getContext().getDiagnosticsOutputFile(); + } + +private: + MachineFunction *MF; + + MachineBlockFrequencyInfo *MBFI; + + /// Compute hotness from IR value (currently assumed to be a block) if PGO is + /// available. + Optional computeHotness(const MachineBasicBlock *MBB); + + /// Similar but use value from \p OptDiag and update hotness there. + void computeHotness(MachineOptimizationRemarkBase &Remark); + + /// \brief Only allow verbose messages if we know we're filtering by hotness + /// (BFI is only set in this case). + bool shouldEmitVerbose() { return MBFI != nullptr; } +}; + +/// The analysis pass +/// +/// Note that this pass shouldn't generally be marked as preserved by other +/// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI +/// could be freed. +class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass { + std::unique_ptr ORE; + +public: + MachineOptimizationRemarkEmitterPass(); + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + MachineOptimizationRemarkEmitter &getORE() { + assert(ORE && "pass not run yet"); + return *ORE; + } + + static char ID; +}; +} + +#endif Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -69,6 +69,11 @@ DK_OptimizationFailure, DK_FirstRemark = DK_OptimizationRemark, DK_LastRemark = DK_OptimizationFailure, + DK_MachineOptimizationRemark, + DK_MachineOptimizationRemarkMissed, + DK_MachineOptimizationRemarkAnalysis, + DK_FirstMachineRemark = DK_MachineOptimizationRemark, + DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis, DK_MIRParser, DK_PGOProfile, DK_Unsupported, @@ -442,8 +447,10 @@ bool isVerbose() const { return IsVerbose; } static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() >= DK_FirstRemark && - DI->getKind() <= DK_LastRemark; + return (DI->getKind() >= DK_FirstRemark && + DI->getKind() <= DK_LastRemark) || + (DI->getKind() >= DK_FirstMachineRemark && + DI->getKind() <= DK_LastMachineRemark); } protected: @@ -533,6 +540,10 @@ Value *getCodeRegion() const { return CodeRegion; } + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark; + } + private: /// The IR value (currently basic block) that the optimization operates on. /// This is currently used to provide run-time hotness information with PGO. @@ -573,8 +584,10 @@ return DI->getKind() == DK_OptimizationRemark; } + static bool isEnabled(StringRef PassName); + /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override; + bool isEnabled() const override { return isEnabled(getPassName()); } }; /// Diagnostic information for missed-optimization remarks. @@ -611,8 +624,10 @@ return DI->getKind() == DK_OptimizationRemarkMissed; } + static bool isEnabled(StringRef PassName); + /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override; + bool isEnabled() const override { return isEnabled(getPassName()); } }; /// Diagnostic information for optimization analysis remarks. @@ -660,8 +675,12 @@ return DI->getKind() == DK_OptimizationRemarkAnalysis; } + static bool isEnabled(StringRef PassName); + /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override; + bool isEnabled() const override { + return shouldAlwaysPrint() || isEnabled(getPassName()); + } static const char *AlwaysPrint; Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -231,6 +231,7 @@ void initializeMachineLICMPass(PassRegistry&); void initializeMachineLoopInfoPass(PassRegistry&); void initializeMachineModuleInfoPass(PassRegistry&); +void initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry&); void initializeMachinePipelinerPass(PassRegistry&); void initializeMachinePostDominatorTreePass(PassRegistry&); void initializeMachineRegionInfoPassPass(PassRegistry&); Index: lib/Analysis/OptimizationDiagnosticInfo.cpp =================================================================== --- lib/Analysis/OptimizationDiagnosticInfo.cpp +++ lib/Analysis/OptimizationDiagnosticInfo.cpp @@ -67,44 +67,43 @@ namespace llvm { namespace yaml { -template <> struct MappingTraits { - static void mapping(IO &io, DiagnosticInfoOptimizationCommonBase *&OptDiag) { - assert(io.outputting() && "input not yet implemented"); - - if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark)) - ; - else if (io.mapTag("!Missed", - OptDiag->getKind() == DK_OptimizationRemarkMissed)) - ; - else if (io.mapTag("!Analysis", - OptDiag->getKind() == DK_OptimizationRemarkAnalysis)) - ; - else if (io.mapTag("!AnalysisFPCommute", - OptDiag->getKind() == - DK_OptimizationRemarkAnalysisFPCommute)) - ; - else if (io.mapTag("!AnalysisAliasing", - OptDiag->getKind() == - DK_OptimizationRemarkAnalysisAliasing)) - ; - else - llvm_unreachable("todo"); - - // These are read-only for now. - DebugLoc DL = OptDiag->getDebugLoc(); - StringRef FN = GlobalValue::getRealLinkageName( - OptDiag->getFunction().getName()); - - StringRef PassName(OptDiag->PassName); - io.mapRequired("Pass", PassName); - io.mapRequired("Name", OptDiag->RemarkName); - if (!io.outputting() || DL) - io.mapOptional("DebugLoc", DL); - io.mapRequired("Function", FN); - io.mapOptional("Hotness", OptDiag->Hotness); - io.mapOptional("Args", OptDiag->Args); - } -}; +void MappingTraits::mapping( + IO &io, DiagnosticInfoOptimizationCommonBase *&OptDiag) { + assert(io.outputting() && "input not yet implemented"); + + if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark)) + ; + else if (io.mapTag("!Missed", + OptDiag->getKind() == DK_OptimizationRemarkMissed)) + ; + else if (io.mapTag("!Analysis", + OptDiag->getKind() == DK_OptimizationRemarkAnalysis)) + ; + else if (io.mapTag("!AnalysisFPCommute", + OptDiag->getKind() == + DK_OptimizationRemarkAnalysisFPCommute)) + ; + else if (io.mapTag("!AnalysisAliasing", + OptDiag->getKind() == + DK_OptimizationRemarkAnalysisAliasing)) + ; + else + llvm_unreachable("todo"); + + // These are read-only for now. + DebugLoc DL = OptDiag->getDebugLoc(); + StringRef FN = + GlobalValue::getRealLinkageName(OptDiag->getFunction().getName()); + + StringRef PassName(OptDiag->PassName); + io.mapRequired("Pass", PassName); + io.mapRequired("Name", OptDiag->RemarkName); + if (!io.outputting() || DL) + io.mapOptional("DebugLoc", DL); + io.mapRequired("Function", FN); + io.mapOptional("Hotness", OptDiag->Hotness); + io.mapOptional("Args", OptDiag->Args); +} template <> struct MappingTraits { static void mapping(IO &io, DebugLoc &DL) { Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -71,6 +71,7 @@ MachineLoopInfo.cpp MachineModuleInfo.cpp MachineModuleInfoImpls.cpp + MachineOptimizationRemarkEmitter.cpp MachinePassRegistry.cpp MachinePipeliner.cpp MachinePostDominators.cpp Index: lib/CodeGen/InlineSpiller.cpp =================================================================== --- lib/CodeGen/InlineSpiller.cpp +++ lib/CodeGen/InlineSpiller.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/VirtRegMap.h" #include "llvm/IR/DebugInfo.h" @@ -140,6 +141,7 @@ const TargetInstrInfo &TII; const TargetRegisterInfo &TRI; const MachineBlockFrequencyInfo &MBFI; + MachineOptimizationRemarkEmitter *ORE; // Variables that are valid during spill(), but used by multiple methods. LiveRangeEdit *Edit; @@ -166,7 +168,8 @@ ~InlineSpiller() override {} public: - InlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm) + InlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm, + MachineOptimizationRemarkEmitter *ORE) : MF(mf), LIS(pass.getAnalysis()), LSS(pass.getAnalysis()), AA(&pass.getAnalysis().getAAResults()), @@ -175,7 +178,7 @@ MFI(mf.getFrameInfo()), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()), TRI(*mf.getSubtarget().getRegisterInfo()), - MBFI(pass.getAnalysis()), + MBFI(pass.getAnalysis()), ORE(ORE), HSpiller(pass, mf, vrm) {} void spill(LiveRangeEdit &) override; @@ -211,10 +214,10 @@ Spiller::~Spiller() { } void Spiller::anchor() { } -Spiller *createInlineSpiller(MachineFunctionPass &pass, - MachineFunction &mf, - VirtRegMap &vrm) { - return new InlineSpiller(pass, mf, vrm); +Spiller *createInlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, + VirtRegMap &vrm, + MachineOptimizationRemarkEmitter *ore) { + return new InlineSpiller(pass, mf, vrm, ore); } } @@ -869,6 +872,10 @@ DEBUG(dumpMachineInstrRangeWithSlotIndex(std::next(MI), MIS.end(), LIS, "spill")); + if (ORE) + ORE->emit( + MachineOptimizationRemark(DEBUG_TYPE, "Spill", MI->getDebugLoc(), &MBB) + << "Spilled register"); ++NumSpills; HSpiller.addToMergeableSpills(*std::next(MI), StackSlot, Original); } Index: lib/CodeGen/MachineOptimizationRemarkEmitter.cpp =================================================================== --- /dev/null +++ lib/CodeGen/MachineOptimizationRemarkEmitter.cpp @@ -0,0 +1,91 @@ +//===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Optimization diagnostic interfaces for machine passes. It's packaged as an +// analysis pass so that by using this service passes become dependent on MBFI +// as well. MBFI is used to compute the "hotness" of the diagnostic message. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/LLVMContext.h" + +using namespace llvm; + +Optional +MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock *MBB) { + if (!MBFI) + return None; + + return MBFI->getBlockProfileCount(MBB); +} + +void MachineOptimizationRemarkEmitter::computeHotness( + MachineOptimizationRemarkBase &Remark) { + MachineBasicBlock *MBB = Remark.getBlock(); + if (MBB) + Remark.setHotness(computeHotness(MBB)); +} + +void MachineOptimizationRemarkEmitter::emit( + DiagnosticInfoOptimizationCommonBase &OptDiagCommon) { + auto *OptDiag = cast(&OptDiagCommon); + computeHotness(*OptDiag); + + LLVMContext &Ctx = MF->getFunction()->getContext(); + yaml::Output *Out = Ctx.getDiagnosticsOutputFile(); + if (Out) { + auto *P = + &const_cast(OptDiagCommon); + *Out << P; + } + // FIXME: now that IsVerbose is part of DI, filtering for this will be moved + // from here to clang. + if (!OptDiag->isVerbose() || shouldEmitVerbose()) + Ctx.diagnose(*OptDiag); +} + +MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass() + : MachineFunctionPass(ID) { + initializeMachineOptimizationRemarkEmitterPassPass( + *PassRegistry::getPassRegistry()); +} + +bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( + MachineFunction &MF) { + MachineBlockFrequencyInfo *MBFI; + + if (MF.getFunction()->getContext().getDiagnosticHotnessRequested()) + MBFI = &getAnalysis(); + else + MBFI = nullptr; + + ORE = llvm::make_unique(&MF, MBFI); + return false; +} + +void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( + AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +char MachineOptimizationRemarkEmitterPass::ID = 0; +static const char ore_name[] = "Machine Optimization Remark Emitter"; +#define ORE_NAME "machine-opt-remark-emitter" + +INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, + false, true) +INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) +INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, + false, true) Index: lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- lib/CodeGen/RegAllocGreedy.cpp +++ lib/CodeGen/RegAllocGreedy.cpp @@ -31,6 +31,7 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/RegAllocRegistry.h" @@ -439,6 +440,7 @@ INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix) INITIALIZE_PASS_DEPENDENCY(EdgeBundles) INITIALIZE_PASS_DEPENDENCY(SpillPlacement) +INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass) INITIALIZE_PASS_END(RAGreedy, "greedy", "Greedy Register Allocator", false, false) @@ -490,6 +492,7 @@ AU.addPreserved(); AU.addRequired(); AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -2633,7 +2636,8 @@ Indexes = &getAnalysis(); MBFI = &getAnalysis(); DomTree = &getAnalysis(); - SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM)); + auto *ORE = &getAnalysis().getORE(); + SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, ORE)); Loops = &getAnalysis(); Bundles = &getAnalysis(); SpillPlacer = &getAnalysis(); Index: lib/CodeGen/Spiller.h =================================================================== --- lib/CodeGen/Spiller.h +++ lib/CodeGen/Spiller.h @@ -15,6 +15,7 @@ class LiveRangeEdit; class MachineFunction; class MachineFunctionPass; + class MachineOptimizationRemarkEmitter; class VirtRegMap; class LiveIntervals; @@ -34,9 +35,9 @@ /// Create and return a spiller that will insert spill code directly instead /// of deferring though VirtRegMap. - Spiller *createInlineSpiller(MachineFunctionPass &pass, - MachineFunction &mf, - VirtRegMap &vrm); + Spiller *createInlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, + VirtRegMap &vrm, + MachineOptimizationRemarkEmitter *ORE = nullptr); } #endif Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -225,9 +225,9 @@ *Inst->getParent()->getParent(), Inst->getDebugLoc(), Inst->getParent()) {} -bool OptimizationRemark::isEnabled() const { +bool OptimizationRemark::isEnabled(StringRef PassName) { return PassRemarksOptLoc.Pattern && - PassRemarksOptLoc.Pattern->match(getPassName()); + PassRemarksOptLoc.Pattern->match(PassName); } OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName, @@ -246,9 +246,9 @@ *Inst->getParent()->getParent(), Inst->getDebugLoc(), Inst->getParent()) {} -bool OptimizationRemarkMissed::isEnabled() const { +bool OptimizationRemarkMissed::isEnabled(StringRef PassName) { return PassRemarksMissedOptLoc.Pattern && - PassRemarksMissedOptLoc.Pattern->match(getPassName()); + PassRemarksMissedOptLoc.Pattern->match(PassName); } OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName, @@ -276,10 +276,9 @@ *cast(CodeRegion)->getParent(), DLoc, CodeRegion) {} -bool OptimizationRemarkAnalysis::isEnabled() const { - return shouldAlwaysPrint() || - (PassRemarksAnalysisOptLoc.Pattern && - PassRemarksAnalysisOptLoc.Pattern->match(getPassName())); +bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) { + return PassRemarksAnalysisOptLoc.Pattern && + PassRemarksAnalysisOptLoc.Pattern->match(PassName); } void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const { Index: test/CodeGen/AArch64/arm64-spill-remarks.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/arm64-spill-remarks.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple -pass-remarks=regalloc 2>&1 | FileCheck -check-prefix=REMARK %s +; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple 2>&1 | FileCheck -check-prefix=NO_REMARK %s + +; REMARK: remark: /tmp/kk.c:2:20: Spilled register +; NO_REMARK-NOT: remark: /tmp/kk.c:2:20: Spilled register + +define void @fpr128(<4 x float>* %p) nounwind ssp { +entry: + %x = load <4 x float>, <4 x float>* %p, align 16, !dbg !8 + call void asm sideeffect "; inlineasm", "~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{q16},~{q17},~{q18},~{q19},~{q20},~{q21},~{q22},~{q23},~{q24},~{q25},~{q26},~{q27},~{q28},~{q29},~{q30},~{q31},~{x0},~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{fp},~{lr},~{sp},~{memory}"() nounwind, !dbg !9 + store <4 x float> %x, <4 x float>* %p, align 16, !dbg !10 + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2) +!1 = !DIFile(filename: "/tmp/kk.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"PIC Level", i32 2} +!5 = !{!"clang version 3.9.0 "} +!6 = distinct !DISubprogram(name: "success", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !2) +!7 = !DISubroutineType(types: !2) +!8 = !DILocation(line: 2, column: 20, scope: !6) +!9 = !DILocation(line: 3, column: 20, scope: !6) +!10 = !DILocation(line: 4, column: 20, scope: !6) Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -233,6 +233,10 @@ if (DI.getSeverity() == DS_Error) *HasError = true; + if (auto *Remark = dyn_cast(&DI)) + if (!Remark->isEnabled()) + return; + DiagnosticPrinterRawOStream DP(errs()); errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; DI.print(DP);