LLVM  14.0.0git
StandardInstrumentations.cpp
Go to the documentation of this file.
1 //===- Standard pass instrumentations handling ----------------*- C++ -*--===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file defines IR-printing pass instrumentation callbacks as well as
11 /// StandardInstrumentations class that manages standard pass instrumentations.
12 ///
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/Any.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Analysis/LoopInfo.h"
22 #include "llvm/IR/Function.h"
24 #include "llvm/IR/Module.h"
26 #include "llvm/IR/PassManager.h"
27 #include "llvm/IR/PrintPasses.h"
28 #include "llvm/IR/Verifier.h"
30 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/Program.h"
35 #include <unordered_set>
36 #include <vector>
37 
38 using namespace llvm;
39 
41  "verify-cfg-preserved", cl::Hidden,
42 #ifdef NDEBUG
43  cl::init(false));
44 #else
45  cl::init(true));
46 #endif
47 
48 // An option that prints out the IR after passes, similar to
49 // -print-after-all except that it only prints the IR after passes that
50 // change the IR. Those passes that do not make changes to the IR are
51 // reported as not making any changes. In addition, the initial IR is
52 // also reported. Other hidden options affect the output from this
53 // option. -filter-passes will limit the output to the named passes
54 // that actually change the IR and other passes are reported as filtered out.
55 // The specified passes will either be reported as making no changes (with
56 // no IR reported) or the changed IR will be reported. Also, the
57 // -filter-print-funcs and -print-module-scope options will do similar
58 // filtering based on function name, reporting changed IRs as functions(or
59 // modules if -print-module-scope is specified) for a particular function
60 // or indicating that the IR has been filtered out. The extra options
61 // can be combined, allowing only changed IRs for certain passes on certain
62 // functions to be reported in different formats, with the rest being
63 // reported as filtered out. The -print-before-changed option will print
64 // the IR as it was before each pass that changed it. The optional
65 // value of quiet will only report when the IR changes, suppressing
66 // all other messages, including the initial IR. The values "diff" and
67 // "diff-quiet" will present the changes in a form similar to a patch, in
68 // either verbose or quiet mode, respectively. The lines that are removed
69 // and added are prefixed with '-' and '+', respectively. The
70 // -filter-print-funcs and -filter-passes can be used to filter the output.
71 // This reporter relies on the linux diff utility to do comparisons and
72 // insert the prefixes. For systems that do not have the necessary
73 // facilities, the error message will be shown in place of the expected output.
74 //
75 enum class ChangePrinter {
83 };
85  "print-changed", cl::desc("Print changed IRs"), cl::Hidden,
87  cl::values(
89  "Run in quiet mode"),
91  "Display patch-like changes"),
93  "Display patch-like changes in quiet mode"),
95  "Display patch-like changes with color"),
97  "Display patch-like changes in quiet mode with color"),
98  // Sentinel value for unspecified option.
100 
101 // An option that supports the -print-changed option. See
102 // the description for -print-changed for an explanation of the use
103 // of this option. Note that this option has no effect without -print-changed.
105  PrintPassesList("filter-passes", cl::value_desc("pass names"),
106  cl::desc("Only consider IR changes for passes whose names "
107  "match for the print-changed option"),
109 // An option that supports the -print-changed option. See
110 // the description for -print-changed for an explanation of the use
111 // of this option. Note that this option has no effect without -print-changed.
112 static cl::opt<bool>
113  PrintChangedBefore("print-before-changed",
114  cl::desc("Print before passes that change them"),
115  cl::init(false), cl::Hidden);
116 
117 // An option for specifying the diff used by print-changed=[diff | diff-quiet]
119  DiffBinary("print-changed-diff-path", cl::Hidden, cl::init("diff"),
120  cl::desc("system diff used by change reporters"));
121 
122 namespace {
123 
124 // Perform a system based diff between \p Before and \p After, using
125 // \p OldLineFormat, \p NewLineFormat, and \p UnchangedLineFormat
126 // to control the formatting of the output. Return an error message
127 // for any failures instead of the diff.
128 std::string doSystemDiff(StringRef Before, StringRef After,
129  StringRef OldLineFormat, StringRef NewLineFormat,
130  StringRef UnchangedLineFormat) {
131  StringRef SR[2]{Before, After};
132  // Store the 2 bodies into temporary files and call diff on them
133  // to get the body of the node.
134  const unsigned NumFiles = 3;
135  static std::string FileName[NumFiles];
136  static int FD[NumFiles]{-1, -1, -1};
137  for (unsigned I = 0; I < NumFiles; ++I) {
138  if (FD[I] == -1) {
140  std::error_code EC =
141  sys::fs::createTemporaryFile("tmpdiff", "txt", FD[I], SV);
142  if (EC)
143  return "Unable to create temporary file.";
144  FileName[I] = Twine(SV).str();
145  }
146  // The third file is used as the result of the diff.
147  if (I == NumFiles - 1)
148  break;
149 
150  std::error_code EC = sys::fs::openFileForWrite(FileName[I], FD[I]);
151  if (EC)
152  return "Unable to open temporary file for writing.";
153 
154  raw_fd_ostream OutStream(FD[I], /*shouldClose=*/true);
155  if (FD[I] == -1)
156  return "Error opening file for writing.";
157  OutStream << SR[I];
158  }
159 
161  if (!DiffExe)
162  return "Unable to find diff executable.";
163 
164  SmallString<128> OLF = formatv("--old-line-format={0}", OldLineFormat);
165  SmallString<128> NLF = formatv("--new-line-format={0}", NewLineFormat);
166  SmallString<128> ULF =
167  formatv("--unchanged-line-format={0}", UnchangedLineFormat);
168 
169  StringRef Args[] = {"-w", "-d", OLF, NLF, ULF, FileName[0], FileName[1]};
170  Optional<StringRef> Redirects[] = {None, StringRef(FileName[2]), None};
171  int Result = sys::ExecuteAndWait(*DiffExe, Args, None, Redirects);
172  if (Result < 0)
173  return "Error executing system diff.";
174  std::string Diff;
175  auto B = MemoryBuffer::getFile(FileName[2]);
176  if (B && *B)
177  Diff = (*B)->getBuffer().str();
178  else
179  return "Unable to read result.";
180 
181  // Clean up.
182  for (unsigned I = 0; I < NumFiles; ++I) {
183  std::error_code EC = sys::fs::remove(FileName[I]);
184  if (EC)
185  return "Unable to remove temporary file.";
186  }
187  return Diff;
188 }
189 
190 /// Extract Module out of \p IR unit. May return nullptr if \p IR does not match
191 /// certain global filters. Will never return nullptr if \p Force is true.
192 const Module *unwrapModule(Any IR, bool Force = false) {
193  if (any_isa<const Module *>(IR))
194  return any_cast<const Module *>(IR);
195 
196  if (any_isa<const Function *>(IR)) {
197  const Function *F = any_cast<const Function *>(IR);
198  if (!Force && !isFunctionInPrintList(F->getName()))
199  return nullptr;
200 
201  return F->getParent();
202  }
203 
204  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
205  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
206  for (const LazyCallGraph::Node &N : *C) {
207  const Function &F = N.getFunction();
208  if (Force || (!F.isDeclaration() && isFunctionInPrintList(F.getName()))) {
209  return F.getParent();
210  }
211  }
212  assert(!Force && "Expected a module");
213  return nullptr;
214  }
215 
216  if (any_isa<const Loop *>(IR)) {
217  const Loop *L = any_cast<const Loop *>(IR);
218  const Function *F = L->getHeader()->getParent();
219  if (!Force && !isFunctionInPrintList(F->getName()))
220  return nullptr;
221  return F->getParent();
222  }
223 
224  llvm_unreachable("Unknown IR unit");
225 }
226 
227 void printIR(raw_ostream &OS, const Function *F) {
228  if (!isFunctionInPrintList(F->getName()))
229  return;
230  OS << *F;
231 }
232 
233 void printIR(raw_ostream &OS, const Module *M) {
235  M->print(OS, nullptr);
236  } else {
237  for (const auto &F : M->functions()) {
238  printIR(OS, &F);
239  }
240  }
241 }
242 
243 void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C) {
244  for (const LazyCallGraph::Node &N : *C) {
245  const Function &F = N.getFunction();
246  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
247  F.print(OS);
248  }
249  }
250 }
251 
252 void printIR(raw_ostream &OS, const Loop *L) {
253  const Function *F = L->getHeader()->getParent();
254  if (!isFunctionInPrintList(F->getName()))
255  return;
256  printLoop(const_cast<Loop &>(*L), OS);
257 }
258 
259 std::string getIRName(Any IR) {
260  if (any_isa<const Module *>(IR))
261  return "[module]";
262 
263  if (any_isa<const Function *>(IR)) {
264  const Function *F = any_cast<const Function *>(IR);
265  return F->getName().str();
266  }
267 
268  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
269  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
270  return C->getName();
271  }
272 
273  if (any_isa<const Loop *>(IR)) {
274  const Loop *L = any_cast<const Loop *>(IR);
275  std::string S;
276  raw_string_ostream OS(S);
277  L->print(OS, /*Verbose*/ false, /*PrintNested*/ false);
278  return OS.str();
279  }
280 
281  llvm_unreachable("Unknown wrapped IR type");
282 }
283 
284 bool moduleContainsFilterPrintFunc(const Module &M) {
285  return any_of(M.functions(),
286  [](const Function &F) {
287  return isFunctionInPrintList(F.getName());
288  }) ||
290 }
291 
292 bool sccContainsFilterPrintFunc(const LazyCallGraph::SCC &C) {
293  return any_of(C,
294  [](const LazyCallGraph::Node &N) {
295  return isFunctionInPrintList(N.getName());
296  }) ||
298 }
299 
300 bool shouldPrintIR(Any IR) {
301  if (any_isa<const Module *>(IR)) {
302  const Module *M = any_cast<const Module *>(IR);
303  return moduleContainsFilterPrintFunc(*M);
304  }
305 
306  if (any_isa<const Function *>(IR)) {
307  const Function *F = any_cast<const Function *>(IR);
308  return isFunctionInPrintList(F->getName());
309  }
310 
311  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
312  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
313  return sccContainsFilterPrintFunc(*C);
314  }
315 
316  if (any_isa<const Loop *>(IR)) {
317  const Loop *L = any_cast<const Loop *>(IR);
319  }
320  llvm_unreachable("Unknown wrapped IR type");
321 }
322 
323 /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
324 /// llvm::Any and does actual print job.
325 void unwrapAndPrint(raw_ostream &OS, Any IR) {
326  if (!shouldPrintIR(IR))
327  return;
328 
329  if (forcePrintModuleIR()) {
330  auto *M = unwrapModule(IR);
331  assert(M && "should have unwrapped module");
332  printIR(OS, M);
333  return;
334  }
335 
336  if (any_isa<const Module *>(IR)) {
337  const Module *M = any_cast<const Module *>(IR);
338  printIR(OS, M);
339  return;
340  }
341 
342  if (any_isa<const Function *>(IR)) {
343  const Function *F = any_cast<const Function *>(IR);
344  printIR(OS, F);
345  return;
346  }
347 
348  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
349  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
350  printIR(OS, C);
351  return;
352  }
353 
354  if (any_isa<const Loop *>(IR)) {
355  const Loop *L = any_cast<const Loop *>(IR);
356  printIR(OS, L);
357  return;
358  }
359  llvm_unreachable("Unknown wrapped IR type");
360 }
361 
362 // Return true when this is a pass for which changes should be ignored
363 bool isIgnored(StringRef PassID) {
364  return isSpecialPass(PassID,
365  {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
366  "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass"});
367 }
368 
369 } // namespace
370 
371 template <typename IRUnitT>
373  assert(BeforeStack.empty() && "Problem with Change Printer stack.");
374 }
375 
376 template <typename IRUnitT>
378  return isFunctionInPrintList(F.getName());
379 }
380 
381 template <typename IRUnitT>
383  if (isIgnored(PassID))
384  return false;
385 
386  static std::unordered_set<std::string> PrintPassNames(PrintPassesList.begin(),
387  PrintPassesList.end());
388  return PrintPassNames.empty() || PrintPassNames.count(PassID.str());
389 }
390 
391 // Return true when this is a pass on IR for which printing
392 // of changes is desired.
393 template <typename IRUnitT>
395  if (!isInterestingPass(PassID))
396  return false;
397  if (any_isa<const Function *>(IR))
398  return isInterestingFunction(*any_cast<const Function *>(IR));
399  return true;
400 }
401 
402 template <typename IRUnitT>
404  // Always need to place something on the stack because invalidated passes
405  // are not given the IR so it cannot be determined whether the pass was for
406  // something that was filtered out.
407  BeforeStack.emplace_back();
408 
409  if (!isInteresting(IR, PassID))
410  return;
411  // Is this the initial IR?
412  if (InitialIR) {
413  InitialIR = false;
414  if (VerboseMode)
415  handleInitialIR(IR);
416  }
417 
418  // Save the IR representation on the stack.
419  IRUnitT &Data = BeforeStack.back();
420  generateIRRepresentation(IR, PassID, Data);
421 }
422 
423 template <typename IRUnitT>
425  assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
426 
427  std::string Name = getIRName(IR);
428 
429  if (isIgnored(PassID)) {
430  if (VerboseMode)
431  handleIgnored(PassID, Name);
432  } else if (!isInteresting(IR, PassID)) {
433  if (VerboseMode)
434  handleFiltered(PassID, Name);
435  } else {
436  // Get the before rep from the stack
437  IRUnitT &Before = BeforeStack.back();
438  // Create the after rep
439  IRUnitT After;
440  generateIRRepresentation(IR, PassID, After);
441 
442  // Was there a change in IR?
443  if (same(Before, After)) {
444  if (VerboseMode)
445  omitAfter(PassID, Name);
446  } else
447  handleAfter(PassID, Name, Before, After, IR);
448  }
449  BeforeStack.pop_back();
450 }
451 
452 template <typename IRUnitT>
454  assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
455 
456  // Always flag it as invalidated as we cannot determine when
457  // a pass for a filtered function is invalidated since we do not
458  // get the IR in the call. Also, the output is just alternate
459  // forms of the banner anyway.
460  if (VerboseMode)
461  handleInvalidated(PassID);
462  BeforeStack.pop_back();
463 }
464 
465 template <typename IRUnitT>
469  [this](StringRef P, Any IR) { saveIRBeforePass(IR, P); });
470 
472  [this](StringRef P, Any IR, const PreservedAnalyses &) {
473  handleIRAfterPass(IR, P);
474  });
476  [this](StringRef P, const PreservedAnalyses &) {
477  handleInvalidatedPass(P);
478  });
479 }
480 
482  : Label(B.getName().str()) {
484  B.print(SS, nullptr, true, true);
485 }
486 
487 template <typename IRUnitT>
489  : ChangeReporter<IRUnitT>(Verbose), Out(dbgs()) {}
490 
491 template <typename IRUnitT>
493  // Always print the module.
494  // Unwrap and print directly to avoid filtering problems in general routines.
495  auto *M = unwrapModule(IR, /*Force=*/true);
496  assert(M && "Expected module to be unwrapped when forced.");
497  Out << "*** IR Dump At Start ***\n";
498  M->print(Out, nullptr);
499 }
500 
501 template <typename IRUnitT>
503  std::string &Name) {
504  Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
505  PassID, Name);
506 }
507 
508 template <typename IRUnitT>
510  Out << formatv("*** IR Pass {0} invalidated ***\n", PassID);
511 }
512 
513 template <typename IRUnitT>
515  std::string &Name) {
516  SmallString<20> Banner =
517  formatv("*** IR Dump After {0} on {1} filtered out ***\n", PassID, Name);
518  Out << Banner;
519 }
520 
521 template <typename IRUnitT>
523  std::string &Name) {
524  Out << formatv("*** IR Pass {0} on {1} ignored ***\n", PassID, Name);
525 }
526 
527 IRChangedPrinter::~IRChangedPrinter() {}
528 
533 }
534 
536  std::string &Output) {
537  raw_string_ostream OS(Output);
538  unwrapAndPrint(OS, IR);
539  OS.str();
540 }
541 
542 void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
543  const std::string &Before,
544  const std::string &After, Any) {
545  // Report the IR before the changes when requested.
546  if (PrintChangedBefore)
547  Out << "*** IR Dump Before " << PassID << " on " << Name << " ***\n"
548  << Before;
549 
550  // We might not get anything to print if we only want to print a specific
551  // function but it gets deleted.
552  if (After.empty()) {
553  Out << "*** IR Deleted After " << PassID << " on " << Name << " ***\n";
554  return;
555  }
556 
557  Out << "*** IR Dump After " << PassID << " on " << Name << " ***\n" << After;
558 }
559 
560 bool IRChangedPrinter::same(const std::string &S1, const std::string &S2) {
561  return S1 == S2;
562 }
563 
564 template <typename IRData>
566  const OrderedChangedData &Before, const OrderedChangedData &After,
567  function_ref<void(const IRData *, const IRData *)> HandlePair) {
568  const auto &BFD = Before.getData();
569  const auto &AFD = After.getData();
570  std::vector<std::string>::const_iterator BI = Before.getOrder().begin();
571  std::vector<std::string>::const_iterator BE = Before.getOrder().end();
572  std::vector<std::string>::const_iterator AI = After.getOrder().begin();
573  std::vector<std::string>::const_iterator AE = After.getOrder().end();
574 
575  auto handlePotentiallyRemovedIRData = [&](std::string S) {
576  // The order in LLVM may have changed so check if still exists.
577  if (!AFD.count(S)) {
578  // This has been removed.
579  HandlePair(&BFD.find(*BI)->getValue(), nullptr);
580  }
581  };
582  auto handleNewIRData = [&](std::vector<const IRData *> &Q) {
583  // Print out any queued up new sections
584  for (const IRData *NBI : Q)
585  HandlePair(nullptr, NBI);
586  Q.clear();
587  };
588 
589  // Print out the IRData in the after order, with before ones interspersed
590  // appropriately (ie, somewhere near where they were in the before list).
591  // Start at the beginning of both lists. Loop through the
592  // after list. If an element is common, then advance in the before list
593  // reporting the removed ones until the common one is reached. Report any
594  // queued up new ones and then report the common one. If an element is not
595  // common, then enqueue it for reporting. When the after list is exhausted,
596  // loop through the before list, reporting any removed ones. Finally,
597  // report the rest of the enqueued new ones.
598  std::vector<const IRData *> NewIRDataQueue;
599  while (AI != AE) {
600  if (!BFD.count(*AI)) {
601  // This section is new so place it in the queue. This will cause it
602  // to be reported after deleted sections.
603  NewIRDataQueue.emplace_back(&AFD.find(*AI)->getValue());
604  ++AI;
605  continue;
606  }
607  // This section is in both; advance and print out any before-only
608  // until we get to it.
609  while (*BI != *AI) {
610  handlePotentiallyRemovedIRData(*BI);
611  ++BI;
612  }
613  // Report any new sections that were queued up and waiting.
614  handleNewIRData(NewIRDataQueue);
615 
616  const IRData &AData = AFD.find(*AI)->getValue();
617  const IRData &BData = BFD.find(*AI)->getValue();
618  HandlePair(&BData, &AData);
619  ++BI;
620  ++AI;
621  }
622 
623  // Check any remaining before sections to see if they have been removed
624  while (BI != BE) {
625  handlePotentiallyRemovedIRData(*BI);
626  ++BI;
627  }
628 
629  handleNewIRData(NewIRDataQueue);
630 }
631 
633  StringRef Name) {
634  if (!getModuleForComparison(IR)) {
635  // Not a module so just handle the single function.
636  assert(Before.getData().size() == 1 && "Expected only one function.");
637  assert(After.getData().size() == 1 && "Expected only one function.");
638  handleFunctionCompare(Name, Prefix, PassID, false,
639  Before.getData().begin()->getValue(),
640  After.getData().begin()->getValue());
641  return;
642  }
643 
645  Before, After, [&](const ChangedFuncData *B, const ChangedFuncData *A) {
646  assert((B || A) && "Both functions cannot be missing.");
647  ChangedFuncData Missing;
648  if (!B)
649  B = &Missing;
650  else if (!A)
651  A = &Missing;
652  handleFunctionCompare(Name, Prefix, PassID, true, *B, *A);
653  });
654 }
655 
657  if (const Module *M = getModuleForComparison(IR)) {
658  // Create data for each existing/interesting function in the module.
659  for (const Function &F : *M)
661  return;
662  }
663 
664  const Function *F = nullptr;
665  if (any_isa<const Function *>(IR))
666  F = any_cast<const Function *>(IR);
667  else {
668  assert(any_isa<const Loop *>(IR) && "Unknown IR unit.");
669  const Loop *L = any_cast<const Loop *>(IR);
670  F = L->getHeader()->getParent();
671  }
672  assert(F && "Unknown IR unit.");
674 }
675 
677  if (any_isa<const Module *>(IR))
678  return any_cast<const Module *>(IR);
679  if (any_isa<const LazyCallGraph::SCC *>(IR))
680  return any_cast<const LazyCallGraph::SCC *>(IR)
681  ->begin()
682  ->getFunction()
683  .getParent();
684  return nullptr;
685 }
686 
688  const Function &F) {
689  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
690  ChangedFuncData CFD;
691  for (const auto &B : F) {
692  CFD.getOrder().emplace_back(B.getName());
693  CFD.getData().insert({B.getName(), B});
694  }
695  Data.getOrder().emplace_back(F.getName());
696  Data.getData().insert({F.getName(), CFD});
697  return true;
698  }
699  return false;
700 }
701 
703  assert(ModuleDescStack.empty() && "ModuleDescStack is not empty at exit");
704 }
705 
706 void PrintIRInstrumentation::pushModuleDesc(StringRef PassID, Any IR) {
707  const Module *M = unwrapModule(IR);
708  ModuleDescStack.emplace_back(M, getIRName(IR), PassID);
709 }
710 
711 PrintIRInstrumentation::PrintModuleDesc
712 PrintIRInstrumentation::popModuleDesc(StringRef PassID) {
713  assert(!ModuleDescStack.empty() && "empty ModuleDescStack");
714  PrintModuleDesc ModuleDesc = ModuleDescStack.pop_back_val();
715  assert(std::get<2>(ModuleDesc).equals(PassID) && "malformed ModuleDescStack");
716  return ModuleDesc;
717 }
718 
719 void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
720  if (isIgnored(PassID))
721  return;
722 
723  // Saving Module for AfterPassInvalidated operations.
724  // Note: here we rely on a fact that we do not change modules while
725  // traversing the pipeline, so the latest captured module is good
726  // for all print operations that has not happen yet.
727  if (shouldPrintAfterPass(PassID))
728  pushModuleDesc(PassID, IR);
729 
730  if (!shouldPrintBeforePass(PassID))
731  return;
732 
733  if (!shouldPrintIR(IR))
734  return;
735 
736  dbgs() << "*** IR Dump Before " << PassID << " on " << getIRName(IR)
737  << " ***\n";
738  unwrapAndPrint(dbgs(), IR);
739 }
740 
741 void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
742  if (isIgnored(PassID))
743  return;
744 
745  if (!shouldPrintAfterPass(PassID))
746  return;
747 
748  const Module *M;
749  std::string IRName;
750  StringRef StoredPassID;
751  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
752  assert(StoredPassID == PassID && "mismatched PassID");
753 
754  if (!shouldPrintIR(IR))
755  return;
756 
757  dbgs() << "*** IR Dump After " << PassID << " on " << IRName << " ***\n";
758  unwrapAndPrint(dbgs(), IR);
759 }
760 
761 void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
763  if (!shouldPrintAfterPass(PassName))
764  return;
765 
766  if (isIgnored(PassID))
767  return;
768 
769  const Module *M;
770  std::string IRName;
771  StringRef StoredPassID;
772  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
773  assert(StoredPassID == PassID && "mismatched PassID");
774  // Additional filtering (e.g. -filter-print-func) can lead to module
775  // printing being skipped.
776  if (!M)
777  return;
778 
779  SmallString<20> Banner =
780  formatv("*** IR Dump After {0} on {1} (invalidated) ***", PassID, IRName);
781  dbgs() << Banner << "\n";
782  printIR(dbgs(), M);
783 }
784 
785 bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) {
786  if (shouldPrintBeforeAll())
787  return true;
788 
791 }
792 
793 bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) {
794  if (shouldPrintAfterAll())
795  return true;
796 
799 }
800 
803  this->PIC = &PIC;
804 
805  // BeforePass callback is not just for printing, it also saves a Module
806  // for later use in AfterPassInvalidated.
809  [this](StringRef P, Any IR) { this->printBeforePass(P, IR); });
810 
811  if (shouldPrintAfterSomePass()) {
813  [this](StringRef P, Any IR, const PreservedAnalyses &) {
814  this->printAfterPass(P, IR);
815  });
817  [this](StringRef P, const PreservedAnalyses &) {
818  this->printAfterPassInvalidated(P);
819  });
820  }
821 }
822 
826  [this](StringRef P, Any IR) { return this->shouldRun(P, IR); });
827 }
828 
829 bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) {
830  const Function *F = nullptr;
831  if (any_isa<const Function *>(IR)) {
832  F = any_cast<const Function *>(IR);
833  } else if (any_isa<const Loop *>(IR)) {
834  F = any_cast<const Loop *>(IR)->getHeader()->getParent();
835  }
836  bool ShouldRun = !(F && F->hasOptNone());
837  if (!ShouldRun && DebugLogging) {
838  errs() << "Skipping pass " << PassID << " on " << F->getName()
839  << " due to optnone attribute\n";
840  }
841  return ShouldRun;
842 }
843 
846  if (!OptBisector->isEnabled())
847  return;
849  return isIgnored(PassID) || OptBisector->checkPass(PassID, getIRName(IR));
850  });
851 }
852 
853 raw_ostream &PrintPassInstrumentation::print() {
854  if (Opts.Indent) {
855  assert(Indent >= 0);
856  dbgs().indent(Indent);
857  }
858  return dbgs();
859 }
860 
863  if (!Enabled)
864  return;
865 
866  std::vector<StringRef> SpecialPasses;
867  if (!Opts.Verbose) {
868  SpecialPasses.emplace_back("PassManager");
869  SpecialPasses.emplace_back("PassAdaptor");
870  }
871 
873  [this, SpecialPasses](StringRef PassID, Any IR) {
874  assert(!isSpecialPass(PassID, SpecialPasses) &&
875  "Unexpectedly skipping special pass");
876 
877  print() << "Skipping pass: " << PassID << " on " << getIRName(IR)
878  << "\n";
879  });
880  PIC.registerBeforeNonSkippedPassCallback([this, SpecialPasses](
881  StringRef PassID, Any IR) {
882  if (isSpecialPass(PassID, SpecialPasses))
883  return;
884 
885  print() << "Running pass: " << PassID << " on " << getIRName(IR) << "\n";
886  Indent += 2;
887  });
889  [this, SpecialPasses](StringRef PassID, Any IR,
890  const PreservedAnalyses &) {
891  if (isSpecialPass(PassID, SpecialPasses))
892  return;
893 
894  Indent -= 2;
895  });
897  [this, SpecialPasses](StringRef PassID, Any IR) {
898  if (isSpecialPass(PassID, SpecialPasses))
899  return;
900 
901  Indent -= 2;
902  });
903 
904  if (!Opts.SkipAnalyses) {
906  print() << "Running analysis: " << PassID << " on " << getIRName(IR)
907  << "\n";
908  Indent += 2;
909  });
911  [this](StringRef PassID, Any IR) { Indent -= 2; });
913  print() << "Invalidating analysis: " << PassID << " on " << getIRName(IR)
914  << "\n";
915  });
917  print() << "Clearing all analysis results for: " << IRName << "\n";
918  });
919  }
920 }
921 
923  bool TrackBBLifetime) {
924  if (TrackBBLifetime)
926  for (const auto &BB : *F) {
927  if (BBGuards)
928  BBGuards->try_emplace(intptr_t(&BB), &BB);
929  for (auto *Succ : successors(&BB)) {
930  Graph[&BB][Succ]++;
931  if (BBGuards)
932  BBGuards->try_emplace(intptr_t(Succ), Succ);
933  }
934  }
935 }
936 
937 static void printBBName(raw_ostream &out, const BasicBlock *BB) {
938  if (BB->hasName()) {
939  out << BB->getName() << "<" << BB << ">";
940  return;
941  }
942 
943  if (!BB->getParent()) {
944  out << "unnamed_removed<" << BB << ">";
945  return;
946  }
947 
948  if (BB->isEntryBlock()) {
949  out << "entry"
950  << "<" << BB << ">";
951  return;
952  }
953 
954  unsigned FuncOrderBlockNum = 0;
955  for (auto &FuncBB : *BB->getParent()) {
956  if (&FuncBB == BB)
957  break;
958  FuncOrderBlockNum++;
959  }
960  out << "unnamed_" << FuncOrderBlockNum << "<" << BB << ">";
961 }
962 
964  const CFG &Before,
965  const CFG &After) {
966  assert(!After.isPoisoned());
967  if (Before.isPoisoned()) {
968  out << "Some blocks were deleted\n";
969  return;
970  }
971 
972  // Find and print graph differences.
973  if (Before.Graph.size() != After.Graph.size())
974  out << "Different number of non-leaf basic blocks: before="
975  << Before.Graph.size() << ", after=" << After.Graph.size() << "\n";
976 
977  for (auto &BB : Before.Graph) {
978  auto BA = After.Graph.find(BB.first);
979  if (BA == After.Graph.end()) {
980  out << "Non-leaf block ";
981  printBBName(out, BB.first);
982  out << " is removed (" << BB.second.size() << " successors)\n";
983  }
984  }
985 
986  for (auto &BA : After.Graph) {
987  auto BB = Before.Graph.find(BA.first);
988  if (BB == Before.Graph.end()) {
989  out << "Non-leaf block ";
990  printBBName(out, BA.first);
991  out << " is added (" << BA.second.size() << " successors)\n";
992  continue;
993  }
994 
995  if (BB->second == BA.second)
996  continue;
997 
998  out << "Different successors of block ";
999  printBBName(out, BA.first);
1000  out << " (unordered):\n";
1001  out << "- before (" << BB->second.size() << "): ";
1002  for (auto &SuccB : BB->second) {
1003  printBBName(out, SuccB.first);
1004  if (SuccB.second != 1)
1005  out << "(" << SuccB.second << "), ";
1006  else
1007  out << ", ";
1008  }
1009  out << "\n";
1010  out << "- after (" << BA.second.size() << "): ";
1011  for (auto &SuccA : BA.second) {
1012  printBBName(out, SuccA.first);
1013  if (SuccA.second != 1)
1014  out << "(" << SuccA.second << "), ";
1015  else
1016  out << ", ";
1017  }
1018  out << "\n";
1019  }
1020 }
1021 
1022 // PreservedCFGCheckerInstrumentation uses PreservedCFGCheckerAnalysis to check
1023 // passes, that reported they kept CFG analyses up-to-date, did not actually
1024 // change CFG. This check is done as follows. Before every functional pass in
1025 // BeforeNonSkippedPassCallback a CFG snapshot (an instance of
1026 // PreservedCFGCheckerInstrumentation::CFG) is requested from
1027 // FunctionAnalysisManager as a result of PreservedCFGCheckerAnalysis. When the
1028 // functional pass finishes and reports that CFGAnalyses or AllAnalyses are
1029 // up-to-date then the cached result of PreservedCFGCheckerAnalysis (if
1030 // available) is checked to be equal to a freshly created CFG snapshot.
1032  : public AnalysisInfoMixin<PreservedCFGCheckerAnalysis> {
1034 
1036 
1037 public:
1038  /// Provide the result type for this analysis pass.
1040 
1041  /// Run the analysis pass over a function and produce CFG.
1043  return Result(&F, /* TrackBBLifetime */ true);
1044  }
1045 };
1046 
1048 
1050  Function &F, const PreservedAnalyses &PA,
1052  auto PAC = PA.getChecker<PreservedCFGCheckerAnalysis>();
1053  return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
1054  PAC.preservedSet<CFGAnalyses>());
1055 }
1056 
1059  if (!VerifyPreservedCFG)
1060  return;
1061 
1062  FAM.registerPass([&] { return PreservedCFGCheckerAnalysis(); });
1063 
1064  auto checkCFG = [](StringRef Pass, StringRef FuncName, const CFG &GraphBefore,
1065  const CFG &GraphAfter) {
1066  if (GraphAfter == GraphBefore)
1067  return;
1068 
1069  dbgs() << "Error: " << Pass
1070  << " does not invalidate CFG analyses but CFG changes detected in "
1071  "function @"
1072  << FuncName << ":\n";
1073  CFG::printDiff(dbgs(), GraphBefore, GraphAfter);
1074  report_fatal_error(Twine("CFG unexpectedly changed by ", Pass));
1075  };
1076 
1078  [this, &FAM](StringRef P, Any IR) {
1079 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1080  assert(&PassStack.emplace_back(P));
1081 #endif
1082  (void)this;
1083  if (!any_isa<const Function *>(IR))
1084  return;
1085 
1086  const auto *F = any_cast<const Function *>(IR);
1087  // Make sure a fresh CFG snapshot is available before the pass.
1089  });
1090 
1092  [this](StringRef P, const PreservedAnalyses &PassPA) {
1093 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1094  assert(PassStack.pop_back_val() == P &&
1095  "Before and After callbacks must correspond");
1096 #endif
1097  (void)this;
1098  });
1099 
1101  checkCFG](StringRef P, Any IR,
1102  const PreservedAnalyses &PassPA) {
1103 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1104  assert(PassStack.pop_back_val() == P &&
1105  "Before and After callbacks must correspond");
1106 #endif
1107  (void)this;
1108 
1109  if (!any_isa<const Function *>(IR))
1110  return;
1111 
1112  if (!PassPA.allAnalysesInSetPreserved<CFGAnalyses>() &&
1114  return;
1115 
1116  const auto *F = any_cast<const Function *>(IR);
1117  if (auto *GraphBefore = FAM.getCachedResult<PreservedCFGCheckerAnalysis>(
1118  *const_cast<Function *>(F)))
1119  checkCFG(P, F->getName(), *GraphBefore,
1120  CFG(F, /* TrackBBLifetime */ false));
1121  });
1122 }
1123 
1127  [this](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
1128  if (isIgnored(P) || P == "VerifierPass")
1129  return;
1130  if (any_isa<const Function *>(IR) || any_isa<const Loop *>(IR)) {
1131  const Function *F;
1132  if (any_isa<const Loop *>(IR))
1133  F = any_cast<const Loop *>(IR)->getHeader()->getParent();
1134  else
1135  F = any_cast<const Function *>(IR);
1136  if (DebugLogging)
1137  dbgs() << "Verifying function " << F->getName() << "\n";
1138 
1139  if (verifyFunction(*F))
1140  report_fatal_error("Broken function found, compilation aborted!");
1141  } else if (any_isa<const Module *>(IR) ||
1142  any_isa<const LazyCallGraph::SCC *>(IR)) {
1143  const Module *M;
1144  if (any_isa<const LazyCallGraph::SCC *>(IR))
1145  M = any_cast<const LazyCallGraph::SCC *>(IR)
1146  ->begin()
1147  ->getFunction()
1148  .getParent();
1149  else
1150  M = any_cast<const Module *>(IR);
1151  if (DebugLogging)
1152  dbgs() << "Verifying module " << M->getName() << "\n";
1153 
1154  if (verifyModule(*M))
1155  report_fatal_error("Broken module found, compilation aborted!");
1156  }
1157  });
1158 }
1159 
1161 
1163  ChangedIRData &D) {
1165 }
1166 
1168  const ChangedIRData &Before,
1169  const ChangedIRData &After, Any IR) {
1170  SmallString<20> Banner =
1171  formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
1172  Out << Banner;
1173  ChangedIRComparer(Out, Before, After, UseColour)
1174  .compare(IR, "", PassID, Name);
1175  Out << "\n";
1176 }
1177 
1179  const ChangedIRData &D2) {
1180  return D1 == D2;
1181 }
1182 
1184  StringRef PassID, bool InModule,
1185  const ChangedFuncData &Before,
1186  const ChangedFuncData &After) {
1187  // Print a banner when this is being shown in the context of a module
1188  if (InModule)
1189  Out << "\n*** IR for function " << Name << " ***\n";
1190 
1192  Before, After, [&](const ChangedBlockData *B, const ChangedBlockData *A) {
1193  StringRef BStr = B ? B->getBody() : "\n";
1194  StringRef AStr = A ? A->getBody() : "\n";
1195  const std::string Removed =
1196  UseColour ? "\033[31m-%l\033[0m\n" : "-%l\n";
1197  const std::string Added = UseColour ? "\033[32m+%l\033[0m\n" : "+%l\n";
1198  const std::string NoChange = " %l\n";
1199  Out << doSystemDiff(BStr, AStr, Removed, Added, NoChange);
1200  });
1201 }
1202 
1209 }
1210 
1212  bool DebugLogging, bool VerifyEach, PrintPassOptions PrintPassOpts)
1213  : PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
1214  PrintChangedIR(PrintChanged == ChangePrinter::PrintChangedVerbose),
1215  PrintChangedDiff(
1220  Verify(DebugLogging), VerifyEach(VerifyEach) {}
1221 
1224  PrintIR.registerCallbacks(PIC);
1225  PrintPass.registerCallbacks(PIC);
1226  TimePasses.registerCallbacks(PIC);
1227  OptNone.registerCallbacks(PIC);
1228  OptBisect.registerCallbacks(PIC);
1229  if (FAM)
1230  PreservedCFGChecker.registerCallbacks(PIC, *FAM);
1231  PrintChangedIR.registerCallbacks(PIC);
1232  PseudoProbeVerification.registerCallbacks(PIC);
1233  if (VerifyEach)
1234  Verify.registerCallbacks(PIC);
1235  PrintChangedDiff.registerCallbacks(PIC);
1236 }
1237 
1238 namespace llvm {
1239 
1240 template class ChangeReporter<std::string>;
1241 template class TextChangeReporter<std::string>;
1242 
1243 template class ChangeReporter<ChangedIRData>;
1244 template class TextChangeReporter<ChangedIRData>;
1245 
1246 } // namespace llvm
llvm::OrderedChangedData
Definition: StandardInstrumentations.h:305
DiffBinary
static cl::opt< std::string > DiffBinary("print-changed-diff-path", cl::Hidden, cl::init("diff"), cl::desc("system diff used by change reporters"))
llvm::sys::findProgramByName
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
llvm::InLineChangePrinter::~InLineChangePrinter
~InLineChangePrinter() override
Definition: StandardInstrumentations.cpp:1160
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
MemoryBuffer.h
llvm::StringRef::back
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:168
llvm::sys::fs::openFileForWrite
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Definition: FileSystem.h:1040
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
PreservedCFGCheckerAnalysis
Definition: StandardInstrumentations.cpp:1031
llvm::InLineChangePrinter::handleAfter
virtual void handleAfter(StringRef PassID, std::string &Name, const ChangedIRData &Before, const ChangedIRData &After, Any) override
Definition: StandardInstrumentations.cpp:1167
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
Pass
print lazy value Lazy Value Info Printer Pass
Definition: LazyValueInfo.cpp:1965
Optional.h
intptr_t
llvm::ChangedIRComparer::generateFunctionData
static bool generateFunctionData(ChangedIRData &Data, const Function &F)
Definition: StandardInstrumentations.cpp:687
ChangePrinter::PrintChangedDiffQuiet
@ PrintChangedDiffQuiet
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:783
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
llvm::IRChangedPrinter::same
bool same(const std::string &Before, const std::string &After) override
Definition: StandardInstrumentations.cpp:560
llvm::Function
Definition: Function.h:62
llvm::Loop
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:530
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
ChangePrinter
ChangePrinter
Definition: StandardInstrumentations.cpp:75
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:625
ChangePrinter::PrintChangedQuiet
@ PrintChangedQuiet
llvm::TextChangeReporter::TextChangeReporter
TextChangeReporter(bool Verbose)
Definition: StandardInstrumentations.cpp:488
llvm::InlinerFunctionImportStatsOpts::Verbose
@ Verbose
llvm::PassInstrumentationCallbacks::registerBeforeNonSkippedPassCallback
void registerBeforeNonSkippedPassCallback(CallableT C)
Definition: PassInstrumentation.h:106
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
PrintPassesList
static cl::list< std::string > PrintPassesList("filter-passes", cl::value_desc("pass names"), cl::desc("Only consider IR changes for passes whose names " "match for the print-changed option"), cl::CommaSeparated, cl::Hidden)
llvm::cl::CommaSeparated
@ CommaSeparated
Definition: CommandLine.h:169
llvm::cl::ValueOptional
@ ValueOptional
Definition: CommandLine.h:136
llvm::AllAnalysesOn
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
Definition: PassManager.h:93
llvm::PrintIRInstrumentation::~PrintIRInstrumentation
~PrintIRInstrumentation()
Definition: StandardInstrumentations.cpp:702
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::verifyFunction
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
Definition: Verifier.cpp:5816
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
Module.h
llvm::PassInstrumentationCallbacks::registerAnalysesClearedCallback
void registerAnalysesClearedCallback(CallableT C)
Definition: PassInstrumentation.h:135
llvm::ChangeReporter::isInterestingFunction
bool isInterestingFunction(const Function &F)
Definition: StandardInstrumentations.cpp:377
llvm::IRChangedPrinter::generateIRRepresentation
void generateIRRepresentation(Any IR, StringRef PassID, std::string &Output) override
Definition: StandardInstrumentations.cpp:535
PIC
PassInstrumentationCallbacks PIC
Definition: PassBuilderBindings.cpp:55
llvm::ChangedBlockData::ChangedBlockData
ChangedBlockData(const BasicBlock &B)
Definition: StandardInstrumentations.cpp:481
llvm::Optional
Definition: APInt.h:33
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::PreservedCFGCheckerInstrumentation::CFG::printDiff
static void printDiff(raw_ostream &out, const CFG &Before, const CFG &After)
Definition: StandardInstrumentations.cpp:963
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
llvm::ChangeReporter::saveIRBeforePass
void saveIRBeforePass(Any IR, StringRef PassID)
Definition: StandardInstrumentations.cpp:403
LegacyPassManager.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::PassInstrumentationCallbacks::getPassNameForClassName
StringRef getPassNameForClassName(StringRef ClassName)
Get the pass name for a given pass class name.
Definition: PassInstrumentation.cpp:27
llvm::PreservedCFGCheckerInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC, FunctionAnalysisManager &FAM)
Definition: StandardInstrumentations.cpp:1057
llvm::ChangeReporter::registerRequiredCallbacks
void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:466
llvm::shouldPrintBeforeAll
bool shouldPrintBeforeAll()
Definition: PrintPasses.cpp:61
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::OrderedChangedData::getData
StringMap< IRData > & getData()
Definition: StandardInstrumentations.h:312
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::shouldPrintAfterSomePass
bool shouldPrintAfterSomePass()
Definition: PrintPasses.cpp:52
CommandLine.h
llvm::TextChangeReporter< std::string >::Out
raw_ostream & Out
Definition: StandardInstrumentations.h:250
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::PrintPassOptions::SkipAnalyses
bool SkipAnalyses
Don't print information for analyses.
Definition: StandardInstrumentations.h:86
llvm::StandardInstrumentations::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC, FunctionAnalysisManager *FAM=nullptr)
Definition: StandardInstrumentations.cpp:1222
llvm::MemoryBuffer::getFile
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Definition: MemoryBuffer.cpp:246
llvm::PrintIRInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:801
llvm::OptNoneInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:823
llvm::LazyCallGraph::SCC
An SCC of the call graph.
Definition: LazyCallGraph.h:422
llvm::PrintPassOptions
Definition: StandardInstrumentations.h:82
llvm::OptBisect
This class implements a mechanism to disable passes and individual optimizations at compile time base...
Definition: OptBisect.h:45
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::StringMap::insert
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:274
llvm::VerifyInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:1124
llvm::X86AS::SS
@ SS
Definition: X86.h:189
PassInstrumentation.h
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::OrderedChangedData::getOrder
std::vector< std::string > & getOrder()
Definition: StandardInstrumentations.h:308
PreservedCFGCheckerAnalysis::Key
static AnalysisKey Key
Definition: StandardInstrumentations.cpp:1035
llvm::isSpecialPass
bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
Definition: PassInstrumentation.cpp:33
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::printLoop
void printLoop(Loop &L, raw_ostream &OS, const std::string &Banner="")
Function to print a loop's contents as LLVM's text IR assembly.
Definition: LoopInfo.cpp:979
llvm::ChangedIRComparer::getModuleForComparison
static const Module * getModuleForComparison(Any IR)
Definition: StandardInstrumentations.cpp:676
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::shouldPrintBeforeSomePass
bool shouldPrintBeforeSomePass()
This is a helper to determine whether to print IR before or after a pass.
Definition: PrintPasses.cpp:48
IR
Statically lint checks LLVM IR
Definition: Lint.cpp:744
llvm::AnalysisManager::Invalidator
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:670
llvm::PassInstrumentationCallbacks::registerShouldRunOptionalPassCallback
void registerShouldRunOptionalPassCallback(CallableT C)
Definition: PassInstrumentation.h:96
LazyCallGraph.h
FormatVariadic.h
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
PrintPasses.h
llvm::None
const NoneType None
Definition: None.h:23
llvm::PrintPassOptions::Indent
bool Indent
Indent based on hierarchy.
Definition: StandardInstrumentations.h:88
llvm::InLineChangePrinter::generateIRRepresentation
virtual void generateIRRepresentation(Any IR, StringRef PassID, ChangedIRData &Output) override
Definition: StandardInstrumentations.cpp:1162
llvm::SmallString< 128 >
LoopInfo.h
llvm::Twine::str
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
ChangePrinter::PrintChangedColourDiffQuiet
@ PrintChangedColourDiffQuiet
llvm::PassInstrumentationCallbacks::registerBeforeAnalysisCallback
void registerBeforeAnalysisCallback(CallableT C)
Definition: PassInstrumentation.h:120
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
llvm::cl::opt< bool >
llvm::ChangeReporter
Definition: StandardInstrumentations.h:171
Verify
ppc ctr loops PowerPC CTR Loops Verify
Definition: PPCCTRLoops.cpp:77
llvm::cl::values
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:697
llvm::PassInstrumentationCallbacks::registerAnalysisInvalidatedCallback
void registerAnalysisInvalidatedCallback(CallableT C)
Definition: PassInstrumentation.h:130
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
PrintChangedBefore
static cl::opt< bool > PrintChangedBefore("print-before-changed", cl::desc("Print before passes that change them"), cl::init(false), cl::Hidden)
isInteresting
static bool isInteresting(const SCEV *S, const Instruction *I, const Loop *L, ScalarEvolution *SE, LoopInfo *LI)
isInteresting - Test whether the given expression is "interesting" when used by the given expression,...
Definition: IVUsers.cpp:60
llvm::shouldPrintAfterAll
bool shouldPrintAfterAll()
Definition: PrintPasses.cpp:63
llvm::ChangedIRComparer::analyzeIR
static void analyzeIR(Any IR, ChangedIRData &Data)
Definition: StandardInstrumentations.cpp:656
llvm::DenseMap
Definition: DenseMap.h:714
llvm::AnalysisKey
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:72
llvm::OrderedChangedData::report
static void report(const OrderedChangedData &Before, const OrderedChangedData &After, function_ref< void(const IRData *, const IRData *)> HandlePair)
Definition: StandardInstrumentations.cpp:565
llvm::TextChangeReporter
Definition: StandardInstrumentations.h:233
llvm::ChangeReporter::isInteresting
bool isInteresting(Any IR, StringRef PassID)
Definition: StandardInstrumentations.cpp:394
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::PreservedCFGCheckerInstrumentation::CFG::BBGuards
Optional< DenseMap< intptr_t, BBGuard > > BBGuards
Definition: StandardInstrumentations.h:126
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1616
llvm::isFunctionInPrintList
bool isFunctionInPrintList(StringRef FunctionName)
Definition: PrintPasses.cpp:83
llvm::StringMap::begin
iterator begin()
Definition: StringMap.h:202
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ChangeReporter::handleIRAfterPass
void handleIRAfterPass(Any IR, StringRef PassID)
Definition: StandardInstrumentations.cpp:424
llvm::codeview::CompileSym2Flags::EC
@ EC
PreservedCFGCheckerAnalysis::run
Result run(Function &F, FunctionAnalysisManager &FAM)
Run the analysis pass over a function and produce CFG.
Definition: StandardInstrumentations.cpp:1042
llvm::printBeforePasses
std::vector< std::string > printBeforePasses()
Definition: PrintPasses.cpp:73
llvm::PreservedAnalyses::allAnalysesInSetPreserved
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
Definition: PassManager.h:338
llvm::PreservedCFGCheckerInstrumentation::CFG::invalidate
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &)
Definition: StandardInstrumentations.cpp:1049
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
NDEBUG
#define NDEBUG
Definition: regutils.h:48
llvm::StringMapImpl::size
unsigned size() const
Definition: StringMap.h:93
llvm::PreservedCFGCheckerInstrumentation::CFG
Definition: StandardInstrumentations.h:125
llvm::AnalysisInfoMixin
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition: PassManager.h:397
llvm::LazyCallGraph::Node
A node in the call graph.
Definition: LazyCallGraph.h:318
llvm::ChangedIRComparer::compare
void compare(Any IR, StringRef Prefix, StringRef PassID, StringRef Name)
Definition: StandardInstrumentations.cpp:632
llvm::printAfterPasses
std::vector< std::string > printAfterPasses()
Definition: PrintPasses.cpp:77
llvm::ChangedIRComparer::After
const ChangedIRData & After
Definition: StandardInstrumentations.h:370
llvm::IRChangedPrinter::handleAfter
void handleAfter(StringRef PassID, std::string &Name, const std::string &Before, const std::string &After, Any) override
Definition: StandardInstrumentations.cpp:542
llvm::sys::fs::remove
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
llvm::sys::fs::createTemporaryFile
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
Definition: Path.cpp:856
llvm::PassInstrumentationCallbacks::registerAfterAnalysisCallback
void registerAfterAnalysisCallback(CallableT C)
Definition: PassInstrumentation.h:125
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1558
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
ChangePrinter::NoChangePrinter
@ NoChangePrinter
llvm::TimePassesHandler::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: PassTimingInfo.cpp:273
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:116
VerifyEach
bool VerifyEach
Definition: PassBuilderBindings.cpp:52
getParent
static const Function * getParent(const Value *V)
Definition: BasicAliasAnalysis.cpp:867
llvm::PseudoProbeVerifier::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: SampleProfileProbe.cpp:88
clEnumValN
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:672
llvm::PreservedCFGCheckerInstrumentation::CFG::isPoisoned
bool isPoisoned() const
Definition: StandardInstrumentations.h:135
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::InLineChangePrinter::same
virtual bool same(const ChangedIRData &Before, const ChangedIRData &After) override
Definition: StandardInstrumentations.cpp:1178
llvm::ChangedBlockData::Body
std::string Body
Definition: StandardInstrumentations.h:302
CallGraphSCCPass.h
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:443
llvm::PassInstrumentationCallbacks::registerAfterPassInvalidatedCallback
void registerAfterPassInvalidatedCallback(CallableT C)
Definition: PassInstrumentation.h:115
llvm::PrintPassOptions::Verbose
bool Verbose
Print adaptors and pass managers.
Definition: StandardInstrumentations.h:84
CFG
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to CFG
Definition: README.txt:39
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::Any
Definition: Any.h:26
Verifier.h
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::StandardInstrumentations::StandardInstrumentations
StandardInstrumentations(bool DebugLogging, bool VerifyEach=false, PrintPassOptions PrintPassOpts=PrintPassOptions())
Definition: StandardInstrumentations.cpp:1211
llvm::AnalysisManager::getCachedResult
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:802
Function.h
llvm::LoopBase::getHeader
BlockT * getHeader() const
Definition: LoopInfo.h:104
PassManager.h
llvm::OptBisector
ManagedStatic< OptBisect > OptBisector
Singleton instance of the OptBisect class, so multiple pass managers don't need to coordinate their u...
Definition: OptBisect.cpp:56
llvm::PassInstrumentationCallbacks::registerBeforeSkippedPassCallback
void registerBeforeSkippedPassCallback(CallableT C)
Definition: PassInstrumentation.h:101
llvm::cl::value_desc
Definition: CommandLine.h:422
llvm::InLineChangePrinter::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:1203
llvm::OptBisectInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:844
llvm::AnalysisManager::registerPass
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:845
PrintChanged
static cl::opt< ChangePrinter > PrintChanged("print-changed", cl::desc("Print changed IRs"), cl::Hidden, cl::ValueOptional, cl::init(ChangePrinter::NoChangePrinter), cl::values(clEnumValN(ChangePrinter::PrintChangedQuiet, "quiet", "Run in quiet mode"), clEnumValN(ChangePrinter::PrintChangedDiffVerbose, "diff", "Display patch-like changes"), clEnumValN(ChangePrinter::PrintChangedDiffQuiet, "diff-quiet", "Display patch-like changes in quiet mode"), clEnumValN(ChangePrinter::PrintChangedColourDiffVerbose, "cdiff", "Display patch-like changes with color"), clEnumValN(ChangePrinter::PrintChangedColourDiffQuiet, "cdiff-quiet", "Display patch-like changes in quiet mode with color"), clEnumValN(ChangePrinter::PrintChangedVerbose, "", "")))
llvm::ChangeReporter::handleInvalidatedPass
void handleInvalidatedPass(StringRef PassID)
Definition: StandardInstrumentations.cpp:453
Any.h
llvm::PassInstrumentationCallbacks::registerAfterPassCallback
void registerAfterPassCallback(CallableT C)
Definition: PassInstrumentation.h:110
llvm::PreservedCFGCheckerInstrumentation::CFG::CFG
CFG(const Function *F, bool TrackBBLifetime)
Definition: StandardInstrumentations.cpp:922
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:497
llvm::PassInstrumentationCallbacks
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
Definition: PassInstrumentation.h:66
N
#define N
Program.h
llvm::sys::ExecuteAndWait
int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env=None, ArrayRef< Optional< StringRef >> Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, Optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
Definition: Program.cpp:32
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::ChangedIRComparer
Definition: StandardInstrumentations.h:343
ChangePrinter::PrintChangedDiffVerbose
@ PrintChangedDiffVerbose
llvm::forcePrintModuleIR
bool forcePrintModuleIR()
Definition: PrintPasses.cpp:81
llvm::PreservedAnalyses::getChecker
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition: PassManager.h:313
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::ChangeReporter::isInterestingPass
bool isInterestingPass(StringRef PassID)
Definition: StandardInstrumentations.cpp:382
llvm::IRChangedPrinter::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:529
llvm::LoopBase::print
void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const
Print loop with all the BBs inside it.
Definition: LoopInfoImpl.h:384
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::cl::desc
Definition: CommandLine.h:412
raw_ostream.h
ChangePrinter::PrintChangedVerbose
@ PrintChangedVerbose
llvm::raw_string_ostream::str
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:643
llvm::ChangedIRComparer::handleFunctionCompare
void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID, bool InModule, const ChangedFuncData &Before, const ChangedFuncData &After)
Definition: StandardInstrumentations.cpp:1183
Debug.h
printBBName
static void printBBName(raw_ostream &out, const BasicBlock *BB)
Definition: StandardInstrumentations.cpp:937
PassName
static const char PassName[]
Definition: X86LowerAMXIntrinsics.cpp:669
llvm::ChangedBlockData
Definition: StandardInstrumentations.h:284
llvm::PreservedCFGCheckerInstrumentation::CFG::Graph
DenseMap< const BasicBlock *, DenseMap< const BasicBlock *, unsigned > > Graph
Definition: StandardInstrumentations.h:127
ChangePrinter::PrintChangedColourDiffVerbose
@ PrintChangedColourDiffVerbose
llvm::verifyModule
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:5827
llvm::PrintPassInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:861
StandardInstrumentations.h
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:908
llvm::PreservedCFGCheckerInstrumentation::VerifyPreservedCFG
static cl::opt< bool > VerifyPreservedCFG
Definition: StandardInstrumentations.h:151
llvm::ChangedIRComparer::Before
const ChangedIRData & Before
Definition: StandardInstrumentations.h:369
llvm::cl::list
Definition: CommandLine.h:1640