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,
234  bool ShouldPreserveUseListOrder = false) {
236  M->print(OS, nullptr, ShouldPreserveUseListOrder);
237  } else {
238  for (const auto &F : M->functions()) {
239  printIR(OS, &F);
240  }
241  }
242 }
243 
244 void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C) {
245  for (const LazyCallGraph::Node &N : *C) {
246  const Function &F = N.getFunction();
247  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
248  F.print(OS);
249  }
250  }
251 }
252 
253 void printIR(raw_ostream &OS, const Loop *L) {
254  const Function *F = L->getHeader()->getParent();
255  if (!isFunctionInPrintList(F->getName()))
256  return;
257  printLoop(const_cast<Loop &>(*L), OS);
258 }
259 
260 std::string getIRName(Any IR) {
261  if (any_isa<const Module *>(IR))
262  return "[module]";
263 
264  if (any_isa<const Function *>(IR)) {
265  const Function *F = any_cast<const Function *>(IR);
266  return F->getName().str();
267  }
268 
269  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
270  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
271  return C->getName();
272  }
273 
274  if (any_isa<const Loop *>(IR)) {
275  const Loop *L = any_cast<const Loop *>(IR);
276  std::string S;
277  raw_string_ostream OS(S);
278  L->print(OS, /*Verbose*/ false, /*PrintNested*/ false);
279  return OS.str();
280  }
281 
282  llvm_unreachable("Unknown wrapped IR type");
283 }
284 
285 bool moduleContainsFilterPrintFunc(const Module &M) {
286  return any_of(M.functions(),
287  [](const Function &F) {
288  return isFunctionInPrintList(F.getName());
289  }) ||
291 }
292 
293 bool sccContainsFilterPrintFunc(const LazyCallGraph::SCC &C) {
294  return any_of(C,
295  [](const LazyCallGraph::Node &N) {
296  return isFunctionInPrintList(N.getName());
297  }) ||
299 }
300 
301 bool shouldPrintIR(Any IR) {
302  if (any_isa<const Module *>(IR)) {
303  const Module *M = any_cast<const Module *>(IR);
304  return moduleContainsFilterPrintFunc(*M);
305  }
306 
307  if (any_isa<const Function *>(IR)) {
308  const Function *F = any_cast<const Function *>(IR);
309  return isFunctionInPrintList(F->getName());
310  }
311 
312  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
313  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
314  return sccContainsFilterPrintFunc(*C);
315  }
316 
317  if (any_isa<const Loop *>(IR)) {
318  const Loop *L = any_cast<const Loop *>(IR);
320  }
321  llvm_unreachable("Unknown wrapped IR type");
322 }
323 
324 /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
325 /// llvm::Any and does actual print job.
326 void unwrapAndPrint(raw_ostream &OS, Any IR,
327  bool ShouldPreserveUseListOrder = false) {
328  if (!shouldPrintIR(IR))
329  return;
330 
331  if (forcePrintModuleIR()) {
332  auto *M = unwrapModule(IR);
333  assert(M && "should have unwrapped module");
334  printIR(OS, M, ShouldPreserveUseListOrder);
335  return;
336  }
337 
338  if (any_isa<const Module *>(IR)) {
339  const Module *M = any_cast<const Module *>(IR);
340  printIR(OS, M, ShouldPreserveUseListOrder);
341  return;
342  }
343 
344  if (any_isa<const Function *>(IR)) {
345  const Function *F = any_cast<const Function *>(IR);
346  printIR(OS, F);
347  return;
348  }
349 
350  if (any_isa<const LazyCallGraph::SCC *>(IR)) {
351  const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
352  printIR(OS, C);
353  return;
354  }
355 
356  if (any_isa<const Loop *>(IR)) {
357  const Loop *L = any_cast<const Loop *>(IR);
358  printIR(OS, L);
359  return;
360  }
361  llvm_unreachable("Unknown wrapped IR type");
362 }
363 
364 // Return true when this is a pass for which changes should be ignored
365 bool isIgnored(StringRef PassID) {
366  return isSpecialPass(PassID,
367  {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
368  "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass"});
369 }
370 
371 } // namespace
372 
373 template <typename IRUnitT>
375  assert(BeforeStack.empty() && "Problem with Change Printer stack.");
376 }
377 
378 template <typename IRUnitT>
380  return isFunctionInPrintList(F.getName());
381 }
382 
383 template <typename IRUnitT>
385  if (isIgnored(PassID))
386  return false;
387 
388  static std::unordered_set<std::string> PrintPassNames(PrintPassesList.begin(),
389  PrintPassesList.end());
390  return PrintPassNames.empty() || PrintPassNames.count(PassID.str());
391 }
392 
393 // Return true when this is a pass on IR for which printing
394 // of changes is desired.
395 template <typename IRUnitT>
397  if (!isInterestingPass(PassID))
398  return false;
399  if (any_isa<const Function *>(IR))
400  return isInterestingFunction(*any_cast<const Function *>(IR));
401  return true;
402 }
403 
404 template <typename IRUnitT>
406  // Always need to place something on the stack because invalidated passes
407  // are not given the IR so it cannot be determined whether the pass was for
408  // something that was filtered out.
409  BeforeStack.emplace_back();
410 
411  if (!isInteresting(IR, PassID))
412  return;
413  // Is this the initial IR?
414  if (InitialIR) {
415  InitialIR = false;
416  if (VerboseMode)
417  handleInitialIR(IR);
418  }
419 
420  // Save the IR representation on the stack.
421  IRUnitT &Data = BeforeStack.back();
422  generateIRRepresentation(IR, PassID, Data);
423 }
424 
425 template <typename IRUnitT>
427  assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
428 
429  std::string Name = getIRName(IR);
430 
431  if (isIgnored(PassID)) {
432  if (VerboseMode)
433  handleIgnored(PassID, Name);
434  } else if (!isInteresting(IR, PassID)) {
435  if (VerboseMode)
436  handleFiltered(PassID, Name);
437  } else {
438  // Get the before rep from the stack
439  IRUnitT &Before = BeforeStack.back();
440  // Create the after rep
441  IRUnitT After;
442  generateIRRepresentation(IR, PassID, After);
443 
444  // Was there a change in IR?
445  if (same(Before, After)) {
446  if (VerboseMode)
447  omitAfter(PassID, Name);
448  } else
449  handleAfter(PassID, Name, Before, After, IR);
450  }
451  BeforeStack.pop_back();
452 }
453 
454 template <typename IRUnitT>
456  assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
457 
458  // Always flag it as invalidated as we cannot determine when
459  // a pass for a filtered function is invalidated since we do not
460  // get the IR in the call. Also, the output is just alternate
461  // forms of the banner anyway.
462  if (VerboseMode)
463  handleInvalidated(PassID);
464  BeforeStack.pop_back();
465 }
466 
467 template <typename IRUnitT>
471  [this](StringRef P, Any IR) { saveIRBeforePass(IR, P); });
472 
474  [this](StringRef P, Any IR, const PreservedAnalyses &) {
475  handleIRAfterPass(IR, P);
476  });
478  [this](StringRef P, const PreservedAnalyses &) {
479  handleInvalidatedPass(P);
480  });
481 }
482 
484  : Label(B.getName().str()) {
486  B.print(SS, nullptr, true, true);
487 }
488 
489 template <typename IRUnitT>
491  : ChangeReporter<IRUnitT>(Verbose), Out(dbgs()) {}
492 
493 template <typename IRUnitT>
495  // Always print the module.
496  // Unwrap and print directly to avoid filtering problems in general routines.
497  auto *M = unwrapModule(IR, /*Force=*/true);
498  assert(M && "Expected module to be unwrapped when forced.");
499  Out << "*** IR Dump At Start ***\n";
500  M->print(Out, nullptr,
501  /*ShouldPreserveUseListOrder=*/true);
502 }
503 
504 template <typename IRUnitT>
506  std::string &Name) {
507  Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
508  PassID, Name);
509 }
510 
511 template <typename IRUnitT>
513  Out << formatv("*** IR Pass {0} invalidated ***\n", PassID);
514 }
515 
516 template <typename IRUnitT>
518  std::string &Name) {
519  SmallString<20> Banner =
520  formatv("*** IR Dump After {0} on {1} filtered out ***\n", PassID, Name);
521  Out << Banner;
522 }
523 
524 template <typename IRUnitT>
526  std::string &Name) {
527  Out << formatv("*** IR Pass {0} on {1} ignored ***\n", PassID, Name);
528 }
529 
530 IRChangedPrinter::~IRChangedPrinter() {}
531 
536 }
537 
539  std::string &Output) {
540  raw_string_ostream OS(Output);
541  unwrapAndPrint(OS, IR,
542  /*ShouldPreserveUseListOrder=*/true);
543  OS.str();
544 }
545 
546 void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
547  const std::string &Before,
548  const std::string &After, Any) {
549  // Report the IR before the changes when requested.
550  if (PrintChangedBefore)
551  Out << "*** IR Dump Before " << PassID << " on " << Name << " ***\n"
552  << Before;
553 
554  // We might not get anything to print if we only want to print a specific
555  // function but it gets deleted.
556  if (After.empty()) {
557  Out << "*** IR Deleted After " << PassID << " on " << Name << " ***\n";
558  return;
559  }
560 
561  Out << "*** IR Dump After " << PassID << " on " << Name << " ***\n" << After;
562 }
563 
564 bool IRChangedPrinter::same(const std::string &S1, const std::string &S2) {
565  return S1 == S2;
566 }
567 
568 template <typename IRData>
570  const OrderedChangedData &Before, const OrderedChangedData &After,
571  function_ref<void(const IRData *, const IRData *)> HandlePair) {
572  const auto &BFD = Before.getData();
573  const auto &AFD = After.getData();
574  std::vector<std::string>::const_iterator BI = Before.getOrder().begin();
575  std::vector<std::string>::const_iterator BE = Before.getOrder().end();
576  std::vector<std::string>::const_iterator AI = After.getOrder().begin();
577  std::vector<std::string>::const_iterator AE = After.getOrder().end();
578 
579  auto handlePotentiallyRemovedIRData = [&](std::string S) {
580  // The order in LLVM may have changed so check if still exists.
581  if (!AFD.count(S)) {
582  // This has been removed.
583  HandlePair(&BFD.find(*BI)->getValue(), nullptr);
584  }
585  };
586  auto handleNewIRData = [&](std::vector<const IRData *> &Q) {
587  // Print out any queued up new sections
588  for (const IRData *NBI : Q)
589  HandlePair(nullptr, NBI);
590  Q.clear();
591  };
592 
593  // Print out the IRData in the after order, with before ones interspersed
594  // appropriately (ie, somewhere near where they were in the before list).
595  // Start at the beginning of both lists. Loop through the
596  // after list. If an element is common, then advance in the before list
597  // reporting the removed ones until the common one is reached. Report any
598  // queued up new ones and then report the common one. If an element is not
599  // common, then enqueue it for reporting. When the after list is exhausted,
600  // loop through the before list, reporting any removed ones. Finally,
601  // report the rest of the enqueued new ones.
602  std::vector<const IRData *> NewIRDataQueue;
603  while (AI != AE) {
604  if (!BFD.count(*AI)) {
605  // This section is new so place it in the queue. This will cause it
606  // to be reported after deleted sections.
607  NewIRDataQueue.emplace_back(&AFD.find(*AI)->getValue());
608  ++AI;
609  continue;
610  }
611  // This section is in both; advance and print out any before-only
612  // until we get to it.
613  while (*BI != *AI) {
614  handlePotentiallyRemovedIRData(*BI);
615  ++BI;
616  }
617  // Report any new sections that were queued up and waiting.
618  handleNewIRData(NewIRDataQueue);
619 
620  const IRData &AData = AFD.find(*AI)->getValue();
621  const IRData &BData = BFD.find(*AI)->getValue();
622  HandlePair(&BData, &AData);
623  ++BI;
624  ++AI;
625  }
626 
627  // Check any remaining before sections to see if they have been removed
628  while (BI != BE) {
629  handlePotentiallyRemovedIRData(*BI);
630  ++BI;
631  }
632 
633  handleNewIRData(NewIRDataQueue);
634 }
635 
637  StringRef Name) {
638  if (!getModuleForComparison(IR)) {
639  // Not a module so just handle the single function.
640  assert(Before.getData().size() == 1 && "Expected only one function.");
641  assert(After.getData().size() == 1 && "Expected only one function.");
642  handleFunctionCompare(Name, Prefix, PassID, false,
643  Before.getData().begin()->getValue(),
644  After.getData().begin()->getValue());
645  return;
646  }
647 
649  Before, After, [&](const ChangedFuncData *B, const ChangedFuncData *A) {
650  assert((B || A) && "Both functions cannot be missing.");
651  ChangedFuncData Missing;
652  if (!B)
653  B = &Missing;
654  else if (!A)
655  A = &Missing;
656  handleFunctionCompare(Name, Prefix, PassID, true, *B, *A);
657  });
658 }
659 
661  if (const Module *M = getModuleForComparison(IR)) {
662  // Create data for each existing/interesting function in the module.
663  for (const Function &F : *M)
665  return;
666  }
667 
668  const Function *F = nullptr;
669  if (any_isa<const Function *>(IR))
670  F = any_cast<const Function *>(IR);
671  else {
672  assert(any_isa<const Loop *>(IR) && "Unknown IR unit.");
673  const Loop *L = any_cast<const Loop *>(IR);
674  F = L->getHeader()->getParent();
675  }
676  assert(F && "Unknown IR unit.");
678 }
679 
681  if (any_isa<const Module *>(IR))
682  return any_cast<const Module *>(IR);
683  if (any_isa<const LazyCallGraph::SCC *>(IR))
684  return any_cast<const LazyCallGraph::SCC *>(IR)
685  ->begin()
686  ->getFunction()
687  .getParent();
688  return nullptr;
689 }
690 
692  const Function &F) {
693  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
694  ChangedFuncData CFD;
695  for (const auto &B : F) {
696  CFD.getOrder().emplace_back(B.getName());
697  CFD.getData().insert({B.getName(), B});
698  }
699  Data.getOrder().emplace_back(F.getName());
700  Data.getData().insert({F.getName(), CFD});
701  return true;
702  }
703  return false;
704 }
705 
707  assert(ModuleDescStack.empty() && "ModuleDescStack is not empty at exit");
708 }
709 
710 void PrintIRInstrumentation::pushModuleDesc(StringRef PassID, Any IR) {
711  const Module *M = unwrapModule(IR);
712  ModuleDescStack.emplace_back(M, getIRName(IR), PassID);
713 }
714 
715 PrintIRInstrumentation::PrintModuleDesc
716 PrintIRInstrumentation::popModuleDesc(StringRef PassID) {
717  assert(!ModuleDescStack.empty() && "empty ModuleDescStack");
718  PrintModuleDesc ModuleDesc = ModuleDescStack.pop_back_val();
719  assert(std::get<2>(ModuleDesc).equals(PassID) && "malformed ModuleDescStack");
720  return ModuleDesc;
721 }
722 
723 void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
724  if (isIgnored(PassID))
725  return;
726 
727  // Saving Module for AfterPassInvalidated operations.
728  // Note: here we rely on a fact that we do not change modules while
729  // traversing the pipeline, so the latest captured module is good
730  // for all print operations that has not happen yet.
731  if (shouldPrintAfterPass(PassID))
732  pushModuleDesc(PassID, IR);
733 
734  if (!shouldPrintBeforePass(PassID))
735  return;
736 
737  if (!shouldPrintIR(IR))
738  return;
739 
740  dbgs() << "*** IR Dump Before " << PassID << " on " << getIRName(IR)
741  << " ***\n";
742  unwrapAndPrint(dbgs(), IR);
743 }
744 
745 void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
746  if (isIgnored(PassID))
747  return;
748 
749  if (!shouldPrintAfterPass(PassID))
750  return;
751 
752  const Module *M;
753  std::string IRName;
754  StringRef StoredPassID;
755  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
756  assert(StoredPassID == PassID && "mismatched PassID");
757 
758  if (!shouldPrintIR(IR))
759  return;
760 
761  dbgs() << "*** IR Dump After " << PassID << " on " << IRName << " ***\n";
762  unwrapAndPrint(dbgs(), IR);
763 }
764 
765 void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
767  if (!shouldPrintAfterPass(PassName))
768  return;
769 
770  if (isIgnored(PassID))
771  return;
772 
773  const Module *M;
774  std::string IRName;
775  StringRef StoredPassID;
776  std::tie(M, IRName, StoredPassID) = popModuleDesc(PassID);
777  assert(StoredPassID == PassID && "mismatched PassID");
778  // Additional filtering (e.g. -filter-print-func) can lead to module
779  // printing being skipped.
780  if (!M)
781  return;
782 
783  SmallString<20> Banner =
784  formatv("*** IR Dump After {0} on {1} (invalidated) ***", PassID, IRName);
785  dbgs() << Banner << "\n";
786  printIR(dbgs(), M);
787 }
788 
789 bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) {
790  if (shouldPrintBeforeAll())
791  return true;
792 
795 }
796 
797 bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) {
798  if (shouldPrintAfterAll())
799  return true;
800 
803 }
804 
807  this->PIC = &PIC;
808 
809  // BeforePass callback is not just for printing, it also saves a Module
810  // for later use in AfterPassInvalidated.
813  [this](StringRef P, Any IR) { this->printBeforePass(P, IR); });
814 
815  if (shouldPrintAfterSomePass()) {
817  [this](StringRef P, Any IR, const PreservedAnalyses &) {
818  this->printAfterPass(P, IR);
819  });
821  [this](StringRef P, const PreservedAnalyses &) {
822  this->printAfterPassInvalidated(P);
823  });
824  }
825 }
826 
830  [this](StringRef P, Any IR) { return this->shouldRun(P, IR); });
831 }
832 
833 bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) {
834  const Function *F = nullptr;
835  if (any_isa<const Function *>(IR)) {
836  F = any_cast<const Function *>(IR);
837  } else if (any_isa<const Loop *>(IR)) {
838  F = any_cast<const Loop *>(IR)->getHeader()->getParent();
839  }
840  bool ShouldRun = !(F && F->hasOptNone());
841  if (!ShouldRun && DebugLogging) {
842  errs() << "Skipping pass " << PassID << " on " << F->getName()
843  << " due to optnone attribute\n";
844  }
845  return ShouldRun;
846 }
847 
850  if (!OptBisector->isEnabled())
851  return;
853  return isIgnored(PassID) || OptBisector->checkPass(PassID, getIRName(IR));
854  });
855 }
856 
857 raw_ostream &PrintPassInstrumentation::print() {
858  if (Opts.Indent) {
859  assert(Indent >= 0);
860  dbgs().indent(Indent);
861  }
862  return dbgs();
863 }
864 
867  if (!Enabled)
868  return;
869 
870  std::vector<StringRef> SpecialPasses;
871  if (!Opts.Verbose) {
872  SpecialPasses.emplace_back("PassManager");
873  SpecialPasses.emplace_back("PassAdaptor");
874  }
875 
877  [this, SpecialPasses](StringRef PassID, Any IR) {
878  assert(!isSpecialPass(PassID, SpecialPasses) &&
879  "Unexpectedly skipping special pass");
880 
881  print() << "Skipping pass: " << PassID << " on " << getIRName(IR)
882  << "\n";
883  });
884  PIC.registerBeforeNonSkippedPassCallback([this, SpecialPasses](
885  StringRef PassID, Any IR) {
886  if (isSpecialPass(PassID, SpecialPasses))
887  return;
888 
889  print() << "Running pass: " << PassID << " on " << getIRName(IR) << "\n";
890  Indent += 2;
891  });
893  [this, SpecialPasses](StringRef PassID, Any IR,
894  const PreservedAnalyses &) {
895  if (isSpecialPass(PassID, SpecialPasses))
896  return;
897 
898  Indent -= 2;
899  });
901  [this, SpecialPasses](StringRef PassID, Any IR) {
902  if (isSpecialPass(PassID, SpecialPasses))
903  return;
904 
905  Indent -= 2;
906  });
907 
908  if (!Opts.SkipAnalyses) {
910  print() << "Running analysis: " << PassID << " on " << getIRName(IR)
911  << "\n";
912  Indent += 2;
913  });
915  [this](StringRef PassID, Any IR) { Indent -= 2; });
917  print() << "Invalidating analysis: " << PassID << " on " << getIRName(IR)
918  << "\n";
919  });
921  print() << "Clearing all analysis results for: " << IRName << "\n";
922  });
923  }
924 }
925 
927  bool TrackBBLifetime) {
928  if (TrackBBLifetime)
930  for (const auto &BB : *F) {
931  if (BBGuards)
932  BBGuards->try_emplace(intptr_t(&BB), &BB);
933  for (auto *Succ : successors(&BB)) {
934  Graph[&BB][Succ]++;
935  if (BBGuards)
936  BBGuards->try_emplace(intptr_t(Succ), Succ);
937  }
938  }
939 }
940 
941 static void printBBName(raw_ostream &out, const BasicBlock *BB) {
942  if (BB->hasName()) {
943  out << BB->getName() << "<" << BB << ">";
944  return;
945  }
946 
947  if (!BB->getParent()) {
948  out << "unnamed_removed<" << BB << ">";
949  return;
950  }
951 
952  if (BB->isEntryBlock()) {
953  out << "entry"
954  << "<" << BB << ">";
955  return;
956  }
957 
958  unsigned FuncOrderBlockNum = 0;
959  for (auto &FuncBB : *BB->getParent()) {
960  if (&FuncBB == BB)
961  break;
962  FuncOrderBlockNum++;
963  }
964  out << "unnamed_" << FuncOrderBlockNum << "<" << BB << ">";
965 }
966 
968  const CFG &Before,
969  const CFG &After) {
970  assert(!After.isPoisoned());
971  if (Before.isPoisoned()) {
972  out << "Some blocks were deleted\n";
973  return;
974  }
975 
976  // Find and print graph differences.
977  if (Before.Graph.size() != After.Graph.size())
978  out << "Different number of non-leaf basic blocks: before="
979  << Before.Graph.size() << ", after=" << After.Graph.size() << "\n";
980 
981  for (auto &BB : Before.Graph) {
982  auto BA = After.Graph.find(BB.first);
983  if (BA == After.Graph.end()) {
984  out << "Non-leaf block ";
985  printBBName(out, BB.first);
986  out << " is removed (" << BB.second.size() << " successors)\n";
987  }
988  }
989 
990  for (auto &BA : After.Graph) {
991  auto BB = Before.Graph.find(BA.first);
992  if (BB == Before.Graph.end()) {
993  out << "Non-leaf block ";
994  printBBName(out, BA.first);
995  out << " is added (" << BA.second.size() << " successors)\n";
996  continue;
997  }
998 
999  if (BB->second == BA.second)
1000  continue;
1001 
1002  out << "Different successors of block ";
1003  printBBName(out, BA.first);
1004  out << " (unordered):\n";
1005  out << "- before (" << BB->second.size() << "): ";
1006  for (auto &SuccB : BB->second) {
1007  printBBName(out, SuccB.first);
1008  if (SuccB.second != 1)
1009  out << "(" << SuccB.second << "), ";
1010  else
1011  out << ", ";
1012  }
1013  out << "\n";
1014  out << "- after (" << BA.second.size() << "): ";
1015  for (auto &SuccA : BA.second) {
1016  printBBName(out, SuccA.first);
1017  if (SuccA.second != 1)
1018  out << "(" << SuccA.second << "), ";
1019  else
1020  out << ", ";
1021  }
1022  out << "\n";
1023  }
1024 }
1025 
1026 // PreservedCFGCheckerInstrumentation uses PreservedCFGCheckerAnalysis to check
1027 // passes, that reported they kept CFG analyses up-to-date, did not actually
1028 // change CFG. This check is done as follows. Before every functional pass in
1029 // BeforeNonSkippedPassCallback a CFG snapshot (an instance of
1030 // PreservedCFGCheckerInstrumentation::CFG) is requested from
1031 // FunctionAnalysisManager as a result of PreservedCFGCheckerAnalysis. When the
1032 // functional pass finishes and reports that CFGAnalyses or AllAnalyses are
1033 // up-to-date then the cached result of PreservedCFGCheckerAnalysis (if
1034 // available) is checked to be equal to a freshly created CFG snapshot.
1036  : public AnalysisInfoMixin<PreservedCFGCheckerAnalysis> {
1038 
1040 
1041 public:
1042  /// Provide the result type for this analysis pass.
1044 
1045  /// Run the analysis pass over a function and produce CFG.
1047  return Result(&F, /* TrackBBLifetime */ true);
1048  }
1049 };
1050 
1052 
1054  Function &F, const PreservedAnalyses &PA,
1056  auto PAC = PA.getChecker<PreservedCFGCheckerAnalysis>();
1057  return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
1058  PAC.preservedSet<CFGAnalyses>());
1059 }
1060 
1063  if (!VerifyPreservedCFG)
1064  return;
1065 
1066  FAM.registerPass([&] { return PreservedCFGCheckerAnalysis(); });
1067 
1068  auto checkCFG = [](StringRef Pass, StringRef FuncName, const CFG &GraphBefore,
1069  const CFG &GraphAfter) {
1070  if (GraphAfter == GraphBefore)
1071  return;
1072 
1073  dbgs() << "Error: " << Pass
1074  << " does not invalidate CFG analyses but CFG changes detected in "
1075  "function @"
1076  << FuncName << ":\n";
1077  CFG::printDiff(dbgs(), GraphBefore, GraphAfter);
1078  report_fatal_error(Twine("CFG unexpectedly changed by ", Pass));
1079  };
1080 
1082  [this, &FAM](StringRef P, Any IR) {
1083 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1084  assert(&PassStack.emplace_back(P));
1085 #endif
1086  (void)this;
1087  if (!any_isa<const Function *>(IR))
1088  return;
1089 
1090  const auto *F = any_cast<const Function *>(IR);
1091  // Make sure a fresh CFG snapshot is available before the pass.
1093  });
1094 
1096  [this](StringRef P, const PreservedAnalyses &PassPA) {
1097 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1098  assert(PassStack.pop_back_val() == P &&
1099  "Before and After callbacks must correspond");
1100 #endif
1101  (void)this;
1102  });
1103 
1105  checkCFG](StringRef P, Any IR,
1106  const PreservedAnalyses &PassPA) {
1107 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
1108  assert(PassStack.pop_back_val() == P &&
1109  "Before and After callbacks must correspond");
1110 #endif
1111  (void)this;
1112 
1113  if (!any_isa<const Function *>(IR))
1114  return;
1115 
1116  if (!PassPA.allAnalysesInSetPreserved<CFGAnalyses>() &&
1118  return;
1119 
1120  const auto *F = any_cast<const Function *>(IR);
1121  if (auto *GraphBefore = FAM.getCachedResult<PreservedCFGCheckerAnalysis>(
1122  *const_cast<Function *>(F)))
1123  checkCFG(P, F->getName(), *GraphBefore,
1124  CFG(F, /* TrackBBLifetime */ false));
1125  });
1126 }
1127 
1131  [this](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
1132  if (isIgnored(P) || P == "VerifierPass")
1133  return;
1134  if (any_isa<const Function *>(IR) || any_isa<const Loop *>(IR)) {
1135  const Function *F;
1136  if (any_isa<const Loop *>(IR))
1137  F = any_cast<const Loop *>(IR)->getHeader()->getParent();
1138  else
1139  F = any_cast<const Function *>(IR);
1140  if (DebugLogging)
1141  dbgs() << "Verifying function " << F->getName() << "\n";
1142 
1143  if (verifyFunction(*F))
1144  report_fatal_error("Broken function found, compilation aborted!");
1145  } else if (any_isa<const Module *>(IR) ||
1146  any_isa<const LazyCallGraph::SCC *>(IR)) {
1147  const Module *M;
1148  if (any_isa<const LazyCallGraph::SCC *>(IR))
1149  M = any_cast<const LazyCallGraph::SCC *>(IR)
1150  ->begin()
1151  ->getFunction()
1152  .getParent();
1153  else
1154  M = any_cast<const Module *>(IR);
1155  if (DebugLogging)
1156  dbgs() << "Verifying module " << M->getName() << "\n";
1157 
1158  if (verifyModule(*M))
1159  report_fatal_error("Broken module found, compilation aborted!");
1160  }
1161  });
1162 }
1163 
1165 
1167  ChangedIRData &D) {
1169 }
1170 
1172  const ChangedIRData &Before,
1173  const ChangedIRData &After, Any IR) {
1174  SmallString<20> Banner =
1175  formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
1176  Out << Banner;
1177  ChangedIRComparer(Out, Before, After, UseColour)
1178  .compare(IR, "", PassID, Name);
1179  Out << "\n";
1180 }
1181 
1183  const ChangedIRData &D2) {
1184  return D1 == D2;
1185 }
1186 
1188  StringRef PassID, bool InModule,
1189  const ChangedFuncData &Before,
1190  const ChangedFuncData &After) {
1191  // Print a banner when this is being shown in the context of a module
1192  if (InModule)
1193  Out << "\n*** IR for function " << Name << " ***\n";
1194 
1196  Before, After, [&](const ChangedBlockData *B, const ChangedBlockData *A) {
1197  StringRef BStr = B ? B->getBody() : "\n";
1198  StringRef AStr = A ? A->getBody() : "\n";
1199  const std::string Removed =
1200  UseColour ? "\033[31m-%l\033[0m\n" : "-%l\n";
1201  const std::string Added = UseColour ? "\033[32m+%l\033[0m\n" : "+%l\n";
1202  const std::string NoChange = " %l\n";
1203  Out << doSystemDiff(BStr, AStr, Removed, Added, NoChange);
1204  });
1205 }
1206 
1213 }
1214 
1216  bool DebugLogging, bool VerifyEach, PrintPassOptions PrintPassOpts)
1217  : PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
1218  PrintChangedIR(PrintChanged == ChangePrinter::PrintChangedVerbose),
1219  PrintChangedDiff(
1224  Verify(DebugLogging), VerifyEach(VerifyEach) {}
1225 
1228  PrintIR.registerCallbacks(PIC);
1229  PrintPass.registerCallbacks(PIC);
1230  TimePasses.registerCallbacks(PIC);
1231  OptNone.registerCallbacks(PIC);
1232  OptBisect.registerCallbacks(PIC);
1233  if (FAM)
1234  PreservedCFGChecker.registerCallbacks(PIC, *FAM);
1235  PrintChangedIR.registerCallbacks(PIC);
1236  PseudoProbeVerification.registerCallbacks(PIC);
1237  if (VerifyEach)
1238  Verify.registerCallbacks(PIC);
1239  PrintChangedDiff.registerCallbacks(PIC);
1240 }
1241 
1242 namespace llvm {
1243 
1244 template class ChangeReporter<std::string>;
1245 template class TextChangeReporter<std::string>;
1246 
1247 template class ChangeReporter<ChangedIRData>;
1248 template class TextChangeReporter<ChangedIRData>;
1249 
1250 } // 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:1164
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:1035
llvm::InLineChangePrinter::handleAfter
virtual void handleAfter(StringRef PassID, std::string &Name, const ChangedIRData &Before, const ChangedIRData &After, Any) override
Definition: StandardInstrumentations.cpp:1171
llvm
---------------------— PointerInfo ------------------------------------—
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:1966
Optional.h
intptr_t
llvm::ChangedIRComparer::generateFunctionData
static bool generateFunctionData(ChangedIRData &Data, const Function &F)
Definition: StandardInstrumentations.cpp:691
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:785
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:564
llvm::Function
Definition: Function.h:61
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:490
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:706
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:5775
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:379
llvm::IRChangedPrinter::generateIRRepresentation
void generateIRRepresentation(Any IR, StringRef PassID, std::string &Output) override
Definition: StandardInstrumentations.cpp:538
PIC
PassInstrumentationCallbacks PIC
Definition: PassBuilderBindings.cpp:55
llvm::ChangedBlockData::ChangedBlockData
ChangedBlockData(const BasicBlock &B)
Definition: StandardInstrumentations.cpp:483
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:892
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:967
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
llvm::ChangeReporter::saveIRBeforePass
void saveIRBeforePass(Any IR, StringRef PassID)
Definition: StandardInstrumentations.cpp:405
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:1061
llvm::ChangeReporter::registerRequiredCallbacks
void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:468
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:1226
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:805
llvm::OptNoneInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:827
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:1128
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:1039
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:680
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:672
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:1166
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:699
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:660
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:569
llvm::TextChangeReporter
Definition: StandardInstrumentations.h:233
llvm::ChangeReporter::isInteresting
bool isInteresting(Any IR, StringRef PassID)
Definition: StandardInstrumentations.cpp:396
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
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:1612
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:426
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:1046
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:1053
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:636
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:546
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:858
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:1554
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:136
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:116
VerifyEach
bool VerifyEach
Definition: PassBuilderBindings.cpp:52
llvm::X86AS::SS
@ SS
Definition: X86.h:189
getParent
static const Function * getParent(const Value *V)
Definition: BasicAliasAnalysis.cpp:776
llvm::PseudoProbeVerifier::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: SampleProfileProbe.cpp:88
clEnumValN
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:674
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:1182
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:297
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:1215
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:804
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:424
llvm::InLineChangePrinter::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:1207
llvm::OptBisectInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:848
llvm::AnalysisManager::registerPass
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:847
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:455
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:926
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:384
llvm::IRChangedPrinter::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:532
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:414
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:1187
Debug.h
printBBName
static void printBBName(raw_ostream &out, const BasicBlock *BB)
Definition: StandardInstrumentations.cpp:941
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:5786
llvm::PrintPassInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: StandardInstrumentations.cpp:865
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:1642