virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
// Called when an ignored pass is encountered.
virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
- // Called to compare the before and after representations of the IR.
- virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
// Stack of IRs before passes.
std::vector<IRUnitT> BeforeStack;
void handleAfter(StringRef PassID, std::string &Name,
const std::string &Before, const std::string &After,
Any) override;
- // Called to compare the before and after representations of the IR.
- bool same(const std::string &Before, const std::string &After) override;
};
-// The following classes hold a representation of the IR for a change
-// reporter that uses string comparisons of the basic blocks
-// that are created using print (ie, similar to dump()).
-// These classes respect the filtering of passes and functions using
-// -filter-passes and -filter-print-funcs.
-//
// Information that needs to be saved for a basic block in order to compare
// before and after the pass to determine if it was changed by a pass.
-class ChangedBlockData {
+template <typename T> class BlockDataT {
public:
- ChangedBlockData(const BasicBlock &B);
-
- bool operator==(const ChangedBlockData &That) const {
- return Body == That.Body;
- }
- bool operator!=(const ChangedBlockData &That) const {
- return Body != That.Body;
+ BlockDataT(const BasicBlock &B) : Label(B.getName().str()), Data(B) {
+ raw_string_ostream SS(Body);
+ B.print(SS, nullptr, true, true);
}
+ bool operator==(const BlockDataT &That) const { return Body == That.Body; }
+ bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
+
// Return the label of the represented basic block.
StringRef getLabel() const { return Label; }
// Return the string representation of the basic block.
StringRef getBody() const { return Body; }
+ // Return the associated data
+ const T &getData() const { return Data; }
+
protected:
std::string Label;
std::string Body;
+
+ // Extra data associated with a basic block
+ T Data;
};
-template <typename IRData> class OrderedChangedData {
+template <typename T> class OrderedChangedData {
public:
// Return the names in the order they were saved
std::vector<std::string> &getOrder() { return Order; }
const std::vector<std::string> &getOrder() const { return Order; }
// Return a map of names to saved representations
- StringMap<IRData> &getData() { return Data; }
- const StringMap<IRData> &getData() const { return Data; }
+ StringMap<T> &getData() { return Data; }
+ const StringMap<T> &getData() const { return Data; }
- bool operator==(const OrderedChangedData<IRData> &That) const {
+ bool operator==(const OrderedChangedData<T> &That) const {
return Data == That.getData();
}
// with ones that are only in \p Before interspersed based on where they
// occur in \p Before. This is used to present the output in an order
// based on how the data is ordered in LLVM.
- static void
- report(const OrderedChangedData &Before, const OrderedChangedData &After,
- function_ref<void(const IRData *, const IRData *)> HandlePair);
+ static void report(const OrderedChangedData &Before,
+ const OrderedChangedData &After,
+ function_ref<void(const T *, const T *)> HandlePair);
protected:
std::vector<std::string> Order;
- StringMap<IRData> Data;
+ StringMap<T> Data;
+};
+
+// Do not need extra information for patch-style change reporter.
+class EmptyData {
+public:
+ EmptyData(const BasicBlock &) {}
};
// The data saved for comparing functions.
-using ChangedFuncData = OrderedChangedData<ChangedBlockData>;
+template <typename T>
+class FuncDataT : public OrderedChangedData<BlockDataT<T>> {};
-// A map of names to the saved data.
-using ChangedIRData = OrderedChangedData<ChangedFuncData>;
+// The data saved for comparing IRs.
+template <typename T>
+class IRDataT : public OrderedChangedData<FuncDataT<T>> {};
-// A class that compares two IRs and does a diff between them. The
-// added lines are prefixed with a '+', the removed lines are prefixed
-// with a '-' and unchanged lines are prefixed with a space (to have
-// things line up).
-class ChangedIRComparer {
+// Abstract template base class for a class that compares two IRs. The
+// class is created with the 2 IRs to compare and then compare is called.
+// The static function analyzeIR is used to build up the IR representation.
+template <typename T> class IRComparer {
public:
- ChangedIRComparer(raw_ostream &OS, const ChangedIRData &Before,
- const ChangedIRData &After, bool ColourMode)
- : Before(Before), After(After), Out(OS), UseColour(ColourMode) {}
+ IRComparer(const IRDataT<T> &Before, const IRDataT<T> &After)
+ : Before(Before), After(After) {}
- // Compare the 2 IRs.
- void compare(Any IR, StringRef Prefix, StringRef PassID, StringRef Name);
+ // Compare the 2 IRs. \p handleFunctionCompare is called to handle the
+ // compare of a function. When \p InModule is set,
+ // this function is being handled as part of comparing a module.
+
+ void compare(
+ bool CompareModule,
+ std::function<void(bool InModule, unsigned Minor,
+ const FuncDataT<T> &Before, const FuncDataT<T> &After)>
+ CompareFunc);
// Analyze \p IR and build the IR representation in \p Data.
- static void analyzeIR(Any IR, ChangedIRData &Data);
+ static void analyzeIR(Any IR, IRDataT<T> &Data);
protected:
- // Return the module when that is the appropriate level of
- // comparison for \p IR.
- static const Module *getModuleForComparison(Any IR);
-
// Generate the data for \p F into \p Data.
- static bool generateFunctionData(ChangedIRData &Data, const Function &F);
-
- // Called to handle the compare of a function. When \p InModule is set,
- // this function is being handled as part of comparing a module.
- void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
- bool InModule, const ChangedFuncData &Before,
- const ChangedFuncData &After);
+ static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
- const ChangedIRData &Before;
- const ChangedIRData &After;
- raw_ostream &Out;
- bool UseColour;
+ const IRDataT<T> &Before;
+ const IRDataT<T> &After;
};
// A change printer that prints out in-line differences in the basic
// and added, respectively. Changes to the IR that do not affect basic
// blocks are not reported as having changed the IR. The option
// -print-module-scope does not affect this change reporter.
-class InLineChangePrinter : public TextChangeReporter<ChangedIRData> {
+class InLineChangePrinter : public TextChangeReporter<IRDataT<EmptyData>> {
public:
InLineChangePrinter(bool VerboseMode, bool ColourMode)
- : TextChangeReporter<ChangedIRData>(VerboseMode), UseColour(ColourMode) {}
+ : TextChangeReporter<IRDataT<EmptyData>>(VerboseMode),
+ UseColour(ColourMode) {}
~InLineChangePrinter() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
protected:
// Create a representation of the IR.
virtual void generateIRRepresentation(Any IR, StringRef PassID,
- ChangedIRData &Output) override;
+ IRDataT<EmptyData> &Output) override;
// Called when an interesting IR has changed.
virtual void handleAfter(StringRef PassID, std::string &Name,
- const ChangedIRData &Before,
- const ChangedIRData &After, Any) override;
- // Called to compare the before and after representations of the IR.
- virtual bool same(const ChangedIRData &Before,
- const ChangedIRData &After) override;
+ const IRDataT<EmptyData> &Before,
+ const IRDataT<EmptyData> &After, Any) override;
+
+ void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
+ StringRef Divider, bool InModule, unsigned Minor,
+ const FuncDataT<EmptyData> &Before,
+ const FuncDataT<EmptyData> &After);
bool UseColour;
};
extern template class ChangeReporter<std::string>;
extern template class TextChangeReporter<std::string>;
-extern template class ChangeReporter<ChangedIRData>;
-extern template class TextChangeReporter<ChangedIRData>;
+extern template class BlockDataT<EmptyData>;
+extern template class FuncDataT<EmptyData>;
+extern template class IRDataT<EmptyData>;
+extern template class ChangeReporter<IRDataT<EmptyData>>;
+extern template class TextChangeReporter<IRDataT<EmptyData>>;
+extern template class IRComparer<EmptyData>;
} // namespace llvm
SmallString<128> ULF =
formatv("--unchanged-line-format={0}", UnchangedLineFormat);
- StringRef Args[] = {"-w", "-d", OLF, NLF, ULF, FileName[0], FileName[1]};
+ StringRef Args[] = {DiffBinary, "-w", "-d", OLF,
+ NLF, ULF, FileName[0], FileName[1]};
Optional<StringRef> Redirects[] = {None, StringRef(FileName[2]), None};
int Result = sys::ExecuteAndWait(*DiffExe, Args, None, Redirects);
if (Result < 0)
"DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass"});
}
+// Return the module when that is the appropriate level of comparison for \p IR.
+const Module *getModuleForComparison(Any IR) {
+ if (any_isa<const Module *>(IR))
+ return any_cast<const Module *>(IR);
+ if (any_isa<const LazyCallGraph::SCC *>(IR))
+ return any_cast<const LazyCallGraph::SCC *>(IR)
+ ->begin()
+ ->getFunction()
+ .getParent();
+ return nullptr;
+}
+
} // namespace
-template <typename IRUnitT>
-ChangeReporter<IRUnitT>::~ChangeReporter<IRUnitT>() {
+template <typename T> ChangeReporter<T>::~ChangeReporter<T>() {
assert(BeforeStack.empty() && "Problem with Change Printer stack.");
}
-template <typename IRUnitT>
-bool ChangeReporter<IRUnitT>::isInterestingFunction(const Function &F) {
+template <typename T>
+bool ChangeReporter<T>::isInterestingFunction(const Function &F) {
return isFunctionInPrintList(F.getName());
}
-template <typename IRUnitT>
-bool ChangeReporter<IRUnitT>::isInterestingPass(StringRef PassID) {
+template <typename T>
+bool ChangeReporter<T>::isInterestingPass(StringRef PassID) {
if (isIgnored(PassID))
return false;
// Return true when this is a pass on IR for which printing
// of changes is desired.
-template <typename IRUnitT>
-bool ChangeReporter<IRUnitT>::isInteresting(Any IR, StringRef PassID) {
+template <typename T>
+bool ChangeReporter<T>::isInteresting(Any IR, StringRef PassID) {
if (!isInterestingPass(PassID))
return false;
if (any_isa<const Function *>(IR))
return true;
}
-template <typename IRUnitT>
-void ChangeReporter<IRUnitT>::saveIRBeforePass(Any IR, StringRef PassID) {
+template <typename T>
+void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID) {
// Always need to place something on the stack because invalidated passes
// are not given the IR so it cannot be determined whether the pass was for
// something that was filtered out.
}
// Save the IR representation on the stack.
- IRUnitT &Data = BeforeStack.back();
+ T &Data = BeforeStack.back();
generateIRRepresentation(IR, PassID, Data);
}
-template <typename IRUnitT>
-void ChangeReporter<IRUnitT>::handleIRAfterPass(Any IR, StringRef PassID) {
+template <typename T>
+void ChangeReporter<T>::handleIRAfterPass(Any IR, StringRef PassID) {
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
std::string Name = getIRName(IR);
handleFiltered(PassID, Name);
} else {
// Get the before rep from the stack
- IRUnitT &Before = BeforeStack.back();
+ T &Before = BeforeStack.back();
// Create the after rep
- IRUnitT After;
+ T After;
generateIRRepresentation(IR, PassID, After);
// Was there a change in IR?
- if (same(Before, After)) {
+ if (Before == After) {
if (VerboseMode)
omitAfter(PassID, Name);
} else
BeforeStack.pop_back();
}
-template <typename IRUnitT>
-void ChangeReporter<IRUnitT>::handleInvalidatedPass(StringRef PassID) {
+template <typename T>
+void ChangeReporter<T>::handleInvalidatedPass(StringRef PassID) {
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
// Always flag it as invalidated as we cannot determine when
BeforeStack.pop_back();
}
-template <typename IRUnitT>
-void ChangeReporter<IRUnitT>::registerRequiredCallbacks(
+template <typename T>
+void ChangeReporter<T>::registerRequiredCallbacks(
PassInstrumentationCallbacks &PIC) {
PIC.registerBeforeNonSkippedPassCallback(
[this](StringRef P, Any IR) { saveIRBeforePass(IR, P); });
});
}
-ChangedBlockData::ChangedBlockData(const BasicBlock &B)
- : Label(B.getName().str()) {
- raw_string_ostream SS(Body);
- B.print(SS, nullptr, true, true);
-}
-
-template <typename IRUnitT>
-TextChangeReporter<IRUnitT>::TextChangeReporter(bool Verbose)
- : ChangeReporter<IRUnitT>(Verbose), Out(dbgs()) {}
+template <typename T>
+TextChangeReporter<T>::TextChangeReporter(bool Verbose)
+ : ChangeReporter<T>(Verbose), Out(dbgs()) {}
-template <typename IRUnitT>
-void TextChangeReporter<IRUnitT>::handleInitialIR(Any IR) {
+template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
// Always print the module.
// Unwrap and print directly to avoid filtering problems in general routines.
auto *M = unwrapModule(IR, /*Force=*/true);
M->print(Out, nullptr);
}
-template <typename IRUnitT>
-void TextChangeReporter<IRUnitT>::omitAfter(StringRef PassID,
- std::string &Name) {
+template <typename T>
+void TextChangeReporter<T>::omitAfter(StringRef PassID, std::string &Name) {
Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
PassID, Name);
}
-template <typename IRUnitT>
-void TextChangeReporter<IRUnitT>::handleInvalidated(StringRef PassID) {
+template <typename T>
+void TextChangeReporter<T>::handleInvalidated(StringRef PassID) {
Out << formatv("*** IR Pass {0} invalidated ***\n", PassID);
}
-template <typename IRUnitT>
-void TextChangeReporter<IRUnitT>::handleFiltered(StringRef PassID,
- std::string &Name) {
+template <typename T>
+void TextChangeReporter<T>::handleFiltered(StringRef PassID,
+ std::string &Name) {
SmallString<20> Banner =
formatv("*** IR Dump After {0} on {1} filtered out ***\n", PassID, Name);
Out << Banner;
}
-template <typename IRUnitT>
-void TextChangeReporter<IRUnitT>::handleIgnored(StringRef PassID,
- std::string &Name) {
+template <typename T>
+void TextChangeReporter<T>::handleIgnored(StringRef PassID, std::string &Name) {
Out << formatv("*** IR Pass {0} on {1} ignored ***\n", PassID, Name);
}
Out << "*** IR Dump After " << PassID << " on " << Name << " ***\n" << After;
}
-bool IRChangedPrinter::same(const std::string &S1, const std::string &S2) {
- return S1 == S2;
-}
-
-template <typename IRData>
-void OrderedChangedData<IRData>::report(
+template <typename T>
+void OrderedChangedData<T>::report(
const OrderedChangedData &Before, const OrderedChangedData &After,
- function_ref<void(const IRData *, const IRData *)> HandlePair) {
+ function_ref<void(const T *, const T *)> HandlePair) {
const auto &BFD = Before.getData();
const auto &AFD = After.getData();
std::vector<std::string>::const_iterator BI = Before.getOrder().begin();
std::vector<std::string>::const_iterator AI = After.getOrder().begin();
std::vector<std::string>::const_iterator AE = After.getOrder().end();
- auto handlePotentiallyRemovedIRData = [&](std::string S) {
+ auto HandlePotentiallyRemovedData = [&](std::string S) {
// The order in LLVM may have changed so check if still exists.
if (!AFD.count(S)) {
// This has been removed.
HandlePair(&BFD.find(*BI)->getValue(), nullptr);
}
};
- auto handleNewIRData = [&](std::vector<const IRData *> &Q) {
+ auto HandleNewData = [&](std::vector<const T *> &Q) {
// Print out any queued up new sections
- for (const IRData *NBI : Q)
+ for (const T *NBI : Q)
HandlePair(nullptr, NBI);
Q.clear();
};
- // Print out the IRData in the after order, with before ones interspersed
+ // Print out the data in the after order, with before ones interspersed
// appropriately (ie, somewhere near where they were in the before list).
// Start at the beginning of both lists. Loop through the
// after list. If an element is common, then advance in the before list
// common, then enqueue it for reporting. When the after list is exhausted,
// loop through the before list, reporting any removed ones. Finally,
// report the rest of the enqueued new ones.
- std::vector<const IRData *> NewIRDataQueue;
+ std::vector<const T *> NewDataQueue;
while (AI != AE) {
if (!BFD.count(*AI)) {
// This section is new so place it in the queue. This will cause it
// to be reported after deleted sections.
- NewIRDataQueue.emplace_back(&AFD.find(*AI)->getValue());
+ NewDataQueue.emplace_back(&AFD.find(*AI)->getValue());
++AI;
continue;
}
// This section is in both; advance and print out any before-only
// until we get to it.
while (*BI != *AI) {
- handlePotentiallyRemovedIRData(*BI);
+ HandlePotentiallyRemovedData(*BI);
++BI;
}
// Report any new sections that were queued up and waiting.
- handleNewIRData(NewIRDataQueue);
+ HandleNewData(NewDataQueue);
- const IRData &AData = AFD.find(*AI)->getValue();
- const IRData &BData = BFD.find(*AI)->getValue();
+ const T &AData = AFD.find(*AI)->getValue();
+ const T &BData = BFD.find(*AI)->getValue();
HandlePair(&BData, &AData);
++BI;
++AI;
// Check any remaining before sections to see if they have been removed
while (BI != BE) {
- handlePotentiallyRemovedIRData(*BI);
+ HandlePotentiallyRemovedData(*BI);
++BI;
}
- handleNewIRData(NewIRDataQueue);
+ HandleNewData(NewDataQueue);
}
-void ChangedIRComparer::compare(Any IR, StringRef Prefix, StringRef PassID,
- StringRef Name) {
- if (!getModuleForComparison(IR)) {
- // Not a module so just handle the single function.
- assert(Before.getData().size() == 1 && "Expected only one function.");
- assert(After.getData().size() == 1 && "Expected only one function.");
- handleFunctionCompare(Name, Prefix, PassID, false,
- Before.getData().begin()->getValue(),
- After.getData().begin()->getValue());
+template <typename T>
+void IRComparer<T>::compare(
+ bool CompareModule,
+ std::function<void(bool InModule, unsigned Minor,
+ const FuncDataT<T> &Before, const FuncDataT<T> &After)>
+ CompareFunc) {
+ if (!CompareModule) {
+ // Just handle the single function.
+ assert(Before.getData().size() == 1 && After.getData().size() == 1 &&
+ "Expected only one function.");
+ CompareFunc(false, 0, Before.getData().begin()->getValue(),
+ After.getData().begin()->getValue());
return;
}
- ChangedIRData::report(
- Before, After, [&](const ChangedFuncData *B, const ChangedFuncData *A) {
- assert((B || A) && "Both functions cannot be missing.");
- ChangedFuncData Missing;
- if (!B)
- B = &Missing;
- else if (!A)
- A = &Missing;
- handleFunctionCompare(Name, Prefix, PassID, true, *B, *A);
- });
+ unsigned Minor = 0;
+ FuncDataT<T> Missing;
+ IRDataT<T>::report(Before, After,
+ [&](const FuncDataT<T> *B, const FuncDataT<T> *A) {
+ assert((B || A) && "Both functions cannot be missing.");
+ if (!B)
+ B = &Missing;
+ else if (!A)
+ A = &Missing;
+ CompareFunc(true, Minor++, *B, *A);
+ });
}
-void ChangedIRComparer::analyzeIR(Any IR, ChangedIRData &Data) {
+template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
if (const Module *M = getModuleForComparison(IR)) {
// Create data for each existing/interesting function in the module.
for (const Function &F : *M)
generateFunctionData(Data, *F);
}
-const Module *ChangedIRComparer::getModuleForComparison(Any IR) {
- if (any_isa<const Module *>(IR))
- return any_cast<const Module *>(IR);
- if (any_isa<const LazyCallGraph::SCC *>(IR))
- return any_cast<const LazyCallGraph::SCC *>(IR)
- ->begin()
- ->getFunction()
- .getParent();
- return nullptr;
-}
-
-bool ChangedIRComparer::generateFunctionData(ChangedIRData &Data,
- const Function &F) {
+template <typename T>
+bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const Function &F) {
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
- ChangedFuncData CFD;
+ FuncDataT<T> FD;
for (const auto &B : F) {
- CFD.getOrder().emplace_back(B.getName());
- CFD.getData().insert({B.getName(), B});
+ FD.getOrder().emplace_back(B.getName());
+ FD.getData().insert({B.getName(), B});
}
Data.getOrder().emplace_back(F.getName());
- Data.getData().insert({F.getName(), CFD});
+ Data.getData().insert({F.getName(), FD});
return true;
}
return false;
return true;
StringRef PassName = PIC->getPassNameForClassName(PassID);
- return llvm::is_contained(printBeforePasses(), PassName);
+ return is_contained(printBeforePasses(), PassName);
}
bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) {
return true;
StringRef PassName = PIC->getPassNameForClassName(PassID);
- return llvm::is_contained(printAfterPasses(), PassName);
+ return is_contained(printAfterPasses(), PassName);
}
void PrintIRInstrumentation::registerCallbacks(
SpecialPasses.emplace_back("PassAdaptor");
}
- PIC.registerBeforeSkippedPassCallback(
- [this, SpecialPasses](StringRef PassID, Any IR) {
- assert(!isSpecialPass(PassID, SpecialPasses) &&
- "Unexpectedly skipping special pass");
+ PIC.registerBeforeSkippedPassCallback([this, SpecialPasses](StringRef PassID,
+ Any IR) {
+ assert(!isSpecialPass(PassID, SpecialPasses) &&
+ "Unexpectedly skipping special pass");
- print() << "Skipping pass: " << PassID << " on " << getIRName(IR)
- << "\n";
- });
+ print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";
+ });
PIC.registerBeforeNonSkippedPassCallback([this, SpecialPasses](
StringRef PassID, Any IR) {
if (isSpecialPass(PassID, SpecialPasses))
report_fatal_error(Twine("CFG unexpectedly changed by ", Pass));
};
- PIC.registerBeforeNonSkippedPassCallback(
- [this, &FAM](StringRef P, Any IR) {
+ PIC.registerBeforeNonSkippedPassCallback([this, &FAM](StringRef P, Any IR) {
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
- assert(&PassStack.emplace_back(P));
+ assert(&PassStack.emplace_back(P));
#endif
- (void)this;
- if (!any_isa<const Function *>(IR))
- return;
+ (void)this;
+ if (!any_isa<const Function *>(IR))
+ return;
- const auto *F = any_cast<const Function *>(IR);
- // Make sure a fresh CFG snapshot is available before the pass.
- FAM.getResult<PreservedCFGCheckerAnalysis>(*const_cast<Function *>(F));
- });
+ const auto *F = any_cast<const Function *>(IR);
+ // Make sure a fresh CFG snapshot is available before the pass.
+ FAM.getResult<PreservedCFGCheckerAnalysis>(*const_cast<Function *>(F));
+ });
PIC.registerAfterPassInvalidatedCallback(
[this](StringRef P, const PreservedAnalyses &PassPA) {
InLineChangePrinter::~InLineChangePrinter() {}
void InLineChangePrinter::generateIRRepresentation(Any IR, StringRef PassID,
- ChangedIRData &D) {
- ChangedIRComparer::analyzeIR(IR, D);
+ IRDataT<EmptyData> &D) {
+ IRComparer<EmptyData>::analyzeIR(IR, D);
}
void InLineChangePrinter::handleAfter(StringRef PassID, std::string &Name,
- const ChangedIRData &Before,
- const ChangedIRData &After, Any IR) {
+ const IRDataT<EmptyData> &Before,
+ const IRDataT<EmptyData> &After, Any IR) {
SmallString<20> Banner =
formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
Out << Banner;
- ChangedIRComparer(Out, Before, After, UseColour)
- .compare(IR, "", PassID, Name);
+ IRComparer<EmptyData>(Before, After)
+ .compare(getModuleForComparison(IR),
+ [&](bool InModule, unsigned Minor,
+ const FuncDataT<EmptyData> &Before,
+ const FuncDataT<EmptyData> &After) -> void {
+ handleFunctionCompare(Name, "", PassID, " on ", InModule,
+ Minor, Before, After);
+ });
Out << "\n";
}
-bool InLineChangePrinter::same(const ChangedIRData &D1,
- const ChangedIRData &D2) {
- return D1 == D2;
-}
-
-void ChangedIRComparer::handleFunctionCompare(StringRef Name, StringRef Prefix,
- StringRef PassID, bool InModule,
- const ChangedFuncData &Before,
- const ChangedFuncData &After) {
+void InLineChangePrinter::handleFunctionCompare(
+ StringRef Name, StringRef Prefix, StringRef PassID, StringRef Divider,
+ bool InModule, unsigned Minor, const FuncDataT<EmptyData> &Before,
+ const FuncDataT<EmptyData> &After) {
// Print a banner when this is being shown in the context of a module
if (InModule)
Out << "\n*** IR for function " << Name << " ***\n";
- ChangedFuncData::report(
- Before, After, [&](const ChangedBlockData *B, const ChangedBlockData *A) {
+ FuncDataT<EmptyData>::report(
+ Before, After,
+ [&](const BlockDataT<EmptyData> *B, const BlockDataT<EmptyData> *A) {
StringRef BStr = B ? B->getBody() : "\n";
StringRef AStr = A ? A->getBody() : "\n";
const std::string Removed =
PrintChanged == ChangePrinter::PrintChangedDiffQuiet ||
PrintChanged == ChangePrinter::PrintChangedColourDiffVerbose ||
PrintChanged == ChangePrinter::PrintChangedColourDiffQuiet)
- TextChangeReporter<ChangedIRData>::registerRequiredCallbacks(PIC);
+ TextChangeReporter<IRDataT<EmptyData>>::registerRequiredCallbacks(PIC);
}
+namespace llvm {
+
StandardInstrumentations::StandardInstrumentations(
bool DebugLogging, bool VerifyEach, PrintPassOptions PrintPassOpts)
: PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
PrintChangedDiff.registerCallbacks(PIC);
}
-namespace llvm {
-
template class ChangeReporter<std::string>;
template class TextChangeReporter<std::string>;
-template class ChangeReporter<ChangedIRData>;
-template class TextChangeReporter<ChangedIRData>;
+template class BlockDataT<EmptyData>;
+template class FuncDataT<EmptyData>;
+template class IRDataT<EmptyData>;
+template class ChangeReporter<IRDataT<EmptyData>>;
+template class TextChangeReporter<IRDataT<EmptyData>>;
+template class IRComparer<EmptyData>;
} // namespace llvm