77
77
#include " llvm/Pass.h"
78
78
#include " llvm/Support/Casting.h"
79
79
#include " llvm/Support/ErrorHandling.h"
80
+ #include " llvm/Support/ManagedStatic.h"
80
81
#include " llvm/Support/MathExtras.h"
81
82
#include " llvm/Support/ModRef.h"
83
+ #include " llvm/Support/Mutex.h"
82
84
#include " llvm/Support/raw_ostream.h"
83
85
#include " llvm/Target/TargetMachine.h"
84
86
#include < algorithm>
@@ -93,21 +95,29 @@ using namespace llvm;
93
95
94
96
namespace {
95
97
98
+ static ManagedStatic<sys::SmartMutex<true >> ReportedErrorsLock;
99
+
96
100
struct MachineVerifier {
97
101
MachineVerifier (MachineFunctionAnalysisManager &MFAM, const char *b,
98
- raw_ostream *OS)
99
- : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b) {}
102
+ raw_ostream *OS, bool AbortOnError = true )
103
+ : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b),
104
+ ReportedErrs (AbortOnError) {}
100
105
101
- MachineVerifier (Pass *pass, const char *b, raw_ostream *OS)
102
- : PASS(pass), OS(OS ? *OS : nulls()), Banner(b) {}
106
+ MachineVerifier (Pass *pass, const char *b, raw_ostream *OS,
107
+ bool AbortOnError = true )
108
+ : PASS(pass), OS(OS ? *OS : nulls()), Banner(b),
109
+ ReportedErrs(AbortOnError) {}
103
110
104
111
MachineVerifier (const char *b, LiveVariables *LiveVars,
105
112
LiveIntervals *LiveInts, LiveStacks *LiveStks,
106
- SlotIndexes *Indexes, raw_ostream *OS)
113
+ SlotIndexes *Indexes, raw_ostream *OS,
114
+ bool AbortOnError = true )
107
115
: OS(OS ? *OS : nulls()), Banner(b), LiveVars(LiveVars),
108
- LiveInts (LiveInts), LiveStks(LiveStks), Indexes(Indexes) {}
116
+ LiveInts(LiveInts), LiveStks(LiveStks), Indexes(Indexes),
117
+ ReportedErrs(AbortOnError) {}
109
118
110
- unsigned verify (const MachineFunction &MF);
119
+ // / \returns true if no problems were found.
120
+ bool verify (const MachineFunction &MF);
111
121
112
122
MachineFunctionAnalysisManager *MFAM = nullptr ;
113
123
Pass *const PASS = nullptr ;
@@ -120,8 +130,6 @@ struct MachineVerifier {
120
130
const MachineRegisterInfo *MRI = nullptr ;
121
131
const RegisterBankInfo *RBI = nullptr ;
122
132
123
- unsigned foundErrors = 0 ;
124
-
125
133
// Avoid querying the MachineFunctionProperties for each operand.
126
134
bool isFunctionRegBankSelected = false ;
127
135
bool isFunctionSelected = false ;
@@ -231,6 +239,39 @@ struct MachineVerifier {
231
239
LiveStacks *LiveStks = nullptr ;
232
240
SlotIndexes *Indexes = nullptr ;
233
241
242
+ class ReportedErrors {
243
+ unsigned NumReported = 0 ;
244
+ bool AbortOnError;
245
+
246
+ public:
247
+ ReportedErrors (bool AbortOnError) : AbortOnError(AbortOnError) {}
248
+ ~ReportedErrors () {
249
+ if (!hasError ())
250
+ return ;
251
+ if (AbortOnError)
252
+ report_fatal_error (" Found " + Twine (NumReported) +
253
+ " machine code errors." );
254
+ // Since we haven't aborted, release the lock to allow other threads to
255
+ // report errors.
256
+ ReportedErrorsLock->unlock ();
257
+ }
258
+
259
+ // / Increment the number of reported errors.
260
+ // / \returns true if this is the first reported error.
261
+ bool increment () {
262
+ // If this is the first error this thread has encountered, grab the lock
263
+ // to prevent other threads from reporting errors at the same time.
264
+ // Otherwise we assume we already have the lock.
265
+ if (!hasError ())
266
+ ReportedErrorsLock->lock ();
267
+ ++NumReported;
268
+ return NumReported == 1 ;
269
+ }
270
+
271
+ bool hasError () { return NumReported; }
272
+ };
273
+ ReportedErrors ReportedErrs;
274
+
234
275
// This is calculated only when trying to verify convergence control tokens.
235
276
// Similar to the LLVM IR verifier, we calculate this locally instead of
236
277
// relying on the pass manager.
@@ -337,11 +378,7 @@ struct MachineVerifierLegacyPass : public MachineFunctionPass {
337
378
MachineFunctionProperties::Property::FailsVerification))
338
379
return false ;
339
380
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." );
381
+ MachineVerifier (this , Banner.c_str (), &errs ()).verify (MF);
345
382
return false ;
346
383
}
347
384
};
@@ -357,10 +394,7 @@ MachineVerifierPass::run(MachineFunction &MF,
357
394
if (MF.getProperties ().hasProperty (
358
395
MachineFunctionProperties::Property::FailsVerification))
359
396
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." );
397
+ MachineVerifier (MFAM, Banner.c_str (), &errs ()).verify (MF);
364
398
return PreservedAnalyses::all ();
365
399
}
366
400
@@ -380,31 +414,20 @@ void llvm::verifyMachineFunction(const std::string &Banner,
380
414
// LiveIntervals *LiveInts;
381
415
// LiveStacks *LiveStks;
382
416
// 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." );
417
+ MachineVerifier (nullptr , Banner.c_str (), &errs ()).verify (MF);
387
418
}
388
419
389
420
bool 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 ;
421
+ bool AbortOnError) const {
422
+ return MachineVerifier (p, Banner, OS, AbortOnError).verify (*this );
396
423
}
397
424
398
425
bool MachineFunction::verify (LiveIntervals *LiveInts, SlotIndexes *Indexes,
399
426
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 ;
427
+ bool AbortOnError) const {
428
+ return MachineVerifier (Banner, /* LiveVars=*/ nullptr , LiveInts,
429
+ /* LiveStks=*/ nullptr , Indexes, OS, AbortOnError)
430
+ .verify (*this );
408
431
}
409
432
410
433
void MachineVerifier::verifySlotIndexes () const {
@@ -430,9 +453,7 @@ void MachineVerifier::verifyProperties(const MachineFunction &MF) {
430
453
report (" Function has NoVRegs property but there are VReg operands" , &MF);
431
454
}
432
455
433
- unsigned MachineVerifier::verify (const MachineFunction &MF) {
434
- foundErrors = 0 ;
435
-
456
+ bool MachineVerifier::verify (const MachineFunction &MF) {
436
457
this ->MF = &MF;
437
458
TM = &MF.getTarget ();
438
459
TII = MF.getSubtarget ().getInstrInfo ();
@@ -447,7 +468,7 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
447
468
// it's expected that the MIR is somewhat broken but that's ok since we'll
448
469
// reset it and clear the FailedISel attribute in ResetMachineFunctions.
449
470
if (isFunctionFailedISel)
450
- return foundErrors ;
471
+ return true ;
451
472
452
473
isFunctionRegBankSelected = MF.getProperties ().hasProperty (
453
474
MachineFunctionProperties::Property::RegBankSelected);
@@ -544,13 +565,13 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
544
565
regMasks.clear ();
545
566
MBBInfoMap.clear ();
546
567
547
- return foundErrors ;
568
+ return !ReportedErrs. hasError () ;
548
569
}
549
570
550
571
void MachineVerifier::report (const char *msg, const MachineFunction *MF) {
551
572
assert (MF);
552
573
OS << ' \n ' ;
553
- if (!foundErrors++ ) {
574
+ if (ReportedErrs. increment () ) {
554
575
if (Banner)
555
576
OS << " # " << Banner << ' \n ' ;
556
577
0 commit comments