llvm.org GIT mirror llvm / 19925fc
New OptimizationRemarkEmitter pass for MIR This allows MIR passes to emit optimization remarks with the same level of functionality that is available to IR passes. It also hooks up the greedy register allocator to report spills. This allows for interesting use cases like increasing interleaving on a loop until spilling of registers is observed. I still need to experiment whether reporting every spill scales but this demonstrates for now that the functionality works from llc using -pass-remarks*=<pass>. Differential Revision: https://reviews.llvm.org/D29004 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293110 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 3 years ago
13 changed file(s) with 530 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
281281 /// \brief Run the analysis pass over a function and produce BFI.
282282 Result run(Function &F, FunctionAnalysisManager &AM);
283283 };
284
285 namespace yaml {
286 template <> struct MappingTraits {
287 static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
288 };
289 }
284290 }
285291 #endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H
5858 /// blocks. Otherwise, return the exiting block. Return 'null' when
5959 /// multiple exiting blocks are present.
6060 MachineBasicBlock *findLoopControlBlock();
61
62 /// Return the debug location of the start of this loop.
63 /// This looks for a BB terminating instruction with a known debug
64 /// location by looking at the preheader and header blocks. If it
65 /// cannot find a terminating instruction with location information,
66 /// it returns an unknown location.
67 DebugLoc getStartLoc() const;
6168
6269 void dump() const;
6370
0 ///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
1 ///
2 /// The LLVM Compiler Infrastructure
3 ///
4 /// This file is distributed under the University of Illinois Open Source
5 /// License. See LICENSE.TXT for details.
6 ///
7 ///===---------------------------------------------------------------------===//
8 /// \file
9 /// Optimization diagnostic interfaces for machine passes. It's packaged as an
10 /// analysis pass so that by using this service passes become dependent on MBFI
11 /// as well. MBFI is used to compute the "hotness" of the diagnostic message.
12 ///
13 ///===---------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
16 #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
17
18 #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20
21 namespace llvm {
22 class MachineBasicBlock;
23 class MachineBlockFrequencyInfo;
24
25 /// \brief Common features for diagnostics dealing with optimization remarks
26 /// that are used by machine passes.
27 class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
28 public:
29 DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
30 StringRef RemarkName, const DebugLoc &DLoc,
31 MachineBasicBlock *MBB)
32 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
33 *MBB->getParent()->getFunction(), DLoc),
34 MBB(MBB) {}
35
36 static bool classof(const DiagnosticInfo *DI) {
37 return DI->getKind() >= DK_FirstMachineRemark &&
38 DI->getKind() <= DK_LastMachineRemark;
39 }
40
41 const MachineBasicBlock *getBlock() const { return MBB; }
42
43 private:
44 MachineBasicBlock *MBB;
45 };
46
47 /// Diagnostic information for applied optimization remarks.
48 class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
49 public:
50 /// \p PassName is the name of the pass emitting this diagnostic. If this name
51 /// matches the regular expression given in -Rpass=, then the diagnostic will
52 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
53 /// DLoc is the debug location and \p MBB is the block that the optimization
54 /// operates in.
55 MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
56 const DebugLoc &DLoc, MachineBasicBlock *MBB)
57 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
58 RemarkName, DLoc, MBB) {}
59
60 static bool classof(const DiagnosticInfo *DI) {
61 return DI->getKind() == DK_MachineOptimizationRemark;
62 }
63
64 /// \see DiagnosticInfoOptimizationBase::isEnabled.
65 bool isEnabled() const override {
66 return OptimizationRemark::isEnabled(getPassName());
67 }
68 };
69
70 /// Diagnostic information for missed-optimization remarks.
71 class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
72 public:
73 /// \p PassName is the name of the pass emitting this diagnostic. If this name
74 /// matches the regular expression given in -Rpass-missed=, then the
75 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
76 /// remark. \p DLoc is the debug location and \p MBB is the block that the
77 /// optimization operates in.
78 MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
79 const DebugLoc &DLoc, MachineBasicBlock *MBB)
80 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
81 PassName, RemarkName, DLoc, MBB) {}
82
83 static bool classof(const DiagnosticInfo *DI) {
84 return DI->getKind() == DK_MachineOptimizationRemarkMissed;
85 }
86
87 /// \see DiagnosticInfoOptimizationBase::isEnabled.
88 bool isEnabled() const override {
89 return OptimizationRemarkMissed::isEnabled(getPassName());
90 }
91 };
92
93 /// Diagnostic information for optimization analysis remarks.
94 class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
95 public:
96 /// \p PassName is the name of the pass emitting this diagnostic. If this name
97 /// matches the regular expression given in -Rpass-analysis=, then the
98 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
99 /// remark. \p DLoc is the debug location and \p MBB is the block that the
100 /// optimization operates in.
101 MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
102 const DebugLoc &DLoc,
103 MachineBasicBlock *MBB)
104 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
105 PassName, RemarkName, DLoc, MBB) {}
106
107 static bool classof(const DiagnosticInfo *DI) {
108 return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
109 }
110
111 /// \see DiagnosticInfoOptimizationBase::isEnabled.
112 bool isEnabled() const override {
113 return OptimizationRemarkAnalysis::isEnabled(getPassName());
114 }
115 };
116
117 /// The optimization diagnostic interface.
118 ///
119 /// It allows reporting when optimizations are performed and when they are not
120 /// along with the reasons for it. Hotness information of the corresponding
121 /// code region can be included in the remark if DiagnosticHotnessRequested is
122 /// enabled in the LLVM context.
123 class MachineOptimizationRemarkEmitter {
124 public:
125 MachineOptimizationRemarkEmitter(MachineFunction &MF,
126 MachineBlockFrequencyInfo *MBFI)
127 : MF(MF), MBFI(MBFI) {}
128
129 /// Emit an optimization remark.
130 void emit(DiagnosticInfoOptimizationBase &OptDiag);
131
132 /// \brief Whether we allow for extra compile-time budget to perform more
133 /// analysis to be more informative.
134 ///
135 /// This is useful to enable additional missed optimizations to be reported
136 /// that are normally too noisy. In this mode, we can use the extra analysis
137 /// (1) to filter trivial false positives or (2) to provide more context so
138 /// that non-trivial false positives can be quickly detected by the user.
139 bool allowExtraAnalysis() const {
140 // For now, only allow this with -fsave-optimization-record since the -Rpass
141 // options are handled in the front-end.
142 return MF.getFunction()->getContext().getDiagnosticsOutputFile();
143 }
144
145 private:
146 MachineFunction &MF;
147
148 /// MBFI is only set if hotness is requested.
149 MachineBlockFrequencyInfo *MBFI;
150
151 /// Compute hotness from IR value (currently assumed to be a block) if PGO is
152 /// available.
153 Optional computeHotness(const MachineBasicBlock &MBB);
154
155 /// Similar but use value from \p OptDiag and update hotness there.
156 void computeHotness(DiagnosticInfoMIROptimization &Remark);
157
158 /// \brief Only allow verbose messages if we know we're filtering by hotness
159 /// (BFI is only set in this case).
160 bool shouldEmitVerbose() { return MBFI != nullptr; }
161 };
162
163 /// The analysis pass
164 ///
165 /// Note that this pass shouldn't generally be marked as preserved by other
166 /// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI
167 /// could be freed.
168 class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
169 std::unique_ptr ORE;
170
171 public:
172 MachineOptimizationRemarkEmitterPass();
173
174 bool runOnMachineFunction(MachineFunction &MF) override;
175
176 void getAnalysisUsage(AnalysisUsage &AU) const override;
177
178 MachineOptimizationRemarkEmitter &getORE() {
179 assert(ORE && "pass not run yet");
180 return *ORE;
181 }
182
183 static char ID;
184 };
185 }
186
187 #endif
6868 DK_OptimizationFailure,
6969 DK_FirstRemark = DK_OptimizationRemark,
7070 DK_LastRemark = DK_OptimizationFailure,
71 DK_MachineOptimizationRemark,
72 DK_MachineOptimizationRemarkMissed,
73 DK_MachineOptimizationRemarkAnalysis,
74 DK_FirstMachineRemark = DK_MachineOptimizationRemark,
75 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
7176 DK_MIRParser,
7277 DK_PGOProfile,
7378 DK_Unsupported,
439444 bool isVerbose() const { return IsVerbose; }
440445
441446 static bool classof(const DiagnosticInfo *DI) {
442 return DI->getKind() >= DK_FirstRemark &&
443 DI->getKind() <= DK_LastRemark;
447 return (DI->getKind() >= DK_FirstRemark &&
448 DI->getKind() <= DK_LastRemark) ||
449 (DI->getKind() >= DK_FirstMachineRemark &&
450 DI->getKind() <= DK_LastMachineRemark);
444451 }
445452
446453 protected:
528535
529536 Value *getCodeRegion() const { return CodeRegion; }
530537
538 static bool classof(const DiagnosticInfo *DI) {
539 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
540 }
541
531542 private:
532543 /// The IR value (currently basic block) that the optimization operates on.
533544 /// This is currently used to provide run-time hotness information with PGO.
568579 return DI->getKind() == DK_OptimizationRemark;
569580 }
570581
582 static bool isEnabled(StringRef PassName);
583
571584 /// \see DiagnosticInfoOptimizationBase::isEnabled.
572 bool isEnabled() const override;
585 bool isEnabled() const override { return isEnabled(getPassName()); }
573586 };
574587
575588 /// Diagnostic information for missed-optimization remarks.
606619 return DI->getKind() == DK_OptimizationRemarkMissed;
607620 }
608621
622 static bool isEnabled(StringRef PassName);
623
609624 /// \see DiagnosticInfoOptimizationBase::isEnabled.
610 bool isEnabled() const override;
625 bool isEnabled() const override { return isEnabled(getPassName()); }
611626 };
612627
613628 /// Diagnostic information for optimization analysis remarks.
655670 return DI->getKind() == DK_OptimizationRemarkAnalysis;
656671 }
657672
673 static bool isEnabled(StringRef PassName);
674
658675 /// \see DiagnosticInfoOptimizationBase::isEnabled.
659 bool isEnabled() const override;
676 bool isEnabled() const override {
677 return shouldAlwaysPrint() || isEnabled(getPassName());
678 }
660679
661680 static const char *AlwaysPrint;
662681
231231 void initializeMachineLICMPass(PassRegistry&);
232232 void initializeMachineLoopInfoPass(PassRegistry&);
233233 void initializeMachineModuleInfoPass(PassRegistry&);
234 void initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry&);
234235 void initializeMachinePipelinerPass(PassRegistry&);
235236 void initializeMachinePostDominatorTreePass(PassRegistry&);
236237 void initializeMachineRegionInfoPassPass(PassRegistry&);
6666 namespace llvm {
6767 namespace yaml {
6868
69 template <> struct MappingTraits {
70 static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
71 assert(io.outputting() && "input not yet implemented");
72
73 if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark))
74 ;
75 else if (io.mapTag("!Missed",
76 OptDiag->getKind() == DK_OptimizationRemarkMissed))
77 ;
78 else if (io.mapTag("!Analysis",
79 OptDiag->getKind() == DK_OptimizationRemarkAnalysis))
80 ;
81 else if (io.mapTag("!AnalysisFPCommute",
82 OptDiag->getKind() ==
83 DK_OptimizationRemarkAnalysisFPCommute))
84 ;
85 else if (io.mapTag("!AnalysisAliasing",
86 OptDiag->getKind() ==
87 DK_OptimizationRemarkAnalysisAliasing))
88 ;
89 else
90 llvm_unreachable("todo");
91
92 // These are read-only for now.
93 DebugLoc DL = OptDiag->getDebugLoc();
94 StringRef FN = GlobalValue::getRealLinkageName(
95 OptDiag->getFunction().getName());
96
97 StringRef PassName(OptDiag->PassName);
98 io.mapRequired("Pass", PassName);
99 io.mapRequired("Name", OptDiag->RemarkName);
100 if (!io.outputting() || DL)
101 io.mapOptional("DebugLoc", DL);
102 io.mapRequired("Function", FN);
103 io.mapOptional("Hotness", OptDiag->Hotness);
104 io.mapOptional("Args", OptDiag->Args);
105 }
106 };
69 void MappingTraits::mapping(
70 IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
71 assert(io.outputting() && "input not yet implemented");
72
73 if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark))
74 ;
75 else if (io.mapTag("!Missed",
76 OptDiag->getKind() == DK_OptimizationRemarkMissed))
77 ;
78 else if (io.mapTag("!Analysis",
79 OptDiag->getKind() == DK_OptimizationRemarkAnalysis))
80 ;
81 else if (io.mapTag("!AnalysisFPCommute",
82 OptDiag->getKind() ==
83 DK_OptimizationRemarkAnalysisFPCommute))
84 ;
85 else if (io.mapTag("!AnalysisAliasing",
86 OptDiag->getKind() ==
87 DK_OptimizationRemarkAnalysisAliasing))
88 ;
89 else
90 llvm_unreachable("todo");
91
92 // These are read-only for now.
93 DebugLoc DL = OptDiag->getDebugLoc();
94 StringRef FN =
95 GlobalValue::getRealLinkageName(OptDiag->getFunction().getName());
96
97 StringRef PassName(OptDiag->PassName);
98 io.mapRequired("Pass", PassName);
99 io.mapRequired("Name", OptDiag->RemarkName);
100 if (!io.outputting() || DL)
101 io.mapOptional("DebugLoc", DL);
102 io.mapRequired("Function", FN);
103 io.mapOptional("Hotness", OptDiag->Hotness);
104 io.mapOptional("Args", OptDiag->Args);
105 }
107106
108107 template <> struct MappingTraits {
109108 static void mapping(IO &io, DebugLoc &DL) {
7070 MachineLoopInfo.cpp
7171 MachineModuleInfo.cpp
7272 MachineModuleInfoImpls.cpp
73 MachineOptimizationRemarkEmitter.cpp
7374 MachinePassRegistry.cpp
7475 MachinePipeliner.cpp
7576 MachinePostDominators.cpp
8686 return nullptr;
8787 }
8888
89 DebugLoc MachineLoop::getStartLoc() const {
90 // Try the pre-header first.
91 if (MachineBasicBlock *PHeadMBB = getLoopPreheader())
92 if (const BasicBlock *PHeadBB = PHeadMBB->getBasicBlock())
93 if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
94 return DL;
95
96 // If we have no pre-header or there are no instructions with debug
97 // info in it, try the header.
98 if (MachineBasicBlock *HeadMBB = getHeader())
99 if (const BasicBlock *HeadBB = HeadMBB->getBasicBlock())
100 return HeadBB->getTerminator()->getDebugLoc();
101
102 return DebugLoc();
103 }
104
89105 MachineBasicBlock *
90106 MachineLoopInfo::findLoopPreheader(MachineLoop *L,
91107 bool SpeculativePreheader) const {
0 ///===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*---===//
1 ///
2 /// The LLVM Compiler Infrastructure
3 ///
4 /// This file is distributed under the University of Illinois Open Source
5 /// License. See LICENSE.TXT for details.
6 ///
7 ///===---------------------------------------------------------------------===//
8 /// \file
9 /// Optimization diagnostic interfaces for machine passes. It's packaged as an
10 /// analysis pass so that by using this service passes become dependent on MBFI
11 /// as well. MBFI is used to compute the "hotness" of the diagnostic message.
12 ///
13 ///===---------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
16 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
17 #include "llvm/IR/DebugInfo.h"
18 #include "llvm/IR/DiagnosticInfo.h"
19 #include "llvm/IR/LLVMContext.h"
20
21 using namespace llvm;
22
23 Optional
24 MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock &MBB) {
25 if (!MBFI)
26 return None;
27
28 return MBFI->getBlockProfileCount(&MBB);
29 }
30
31 void MachineOptimizationRemarkEmitter::computeHotness(
32 DiagnosticInfoMIROptimization &Remark) {
33 const MachineBasicBlock *MBB = Remark.getBlock();
34 if (MBB)
35 Remark.setHotness(computeHotness(*MBB));
36 }
37
38 void MachineOptimizationRemarkEmitter::emit(
39 DiagnosticInfoOptimizationBase &OptDiagCommon) {
40 auto &OptDiag = cast(OptDiagCommon);
41 computeHotness(OptDiag);
42
43 LLVMContext &Ctx = MF.getFunction()->getContext();
44 yaml::Output *Out = Ctx.getDiagnosticsOutputFile();
45 if (Out) {
46 auto *P = &const_cast(OptDiagCommon);
47 *Out << P;
48 }
49 // FIXME: now that IsVerbose is part of DI, filtering for this will be moved
50 // from here to clang.
51 if (!OptDiag.isVerbose() || shouldEmitVerbose())
52 Ctx.diagnose(OptDiag);
53 }
54
55 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass()
56 : MachineFunctionPass(ID) {
57 initializeMachineOptimizationRemarkEmitterPassPass(
58 *PassRegistry::getPassRegistry());
59 }
60
61 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction(
62 MachineFunction &MF) {
63 MachineBlockFrequencyInfo *MBFI;
64
65 if (MF.getFunction()->getContext().getDiagnosticHotnessRequested())
66 MBFI = &getAnalysis();
67 else
68 MBFI = nullptr;
69
70 ORE = llvm::make_unique(MF, MBFI);
71 return false;
72 }
73
74 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage(
75 AnalysisUsage &AU) const {
76 AU.addRequired();
77 AU.setPreservesAll();
78 MachineFunctionPass::getAnalysisUsage(AU);
79 }
80
81 char MachineOptimizationRemarkEmitterPass::ID = 0;
82 static const char ore_name[] = "Machine Optimization Remark Emitter";
83 #define ORE_NAME "machine-opt-remark-emitter"
84
85 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name,
86 false, true)
87 INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
88 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name,
89 false, true)
2828 #include "llvm/CodeGen/LiveStackAnalysis.h"
2929 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
3030 #include "llvm/CodeGen/MachineDominators.h"
31 #include "llvm/CodeGen/MachineFrameInfo.h"
3132 #include "llvm/CodeGen/MachineFunctionPass.h"
3233 #include "llvm/CodeGen/MachineLoopInfo.h"
34 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
3335 #include "llvm/CodeGen/MachineRegisterInfo.h"
3436 #include "llvm/CodeGen/Passes.h"
3537 #include "llvm/CodeGen/RegAllocRegistry.h"
124126 MachineBlockFrequencyInfo *MBFI;
125127 MachineDominatorTree *DomTree;
126128 MachineLoopInfo *Loops;
129 MachineOptimizationRemarkEmitter *ORE;
127130 EdgeBundles *Bundles;
128131 SpillPlacement *SpillPlacer;
129132 LiveDebugVariables *DebugVars;
418421 void collectHintInfo(unsigned, HintsInfo &);
419422
420423 bool isUnusedCalleeSavedReg(unsigned PhysReg) const;
424
425 /// Compute and report the number of spills and reloads for a loop.
426 void reportNumberOfSplillsReloads(MachineLoop *L, unsigned &Reloads,
427 unsigned &FoldedReloads, unsigned &Spills,
428 unsigned &FoldedSpills);
429
430 /// Report the number of spills and reloads for each loop.
431 void reportNumberOfSplillsReloads() {
432 for (MachineLoop *L : *Loops) {
433 unsigned Reloads, FoldedReloads, Spills, FoldedSpills;
434 reportNumberOfSplillsReloads(L, Reloads, FoldedReloads, Spills,
435 FoldedSpills);
436 }
437 }
421438 };
422439 } // end anonymous namespace
423440
438455 INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
439456 INITIALIZE_PASS_DEPENDENCY(EdgeBundles)
440457 INITIALIZE_PASS_DEPENDENCY(SpillPlacement)
458 INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
441459 INITIALIZE_PASS_END(RAGreedy, "greedy",
442460 "Greedy Register Allocator", false, false)
443461
489507 AU.addPreserved();
490508 AU.addRequired();
491509 AU.addRequired();
510 AU.addRequired();
492511 MachineFunctionPass::getAnalysisUsage(AU);
493512 }
494513
26102629 return 0;
26112630 }
26122631
2632 void RAGreedy::reportNumberOfSplillsReloads(MachineLoop *L, unsigned &Reloads,
2633 unsigned &FoldedReloads,
2634 unsigned &Spills,
2635 unsigned &FoldedSpills) {
2636 Reloads = 0;
2637 FoldedReloads = 0;
2638 Spills = 0;
2639 FoldedSpills = 0;
2640
2641 // Sum up the spill and reloads in subloops.
2642 for (MachineLoop *SubLoop : *L) {
2643 unsigned SubReloads;
2644 unsigned SubFoldedReloads;
2645 unsigned SubSpills;
2646 unsigned SubFoldedSpills;
2647
2648 reportNumberOfSplillsReloads(SubLoop, SubReloads, SubFoldedReloads,
2649 SubSpills, SubFoldedSpills);
2650 Reloads += SubReloads;
2651 FoldedReloads += SubFoldedReloads;
2652 Spills += SubSpills;
2653 FoldedSpills += SubFoldedSpills;
2654 }
2655
2656 const MachineFrameInfo &MFI = MF->getFrameInfo();
2657 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
2658 int FI;
2659
2660 for (MachineBasicBlock *MBB : L->getBlocks())
2661 // Handle blocks that were not included in subloops.
2662 if (Loops->getLoopFor(MBB) == L)
2663 for (MachineInstr &MI : *MBB) {
2664 const MachineMemOperand *MMO;
2665
2666 if (TII->isLoadFromStackSlot(MI, FI) && MFI.isSpillSlotObjectIndex(FI))
2667 ++Reloads;
2668 else if (TII->hasLoadFromStackSlot(MI, MMO, FI) &&
2669 MFI.isSpillSlotObjectIndex(FI))
2670 ++FoldedReloads;
2671 else if (TII->isStoreToStackSlot(MI, FI) &&
2672 MFI.isSpillSlotObjectIndex(FI))
2673 ++Spills;
2674 else if (TII->hasStoreToStackSlot(MI, MMO, FI) &&
2675 MFI.isSpillSlotObjectIndex(FI))
2676 ++FoldedSpills;
2677 }
2678
2679 if (Reloads || FoldedReloads || Spills || FoldedSpills) {
2680 using namespace ore;
2681 MachineOptimizationRemarkMissed R(DEBUG_TYPE, "LoopSpillReload",
2682 L->getStartLoc(), L->getHeader());
2683 if (Spills)
2684 R << NV("NumSpills", Spills) << " spills ";
2685 if (FoldedSpills)
2686 R << NV("NumFoldedSpills", FoldedSpills) << " folded spills ";
2687 if (Reloads)
2688 R << NV("NumReloads", Reloads) << " reloads ";
2689 if (FoldedReloads)
2690 R << NV("NumFoldedReloads", FoldedReloads) << " folded reloads ";
2691 ORE->emit(R << "generated in loop");
2692 }
2693 }
2694
26132695 bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
26142696 DEBUG(dbgs() << "********** GREEDY REGISTER ALLOCATION **********\n"
26152697 << "********** Function: " << mf.getName() << '\n');
26322714 Indexes = &getAnalysis();
26332715 MBFI = &getAnalysis();
26342716 DomTree = &getAnalysis();
2717 ORE = &getAnalysis().getORE();
26352718 SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM));
26362719 Loops = &getAnalysis();
26372720 Bundles = &getAnalysis();
26572740 allocatePhysRegs();
26582741 tryHintsRecoloring();
26592742 postOptimization();
2743 reportNumberOfSplillsReloads();
26602744
26612745 releaseMemory();
26622746 return true;
221221 RemarkName, *Inst->getParent()->getParent(),
222222 Inst->getDebugLoc(), Inst->getParent()) {}
223223
224 bool OptimizationRemark::isEnabled() const {
224 bool OptimizationRemark::isEnabled(StringRef PassName) {
225225 return PassRemarksOptLoc.Pattern &&
226 PassRemarksOptLoc.Pattern->match(getPassName());
226 PassRemarksOptLoc.Pattern->match(PassName);
227227 }
228228
229229 OptimizationRemarkMissed::OptimizationRemarkMissed(const char *PassName,
242242 *Inst->getParent()->getParent(),
243243 Inst->getDebugLoc(), Inst->getParent()) {}
244244
245 bool OptimizationRemarkMissed::isEnabled() const {
245 bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
246246 return PassRemarksMissedOptLoc.Pattern &&
247 PassRemarksMissedOptLoc.Pattern->match(getPassName());
247 PassRemarksMissedOptLoc.Pattern->match(PassName);
248248 }
249249
250250 OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(const char *PassName,
272272 *cast(CodeRegion)->getParent(),
273273 DLoc, CodeRegion) {}
274274
275 bool OptimizationRemarkAnalysis::isEnabled() const {
276 return shouldAlwaysPrint() ||
277 (PassRemarksAnalysisOptLoc.Pattern &&
278 PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
275 bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
276 return PassRemarksAnalysisOptLoc.Pattern &&
277 PassRemarksAnalysisOptLoc.Pattern->match(PassName);
279278 }
280279
281280 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
0 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple -pass-remarks-missed=regalloc 2>&1 | FileCheck -check-prefix=REMARK %s
1 ; RUN: llc < %s -mtriple=arm64-apple-ios7.0 -aarch64-neon-syntax=apple 2>&1 | FileCheck -check-prefix=NO_REMARK %s
2
3 ; This has two nested loops, each with one value that has to be spilled and
4 ; then reloaded.
5
6 ; (loop3:)
7 ; REMARK: remark: /tmp/kk.c:3:20: 1 spills 1 reloads generated in loop
8 ; (loop2:)
9 ; REMARK: remark: /tmp/kk.c:2:20: 1 spills 1 reloads generated in loop
10 ; (loop:)
11 ; REMARK: remark: /tmp/kk.c:1:20: 2 spills 2 reloads generated in loop
12
13 ; NO_REMARK-NOT: remark
14
15 define void @fpr128(<4 x float>* %p) nounwind ssp {
16 entry:
17 br label %loop, !dbg !8
18
19 loop:
20 %i = phi i32 [ 0, %entry], [ %i.2, %end2 ]
21 br label %loop2, !dbg !9
22
23 loop2:
24 %j = phi i32 [ 0, %loop], [ %j.2, %loop2 ]
25 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
26 %j.2 = add i32 %j, 1
27 %c2 = icmp slt i32 %j.2, 100
28 br i1 %c2, label %loop2, label %end2
29
30 end2:
31 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
32 %i.2 = add i32 %i, 1
33 %c = icmp slt i32 %i.2, 100
34 br i1 %c, label %loop, label %end
35
36 end:
37 br label %loop3
38
39 loop3:
40 %k = phi i32 [ 0, %end], [ %k.2, %loop3 ]
41 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
42 %k.2 = add i32 %k, 1
43 %c3 = icmp slt i32 %k.2, 100
44 br i1 %c3, label %loop3, label %end3, !dbg !10
45
46 end3:
47 ret void
48 }
49
50 !llvm.dbg.cu = !{!0}
51 !llvm.module.flags = !{!3, !4}
52 !llvm.ident = !{!5}
53
54 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2)
55 !1 = !DIFile(filename: "/tmp/kk.c", directory: "/tmp")
56 !2 = !{}
57 !3 = !{i32 2, !"Debug Info Version", i32 3}
58 !4 = !{i32 1, !"PIC Level", i32 2}
59 !5 = !{!"clang version 3.9.0 "}
60 !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)
61 !7 = !DISubroutineType(types: !2)
62 !8 = !DILocation(line: 1, column: 20, scope: !6)
63 !9 = !DILocation(line: 2, column: 20, scope: !6)
64 !10 = !DILocation(line: 3, column: 20, scope: !6)
232232 if (DI.getSeverity() == DS_Error)
233233 *HasError = true;
234234
235 if (auto *Remark = dyn_cast(&DI))
236 if (!Remark->isEnabled())
237 return;
238
235239 DiagnosticPrinterRawOStream DP(errs());
236240 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
237241 DI.print(DP);