7777#include " llvm/Pass.h"
7878#include " llvm/Support/Casting.h"
7979#include " llvm/Support/ErrorHandling.h"
80+ #include " llvm/Support/ManagedStatic.h"
8081#include " llvm/Support/MathExtras.h"
8182#include " llvm/Support/ModRef.h"
83+ #include " llvm/Support/Mutex.h"
8284#include " llvm/Support/raw_ostream.h"
8385#include " llvm/Target/TargetMachine.h"
8486#include < algorithm>
@@ -93,21 +95,31 @@ using namespace llvm;
9395
9496namespace {
9597
98+ // / Used the by the ReportedErrors class to guarantee only one error is reported
99+ // / at one time.
100+ static ManagedStatic<sys::SmartMutex<true >> ReportedErrorsLock;
101+
96102struct MachineVerifier {
97103 MachineVerifier (MachineFunctionAnalysisManager &MFAM, const char *b,
98- raw_ostream *OS)
99- : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b) {}
104+ raw_ostream *OS, bool AbortOnError = true )
105+ : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b),
106+ ReportedErrs (AbortOnError) {}
100107
101- MachineVerifier (Pass *pass, const char *b, raw_ostream *OS)
102- : PASS(pass), OS(OS ? *OS : nulls()), Banner(b) {}
108+ MachineVerifier (Pass *pass, const char *b, raw_ostream *OS,
109+ bool AbortOnError = true )
110+ : PASS(pass), OS(OS ? *OS : nulls()), Banner(b),
111+ ReportedErrs(AbortOnError) {}
103112
104113 MachineVerifier (const char *b, LiveVariables *LiveVars,
105114 LiveIntervals *LiveInts, LiveStacks *LiveStks,
106- SlotIndexes *Indexes, raw_ostream *OS)
115+ SlotIndexes *Indexes, raw_ostream *OS,
116+ bool AbortOnError = true )
107117 : OS(OS ? *OS : nulls()), Banner(b), LiveVars(LiveVars),
108- LiveInts (LiveInts), LiveStks(LiveStks), Indexes(Indexes) {}
118+ LiveInts(LiveInts), LiveStks(LiveStks), Indexes(Indexes),
119+ ReportedErrs(AbortOnError) {}
109120
110- unsigned verify (const MachineFunction &MF);
121+ // / \returns true if no problems were found.
122+ bool verify (const MachineFunction &MF);
111123
112124 MachineFunctionAnalysisManager *MFAM = nullptr ;
113125 Pass *const PASS = nullptr ;
@@ -120,8 +132,6 @@ struct MachineVerifier {
120132 const MachineRegisterInfo *MRI = nullptr ;
121133 const RegisterBankInfo *RBI = nullptr ;
122134
123- unsigned foundErrors = 0 ;
124-
125135 // Avoid querying the MachineFunctionProperties for each operand.
126136 bool isFunctionRegBankSelected = false ;
127137 bool isFunctionSelected = false ;
@@ -231,6 +241,44 @@ struct MachineVerifier {
231241 LiveStacks *LiveStks = nullptr ;
232242 SlotIndexes *Indexes = nullptr ;
233243
244+ // / A class to track the number of reported error and to guarantee that only
245+ // / one error is reported at one time.
246+ class ReportedErrors {
247+ unsigned NumReported = 0 ;
248+ bool AbortOnError;
249+
250+ public:
251+ // / \param AbortOnError -- If set, abort after printing the first error.
252+ ReportedErrors (bool AbortOnError) : AbortOnError(AbortOnError) {}
253+
254+ ~ReportedErrors () {
255+ if (!hasError ())
256+ return ;
257+ if (AbortOnError)
258+ report_fatal_error (" Found " + Twine (NumReported) +
259+ " machine code errors." );
260+ // Since we haven't aborted, release the lock to allow other threads to
261+ // report errors.
262+ ReportedErrorsLock->unlock ();
263+ }
264+
265+ // / Increment the number of reported errors.
266+ // / \returns true if this is the first reported error.
267+ bool increment () {
268+ // If this is the first error this thread has encountered, grab the lock
269+ // to prevent other threads from reporting errors at the same time.
270+ // Otherwise we assume we already have the lock.
271+ if (!hasError ())
272+ ReportedErrorsLock->lock ();
273+ ++NumReported;
274+ return NumReported == 1 ;
275+ }
276+
277+ // / \returns true if an error was reported.
278+ bool hasError () { return NumReported; }
279+ };
280+ ReportedErrors ReportedErrs;
281+
234282 // This is calculated only when trying to verify convergence control tokens.
235283 // Similar to the LLVM IR verifier, we calculate this locally instead of
236284 // relying on the pass manager.
@@ -337,11 +385,7 @@ struct MachineVerifierLegacyPass : public MachineFunctionPass {
337385 MachineFunctionProperties::Property::FailsVerification))
338386 return false ;
339387
340- unsigned FoundErrors =
341- MachineVerifier (this , Banner.c_str (), &errs ()).verify (MF);
342- if (FoundErrors)
343- report_fatal_error (" Found " + Twine (FoundErrors) +
344- " machine code errors." );
388+ MachineVerifier (this , Banner.c_str (), &errs ()).verify (MF);
345389 return false ;
346390 }
347391};
@@ -357,10 +401,7 @@ MachineVerifierPass::run(MachineFunction &MF,
357401 if (MF.getProperties ().hasProperty (
358402 MachineFunctionProperties::Property::FailsVerification))
359403 return PreservedAnalyses::all ();
360- unsigned FoundErrors =
361- MachineVerifier (MFAM, Banner.c_str (), &errs ()).verify (MF);
362- if (FoundErrors)
363- report_fatal_error (" Found " + Twine (FoundErrors) + " machine code errors." );
404+ MachineVerifier (MFAM, Banner.c_str (), &errs ()).verify (MF);
364405 return PreservedAnalyses::all ();
365406}
366407
@@ -380,31 +421,20 @@ void llvm::verifyMachineFunction(const std::string &Banner,
380421 // LiveIntervals *LiveInts;
381422 // LiveStacks *LiveStks;
382423 // SlotIndexes *Indexes;
383- unsigned FoundErrors =
384- MachineVerifier (nullptr , Banner.c_str (), &errs ()).verify (MF);
385- if (FoundErrors)
386- report_fatal_error (" Found " + Twine (FoundErrors) + " machine code errors." );
424+ MachineVerifier (nullptr , Banner.c_str (), &errs ()).verify (MF);
387425}
388426
389427bool MachineFunction::verify (Pass *p, const char *Banner, raw_ostream *OS,
390- bool AbortOnErrors) const {
391- MachineFunction &MF = const_cast <MachineFunction&>(*this );
392- unsigned FoundErrors = MachineVerifier (p, Banner, OS).verify (MF);
393- if (AbortOnErrors && FoundErrors)
394- report_fatal_error (" Found " +Twine (FoundErrors)+" machine code errors." );
395- return FoundErrors == 0 ;
428+ bool AbortOnError) const {
429+ return MachineVerifier (p, Banner, OS, AbortOnError).verify (*this );
396430}
397431
398432bool MachineFunction::verify (LiveIntervals *LiveInts, SlotIndexes *Indexes,
399433 const char *Banner, raw_ostream *OS,
400- bool AbortOnErrors) const {
401- MachineFunction &MF = const_cast <MachineFunction &>(*this );
402- unsigned FoundErrors =
403- MachineVerifier (Banner, nullptr , LiveInts, nullptr , Indexes, OS)
404- .verify (MF);
405- if (AbortOnErrors && FoundErrors)
406- report_fatal_error (" Found " + Twine (FoundErrors) + " machine code errors." );
407- return FoundErrors == 0 ;
434+ bool AbortOnError) const {
435+ return MachineVerifier (Banner, /* LiveVars=*/ nullptr , LiveInts,
436+ /* LiveStks=*/ nullptr , Indexes, OS, AbortOnError)
437+ .verify (*this );
408438}
409439
410440void MachineVerifier::verifySlotIndexes () const {
@@ -430,9 +460,7 @@ void MachineVerifier::verifyProperties(const MachineFunction &MF) {
430460 report (" Function has NoVRegs property but there are VReg operands" , &MF);
431461}
432462
433- unsigned MachineVerifier::verify (const MachineFunction &MF) {
434- foundErrors = 0 ;
435-
463+ bool MachineVerifier::verify (const MachineFunction &MF) {
436464 this ->MF = &MF;
437465 TM = &MF.getTarget ();
438466 TII = MF.getSubtarget ().getInstrInfo ();
@@ -447,7 +475,7 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
447475 // it's expected that the MIR is somewhat broken but that's ok since we'll
448476 // reset it and clear the FailedISel attribute in ResetMachineFunctions.
449477 if (isFunctionFailedISel)
450- return foundErrors ;
478+ return true ;
451479
452480 isFunctionRegBankSelected = MF.getProperties ().hasProperty (
453481 MachineFunctionProperties::Property::RegBankSelected);
@@ -544,13 +572,13 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
544572 regMasks.clear ();
545573 MBBInfoMap.clear ();
546574
547- return foundErrors ;
575+ return !ReportedErrs. hasError () ;
548576}
549577
550578void MachineVerifier::report (const char *msg, const MachineFunction *MF) {
551579 assert (MF);
552580 OS << ' \n ' ;
553- if (!foundErrors++ ) {
581+ if (ReportedErrs. increment () ) {
554582 if (Banner)
555583 OS << " # " << Banner << ' \n ' ;
556584
0 commit comments