1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares the different classes involved in low level diagnostics. 11 // 12 // Diagnostics reporting is still done as part of the LLVMContext. 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_DIAGNOSTICINFO_H 16 #define LLVM_IR_DIAGNOSTICINFO_H 17 18 #include "llvm-c/Types.h" 19 #include "llvm/ADT/Optional.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/ADT/Twine.h" 23 #include "llvm/IR/DebugLoc.h" 24 #include "llvm/Support/CBindingWrapping.h" 25 #include "llvm/Support/YAMLTraits.h" 26 #include <algorithm> 27 #include <cstdint> 28 #include <functional> 29 #include <iterator> 30 #include <string> 31 32 namespace llvm { 33 34 // Forward declarations. 35 class DiagnosticPrinter; 36 class Function; 37 class Instruction; 38 class LLVMContext; 39 class Module; 40 class SMDiagnostic; 41 42 /// \brief Defines the different supported severity of a diagnostic. 43 enum DiagnosticSeverity : char { 44 DS_Error, 45 DS_Warning, 46 DS_Remark, 47 // A note attaches additional information to one of the previous diagnostic 48 // types. 49 DS_Note 50 }; 51 52 /// \brief Defines the different supported kind of a diagnostic. 53 /// This enum should be extended with a new ID for each added concrete subclass. 54 enum DiagnosticKind { 55 DK_InlineAsm, 56 DK_ResourceLimit, 57 DK_StackSize, 58 DK_Linker, 59 DK_DebugMetadataVersion, 60 DK_DebugMetadataInvalid, 61 DK_ISelFallback, 62 DK_SampleProfile, 63 DK_OptimizationRemark, 64 DK_OptimizationRemarkMissed, 65 DK_OptimizationRemarkAnalysis, 66 DK_OptimizationRemarkAnalysisFPCommute, 67 DK_OptimizationRemarkAnalysisAliasing, 68 DK_OptimizationFailure, 69 DK_FirstRemark = DK_OptimizationRemark, 70 DK_LastRemark = DK_OptimizationFailure, 71 DK_MachineOptimizationRemark, 72 DK_MachineOptimizationRemarkMissed, 73 DK_MachineOptimizationRemarkAnalysis, 74 DK_FirstMachineRemark = DK_MachineOptimizationRemark, 75 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis, 76 DK_MIRParser, 77 DK_PGOProfile, 78 DK_Unsupported, 79 DK_FirstPluginKind 80 }; 81 82 /// \brief Get the next available kind ID for a plugin diagnostic. 83 /// Each time this function is called, it returns a different number. 84 /// Therefore, a plugin that wants to "identify" its own classes 85 /// with a dynamic identifier, just have to use this method to get a new ID 86 /// and assign it to each of its classes. 87 /// The returned ID will be greater than or equal to DK_FirstPluginKind. 88 /// Thus, the plugin identifiers will not conflict with the 89 /// DiagnosticKind values. 90 int getNextAvailablePluginDiagnosticKind(); 91 92 /// \brief This is the base abstract class for diagnostic reporting in 93 /// the backend. 94 /// The print method must be overloaded by the subclasses to print a 95 /// user-friendly message in the client of the backend (let us call it a 96 /// frontend). 97 class DiagnosticInfo { 98 private: 99 /// Kind defines the kind of report this is about. 100 const /* DiagnosticKind */ int Kind; 101 /// Severity gives the severity of the diagnostic. 102 const DiagnosticSeverity Severity; 103 104 public: 105 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity) 106 : Kind(Kind), Severity(Severity) {} 107 108 virtual ~DiagnosticInfo() = default; 109 110 /* DiagnosticKind */ int getKind() const { return Kind; } 111 DiagnosticSeverity getSeverity() const { return Severity; } 112 113 /// Print using the given \p DP a user-friendly message. 114 /// This is the default message that will be printed to the user. 115 /// It is used when the frontend does not directly take advantage 116 /// of the information contained in fields of the subclasses. 117 /// The printed message must not end with '.' nor start with a severity 118 /// keyword. 119 virtual void print(DiagnosticPrinter &DP) const = 0; 120 }; 121 122 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>; 123 124 /// Diagnostic information for inline asm reporting. 125 /// This is basically a message and an optional location. 126 class DiagnosticInfoInlineAsm : public DiagnosticInfo { 127 private: 128 /// Optional line information. 0 if not set. 129 unsigned LocCookie = 0; 130 /// Message to be reported. 131 const Twine &MsgStr; 132 /// Optional origin of the problem. 133 const Instruction *Instr = nullptr; 134 135 public: 136 /// \p MsgStr is the message to be reported to the frontend. 137 /// This class does not copy \p MsgStr, therefore the reference must be valid 138 /// for the whole life time of the Diagnostic. 139 DiagnosticInfoInlineAsm(const Twine &MsgStr, 140 DiagnosticSeverity Severity = DS_Error) 141 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {} 142 143 /// \p LocCookie if non-zero gives the line number for this report. 144 /// \p MsgStr gives the message. 145 /// This class does not copy \p MsgStr, therefore the reference must be valid 146 /// for the whole life time of the Diagnostic. 147 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr, 148 DiagnosticSeverity Severity = DS_Error) 149 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie), 150 MsgStr(MsgStr) {} 151 152 /// \p Instr gives the original instruction that triggered the diagnostic. 153 /// \p MsgStr gives the message. 154 /// This class does not copy \p MsgStr, therefore the reference must be valid 155 /// for the whole life time of the Diagnostic. 156 /// Same for \p I. 157 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr, 158 DiagnosticSeverity Severity = DS_Error); 159 160 unsigned getLocCookie() const { return LocCookie; } 161 const Twine &getMsgStr() const { return MsgStr; } 162 const Instruction *getInstruction() const { return Instr; } 163 164 /// \see DiagnosticInfo::print. 165 void print(DiagnosticPrinter &DP) const override; 166 167 static bool classof(const DiagnosticInfo *DI) { 168 return DI->getKind() == DK_InlineAsm; 169 } 170 }; 171 172 /// Diagnostic information for stack size etc. reporting. 173 /// This is basically a function and a size. 174 class DiagnosticInfoResourceLimit : public DiagnosticInfo { 175 private: 176 /// The function that is concerned by this resource limit diagnostic. 177 const Function &Fn; 178 179 /// Description of the resource type (e.g. stack size) 180 const char *ResourceName; 181 182 /// The computed size usage 183 uint64_t ResourceSize; 184 185 // Threshould passed 186 uint64_t ResourceLimit; 187 188 public: 189 /// \p The function that is concerned by this stack size diagnostic. 190 /// \p The computed stack size. 191 DiagnosticInfoResourceLimit(const Function &Fn, 192 const char *ResourceName, 193 uint64_t ResourceSize, 194 DiagnosticSeverity Severity = DS_Warning, 195 DiagnosticKind Kind = DK_ResourceLimit, 196 uint64_t ResourceLimit = 0) 197 : DiagnosticInfo(Kind, Severity), 198 Fn(Fn), 199 ResourceName(ResourceName), 200 ResourceSize(ResourceSize), 201 ResourceLimit(ResourceLimit) {} 202 203 const Function &getFunction() const { return Fn; } 204 const char *getResourceName() const { return ResourceName; } 205 uint64_t getResourceSize() const { return ResourceSize; } 206 uint64_t getResourceLimit() const { return ResourceLimit; } 207 208 /// \see DiagnosticInfo::print. 209 void print(DiagnosticPrinter &DP) const override; 210 211 static bool classof(const DiagnosticInfo *DI) { 212 return DI->getKind() == DK_ResourceLimit || 213 DI->getKind() == DK_StackSize; 214 } 215 }; 216 217 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit { 218 public: 219 DiagnosticInfoStackSize(const Function &Fn, 220 uint64_t StackSize, 221 DiagnosticSeverity Severity = DS_Warning, 222 uint64_t StackLimit = 0) 223 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, 224 Severity, DK_StackSize, StackLimit) {} 225 226 uint64_t getStackSize() const { return getResourceSize(); } 227 uint64_t getStackLimit() const { return getResourceLimit(); } 228 229 static bool classof(const DiagnosticInfo *DI) { 230 return DI->getKind() == DK_StackSize; 231 } 232 }; 233 234 /// Diagnostic information for debug metadata version reporting. 235 /// This is basically a module and a version. 236 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo { 237 private: 238 /// The module that is concerned by this debug metadata version diagnostic. 239 const Module &M; 240 /// The actual metadata version. 241 unsigned MetadataVersion; 242 243 public: 244 /// \p The module that is concerned by this debug metadata version diagnostic. 245 /// \p The actual metadata version. 246 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion, 247 DiagnosticSeverity Severity = DS_Warning) 248 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M), 249 MetadataVersion(MetadataVersion) {} 250 251 const Module &getModule() const { return M; } 252 unsigned getMetadataVersion() const { return MetadataVersion; } 253 254 /// \see DiagnosticInfo::print. 255 void print(DiagnosticPrinter &DP) const override; 256 257 static bool classof(const DiagnosticInfo *DI) { 258 return DI->getKind() == DK_DebugMetadataVersion; 259 } 260 }; 261 262 /// Diagnostic information for stripping invalid debug metadata. 263 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo { 264 private: 265 /// The module that is concerned by this debug metadata version diagnostic. 266 const Module &M; 267 268 public: 269 /// \p The module that is concerned by this debug metadata version diagnostic. 270 DiagnosticInfoIgnoringInvalidDebugMetadata( 271 const Module &M, DiagnosticSeverity Severity = DS_Warning) 272 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {} 273 274 const Module &getModule() const { return M; } 275 276 /// \see DiagnosticInfo::print. 277 void print(DiagnosticPrinter &DP) const override; 278 279 static bool classof(const DiagnosticInfo *DI) { 280 return DI->getKind() == DK_DebugMetadataInvalid; 281 } 282 }; 283 284 /// Diagnostic information for the sample profiler. 285 class DiagnosticInfoSampleProfile : public DiagnosticInfo { 286 public: 287 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum, 288 const Twine &Msg, 289 DiagnosticSeverity Severity = DS_Error) 290 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 291 LineNum(LineNum), Msg(Msg) {} 292 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, 293 DiagnosticSeverity Severity = DS_Error) 294 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 295 Msg(Msg) {} 296 DiagnosticInfoSampleProfile(const Twine &Msg, 297 DiagnosticSeverity Severity = DS_Error) 298 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {} 299 300 /// \see DiagnosticInfo::print. 301 void print(DiagnosticPrinter &DP) const override; 302 303 static bool classof(const DiagnosticInfo *DI) { 304 return DI->getKind() == DK_SampleProfile; 305 } 306 307 StringRef getFileName() const { return FileName; } 308 unsigned getLineNum() const { return LineNum; } 309 const Twine &getMsg() const { return Msg; } 310 311 private: 312 /// Name of the input file associated with this diagnostic. 313 StringRef FileName; 314 315 /// Line number where the diagnostic occurred. If 0, no line number will 316 /// be emitted in the message. 317 unsigned LineNum = 0; 318 319 /// Message to report. 320 const Twine &Msg; 321 }; 322 323 /// Diagnostic information for the PGO profiler. 324 class DiagnosticInfoPGOProfile : public DiagnosticInfo { 325 public: 326 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg, 327 DiagnosticSeverity Severity = DS_Error) 328 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {} 329 330 /// \see DiagnosticInfo::print. 331 void print(DiagnosticPrinter &DP) const override; 332 333 static bool classof(const DiagnosticInfo *DI) { 334 return DI->getKind() == DK_PGOProfile; 335 } 336 337 const char *getFileName() const { return FileName; } 338 const Twine &getMsg() const { return Msg; } 339 340 private: 341 /// Name of the input file associated with this diagnostic. 342 const char *FileName; 343 344 /// Message to report. 345 const Twine &Msg; 346 }; 347 348 class DiagnosticLocation { 349 StringRef Filename; 350 unsigned Line = 0; 351 unsigned Column = 0; 352 353 public: 354 DiagnosticLocation() = default; 355 DiagnosticLocation(const DebugLoc &DL); 356 DiagnosticLocation(const DISubprogram *SP); 357 358 bool isValid() const { return !Filename.empty(); } 359 StringRef getFilename() const { return Filename; } 360 unsigned getLine() const { return Line; } 361 unsigned getColumn() const { return Column; } 362 }; 363 364 /// Common features for diagnostics with an associated location. 365 class DiagnosticInfoWithLocationBase : public DiagnosticInfo { 366 public: 367 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 368 /// the location information to use in the diagnostic. 369 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind, 370 enum DiagnosticSeverity Severity, 371 const Function &Fn, 372 const DiagnosticLocation &Loc) 373 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {} 374 375 /// Return true if location information is available for this diagnostic. 376 bool isLocationAvailable() const { return Loc.isValid(); } 377 378 /// Return a string with the location information for this diagnostic 379 /// in the format "file:line:col". If location information is not available, 380 /// it returns "<unknown>:0:0". 381 const std::string getLocationStr() const; 382 383 /// Return location information for this diagnostic in three parts: 384 /// the source file name, line number and column. 385 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const; 386 387 const Function &getFunction() const { return Fn; } 388 DiagnosticLocation getLocation() const { return Loc; } 389 390 private: 391 /// Function where this diagnostic is triggered. 392 const Function &Fn; 393 394 /// Debug location where this diagnostic is triggered. 395 DiagnosticLocation Loc; 396 }; 397 398 /// \brief Common features for diagnostics dealing with optimization remarks 399 /// that are used by both IR and MIR passes. 400 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase { 401 public: 402 /// \brief Used to set IsVerbose via the stream interface. 403 struct setIsVerbose {}; 404 405 /// \brief When an instance of this is inserted into the stream, the arguments 406 /// following will not appear in the remark printed in the compiler output 407 /// (-Rpass) but only in the optimization record file 408 /// (-fsave-optimization-record). 409 struct setExtraArgs {}; 410 411 /// \brief Used in the streaming interface as the general argument type. It 412 /// internally converts everything into a key-value pair. 413 struct Argument { 414 StringRef Key; 415 std::string Val; 416 // If set, the debug location corresponding to the value. 417 DiagnosticLocation Loc; 418 419 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {} 420 Argument(StringRef Key, const Value *V); 421 Argument(StringRef Key, const Type *T); 422 Argument(StringRef Key, int N); 423 Argument(StringRef Key, unsigned N); 424 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {} 425 }; 426 427 /// \p PassName is the name of the pass emitting this diagnostic. \p 428 /// RemarkName is a textual identifier for the remark (single-word, 429 /// camel-case). \p Fn is the function where the diagnostic is being emitted. 430 /// \p Loc is the location information to use in the diagnostic. If line table 431 /// information is available, the diagnostic will include the source code 432 /// location. 433 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, 434 enum DiagnosticSeverity Severity, 435 const char *PassName, StringRef RemarkName, 436 const Function &Fn, 437 const DiagnosticLocation &Loc) 438 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc), 439 PassName(PassName), RemarkName(RemarkName) {} 440 441 DiagnosticInfoOptimizationBase &operator<<(StringRef S); 442 DiagnosticInfoOptimizationBase &operator<<(Argument A); 443 DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V); 444 DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA); 445 446 /// \see DiagnosticInfo::print. 447 void print(DiagnosticPrinter &DP) const override; 448 449 /// Return true if this optimization remark is enabled by one of 450 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed, 451 /// or -pass-remarks-analysis). Note that this only handles the LLVM 452 /// flags. We cannot access Clang flags from here (they are handled 453 /// in BackendConsumer::OptimizationRemarkHandler). 454 virtual bool isEnabled() const = 0; 455 456 StringRef getPassName() const { return PassName; } 457 std::string getMsg() const; 458 Optional<uint64_t> getHotness() const { return Hotness; } 459 void setHotness(Optional<uint64_t> H) { Hotness = H; } 460 461 bool isVerbose() const { return IsVerbose; } 462 463 static bool classof(const DiagnosticInfo *DI) { 464 return (DI->getKind() >= DK_FirstRemark && 465 DI->getKind() <= DK_LastRemark) || 466 (DI->getKind() >= DK_FirstMachineRemark && 467 DI->getKind() <= DK_LastMachineRemark); 468 } 469 470 bool isPassed() const { 471 return (getKind() == DK_OptimizationRemark || 472 getKind() == DK_MachineOptimizationRemark); 473 } 474 475 bool isMissed() const { 476 return (getKind() == DK_OptimizationRemarkMissed || 477 getKind() == DK_MachineOptimizationRemarkMissed); 478 } 479 480 bool isAnalysis() const { 481 return (getKind() == DK_OptimizationRemarkAnalysis || 482 getKind() == DK_MachineOptimizationRemarkAnalysis); 483 } 484 485 protected: 486 /// Name of the pass that triggers this report. If this matches the 487 /// regular expression given in -Rpass=regexp, then the remark will 488 /// be emitted. 489 const char *PassName; 490 491 /// Textual identifier for the remark (single-word, camel-case). Can be used 492 /// by external tools reading the YAML output file for optimization remarks to 493 /// identify the remark. 494 StringRef RemarkName; 495 496 /// If profile information is available, this is the number of times the 497 /// corresponding code was executed in a profile instrumentation run. 498 Optional<uint64_t> Hotness; 499 500 /// Arguments collected via the streaming interface. 501 SmallVector<Argument, 4> Args; 502 503 /// The remark is expected to be noisy. 504 bool IsVerbose = false; 505 506 /// \brief If positive, the index of the first argument that only appear in 507 /// the optimization records and not in the remark printed in the compiler 508 /// output. 509 int FirstExtraArgIndex = -1; 510 511 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>; 512 }; 513 514 /// \brief Common features for diagnostics dealing with optimization remarks 515 /// that are used by IR passes. 516 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { 517 public: 518 /// \p PassName is the name of the pass emitting this diagnostic. \p 519 /// RemarkName is a textual identifier for the remark (single-word, 520 /// camel-case). \p Fn is the function where the diagnostic is being emitted. 521 /// \p Loc is the location information to use in the diagnostic. If line table 522 /// information is available, the diagnostic will include the source code 523 /// location. \p CodeRegion is IR value (currently basic block) that the 524 /// optimization operates on. This is currently used to provide run-time 525 /// hotness information with PGO. 526 DiagnosticInfoIROptimization(enum DiagnosticKind Kind, 527 enum DiagnosticSeverity Severity, 528 const char *PassName, StringRef RemarkName, 529 const Function &Fn, 530 const DiagnosticLocation &Loc, 531 const Value *CodeRegion = nullptr) 532 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn, 533 Loc), 534 CodeRegion(CodeRegion) {} 535 536 /// \brief This is ctor variant allows a pass to build an optimization remark 537 /// from an existing remark. 538 /// 539 /// This is useful when a transformation pass (e.g LV) wants to emit a remark 540 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis 541 /// remark. The string \p Prepend will be emitted before the original 542 /// message. 543 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend, 544 const DiagnosticInfoIROptimization &Orig) 545 : DiagnosticInfoOptimizationBase( 546 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName, 547 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()), 548 CodeRegion(Orig.getCodeRegion()) { 549 *this << Prepend; 550 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args)); 551 } 552 553 /// Legacy interface. 554 /// \p PassName is the name of the pass emitting this diagnostic. 555 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 556 /// the location information to use in the diagnostic. If line table 557 /// information is available, the diagnostic will include the source code 558 /// location. \p Msg is the message to show. Note that this class does not 559 /// copy this message, so this reference must be valid for the whole life time 560 /// of the diagnostic. 561 DiagnosticInfoIROptimization(enum DiagnosticKind Kind, 562 enum DiagnosticSeverity Severity, 563 const char *PassName, const Function &Fn, 564 const DiagnosticLocation &Loc, const Twine &Msg) 565 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) { 566 *this << Msg.str(); 567 } 568 569 const Value *getCodeRegion() const { return CodeRegion; } 570 571 static bool classof(const DiagnosticInfo *DI) { 572 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark; 573 } 574 575 private: 576 /// The IR value (currently basic block) that the optimization operates on. 577 /// This is currently used to provide run-time hotness information with PGO. 578 const Value *CodeRegion; 579 }; 580 581 /// Diagnostic information for applied optimization remarks. 582 class OptimizationRemark : public DiagnosticInfoIROptimization { 583 public: 584 /// \p PassName is the name of the pass emitting this diagnostic. If this name 585 /// matches the regular expression given in -Rpass=, then the diagnostic will 586 /// be emitted. \p RemarkName is a textual identifier for the remark (single- 587 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the 588 /// region that the optimization operates on (currently only block is 589 /// supported). 590 OptimizationRemark(const char *PassName, StringRef RemarkName, 591 const DiagnosticLocation &Loc, const Value *CodeRegion); 592 593 /// Same as above, but the debug location and code region are derived from \p 594 /// Instr. 595 OptimizationRemark(const char *PassName, StringRef RemarkName, 596 const Instruction *Inst); 597 598 /// Same as above, but the debug location and code region are derived from \p 599 /// Func. 600 OptimizationRemark(const char *PassName, StringRef RemarkName, 601 const Function *Func); 602 603 static bool classof(const DiagnosticInfo *DI) { 604 return DI->getKind() == DK_OptimizationRemark; 605 } 606 607 static bool isEnabled(StringRef PassName); 608 609 /// \see DiagnosticInfoOptimizationBase::isEnabled. 610 bool isEnabled() const override { return isEnabled(getPassName()); } 611 612 private: 613 /// This is deprecated now and only used by the function API below. 614 /// \p PassName is the name of the pass emitting this diagnostic. If 615 /// this name matches the regular expression given in -Rpass=, then the 616 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 617 /// is being emitted. \p Loc is the location information to use in the 618 /// diagnostic. If line table information is available, the diagnostic 619 /// will include the source code location. \p Msg is the message to show. 620 /// Note that this class does not copy this message, so this reference 621 /// must be valid for the whole life time of the diagnostic. 622 OptimizationRemark(const char *PassName, const Function &Fn, 623 const DiagnosticLocation &Loc, const Twine &Msg) 624 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, 625 Fn, Loc, Msg) {} 626 627 friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, 628 const Function &Fn, 629 const DiagnosticLocation &Loc, 630 const Twine &Msg); 631 }; 632 633 /// Diagnostic information for missed-optimization remarks. 634 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization { 635 public: 636 /// \p PassName is the name of the pass emitting this diagnostic. If this name 637 /// matches the regular expression given in -Rpass-missed=, then the 638 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 639 /// remark (single-word, camel-case). \p Loc is the debug location and \p 640 /// CodeRegion is the region that the optimization operates on (currently only 641 /// block is supported). 642 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 643 const DiagnosticLocation &Loc, 644 const Value *CodeRegion); 645 646 /// \brief Same as above but \p Inst is used to derive code region and debug 647 /// location. 648 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 649 const Instruction *Inst); 650 651 static bool classof(const DiagnosticInfo *DI) { 652 return DI->getKind() == DK_OptimizationRemarkMissed; 653 } 654 655 static bool isEnabled(StringRef PassName); 656 657 /// \see DiagnosticInfoOptimizationBase::isEnabled. 658 bool isEnabled() const override { return isEnabled(getPassName()); } 659 660 private: 661 /// This is deprecated now and only used by the function API below. 662 /// \p PassName is the name of the pass emitting this diagnostic. If 663 /// this name matches the regular expression given in -Rpass-missed=, then the 664 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 665 /// is being emitted. \p Loc is the location information to use in the 666 /// diagnostic. If line table information is available, the diagnostic 667 /// will include the source code location. \p Msg is the message to show. 668 /// Note that this class does not copy this message, so this reference 669 /// must be valid for the whole life time of the diagnostic. 670 OptimizationRemarkMissed(const char *PassName, const Function &Fn, 671 const DiagnosticLocation &Loc, const Twine &Msg) 672 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, 673 PassName, Fn, Loc, Msg) {} 674 675 friend void emitOptimizationRemarkMissed(LLVMContext &Ctx, 676 const char *PassName, 677 const Function &Fn, 678 const DiagnosticLocation &Loc, 679 const Twine &Msg); 680 }; 681 682 /// Diagnostic information for optimization analysis remarks. 683 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization { 684 public: 685 /// \p PassName is the name of the pass emitting this diagnostic. If this name 686 /// matches the regular expression given in -Rpass-analysis=, then the 687 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 688 /// remark (single-word, camel-case). \p Loc is the debug location and \p 689 /// CodeRegion is the region that the optimization operates on (currently only 690 /// block is supported). 691 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 692 const DiagnosticLocation &Loc, 693 const Value *CodeRegion); 694 695 /// \brief This is ctor variant allows a pass to build an optimization remark 696 /// from an existing remark. 697 /// 698 /// This is useful when a transformation pass (e.g LV) wants to emit a remark 699 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis 700 /// remark. The string \p Prepend will be emitted before the original 701 /// message. 702 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend, 703 const OptimizationRemarkAnalysis &Orig) 704 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {} 705 706 /// \brief Same as above but \p Inst is used to derive code region and debug 707 /// location. 708 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 709 const Instruction *Inst); 710 711 static bool classof(const DiagnosticInfo *DI) { 712 return DI->getKind() == DK_OptimizationRemarkAnalysis; 713 } 714 715 static bool isEnabled(StringRef PassName); 716 717 /// \see DiagnosticInfoOptimizationBase::isEnabled. 718 bool isEnabled() const override { 719 return shouldAlwaysPrint() || isEnabled(getPassName()); 720 } 721 722 static const char *AlwaysPrint; 723 724 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; } 725 726 protected: 727 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, 728 const Function &Fn, const DiagnosticLocation &Loc, 729 const Twine &Msg) 730 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {} 731 732 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, 733 StringRef RemarkName, 734 const DiagnosticLocation &Loc, 735 const Value *CodeRegion); 736 737 private: 738 /// This is deprecated now and only used by the function API below. 739 /// \p PassName is the name of the pass emitting this diagnostic. If 740 /// this name matches the regular expression given in -Rpass-analysis=, then 741 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 742 /// is being emitted. \p Loc is the location information to use in the 743 /// diagnostic. If line table information is available, the diagnostic will 744 /// include the source code location. \p Msg is the message to show. Note that 745 /// this class does not copy this message, so this reference must be valid for 746 /// the whole life time of the diagnostic. 747 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn, 748 const DiagnosticLocation &Loc, const Twine &Msg) 749 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, 750 PassName, Fn, Loc, Msg) {} 751 752 friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, 753 const char *PassName, 754 const Function &Fn, 755 const DiagnosticLocation &Loc, 756 const Twine &Msg); 757 }; 758 759 /// Diagnostic information for optimization analysis remarks related to 760 /// floating-point non-commutativity. 761 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis { 762 public: 763 /// \p PassName is the name of the pass emitting this diagnostic. If this name 764 /// matches the regular expression given in -Rpass-analysis=, then the 765 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 766 /// remark (single-word, camel-case). \p Loc is the debug location and \p 767 /// CodeRegion is the region that the optimization operates on (currently only 768 /// block is supported). The front-end will append its own message related to 769 /// options that address floating-point non-commutativity. 770 OptimizationRemarkAnalysisFPCommute(const char *PassName, 771 StringRef RemarkName, 772 const DiagnosticLocation &Loc, 773 const Value *CodeRegion) 774 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, 775 PassName, RemarkName, Loc, CodeRegion) {} 776 777 static bool classof(const DiagnosticInfo *DI) { 778 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; 779 } 780 781 private: 782 /// This is deprecated now and only used by the function API below. 783 /// \p PassName is the name of the pass emitting this diagnostic. If 784 /// this name matches the regular expression given in -Rpass-analysis=, then 785 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 786 /// is being emitted. \p Loc is the location information to use in the 787 /// diagnostic. If line table information is available, the diagnostic will 788 /// include the source code location. \p Msg is the message to show. The 789 /// front-end will append its own message related to options that address 790 /// floating-point non-commutativity. Note that this class does not copy this 791 /// message, so this reference must be valid for the whole life time of the 792 /// diagnostic. 793 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn, 794 const DiagnosticLocation &Loc, 795 const Twine &Msg) 796 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, 797 PassName, Fn, Loc, Msg) {} 798 799 friend void emitOptimizationRemarkAnalysisFPCommute( 800 LLVMContext &Ctx, const char *PassName, const Function &Fn, 801 const DiagnosticLocation &Loc, const Twine &Msg); 802 }; 803 804 /// Diagnostic information for optimization analysis remarks related to 805 /// pointer aliasing. 806 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis { 807 public: 808 /// \p PassName is the name of the pass emitting this diagnostic. If this name 809 /// matches the regular expression given in -Rpass-analysis=, then the 810 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 811 /// remark (single-word, camel-case). \p Loc is the debug location and \p 812 /// CodeRegion is the region that the optimization operates on (currently only 813 /// block is supported). The front-end will append its own message related to 814 /// options that address pointer aliasing legality. 815 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName, 816 const DiagnosticLocation &Loc, 817 const Value *CodeRegion) 818 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, 819 PassName, RemarkName, Loc, CodeRegion) {} 820 821 static bool classof(const DiagnosticInfo *DI) { 822 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; 823 } 824 825 private: 826 /// This is deprecated now and only used by the function API below. 827 /// \p PassName is the name of the pass emitting this diagnostic. If 828 /// this name matches the regular expression given in -Rpass-analysis=, then 829 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 830 /// is being emitted. \p Loc is the location information to use in the 831 /// diagnostic. If line table information is available, the diagnostic will 832 /// include the source code location. \p Msg is the message to show. The 833 /// front-end will append its own message related to options that address 834 /// pointer aliasing legality. Note that this class does not copy this 835 /// message, so this reference must be valid for the whole life time of the 836 /// diagnostic. 837 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn, 838 const DiagnosticLocation &Loc, 839 const Twine &Msg) 840 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, 841 PassName, Fn, Loc, Msg) {} 842 843 friend void emitOptimizationRemarkAnalysisAliasing( 844 LLVMContext &Ctx, const char *PassName, const Function &Fn, 845 const DiagnosticLocation &Loc, const Twine &Msg); 846 }; 847 848 /// Diagnostic information for machine IR parser. 849 class DiagnosticInfoMIRParser : public DiagnosticInfo { 850 const SMDiagnostic &Diagnostic; 851 852 public: 853 DiagnosticInfoMIRParser(DiagnosticSeverity Severity, 854 const SMDiagnostic &Diagnostic) 855 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {} 856 857 const SMDiagnostic &getDiagnostic() const { return Diagnostic; } 858 859 void print(DiagnosticPrinter &DP) const override; 860 861 static bool classof(const DiagnosticInfo *DI) { 862 return DI->getKind() == DK_MIRParser; 863 } 864 }; 865 866 /// Diagnostic information for ISel fallback path. 867 class DiagnosticInfoISelFallback : public DiagnosticInfo { 868 /// The function that is concerned by this diagnostic. 869 const Function &Fn; 870 871 public: 872 DiagnosticInfoISelFallback(const Function &Fn, 873 DiagnosticSeverity Severity = DS_Warning) 874 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {} 875 876 const Function &getFunction() const { return Fn; } 877 878 void print(DiagnosticPrinter &DP) const override; 879 880 static bool classof(const DiagnosticInfo *DI) { 881 return DI->getKind() == DK_ISelFallback; 882 } 883 }; 884 885 // Create wrappers for C Binding types (see CBindingWrapping.h). 886 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef) 887 888 /// \brief Legacy interface to emit an optimization-applied message. Use 889 /// (Machine)OptimizationRemarkEmitter instead. 890 /// 891 /// \p PassName is the name of the pass emitting the message. If -Rpass= is 892 /// given and \p PassName matches the regular expression in -Rpass, then the 893 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc 894 /// is the debug location where the diagnostic is generated. \p Msg is the 895 /// message string to use. 896 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, 897 const Function &Fn, const DiagnosticLocation &Loc, 898 const Twine &Msg); 899 900 /// \brief Legacy interface to emit an optimization-missed message. Use 901 /// (Machine)OptimizationRemarkEmitter instead. 902 /// 903 /// \p PassName is the name of the pass emitting the message. If -Rpass-missed= 904 /// is given and \p PassName matches the regular expression in -Rpass, then the 905 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc 906 /// is the debug location where the diagnostic is generated. \p Msg is the 907 /// message string to use. 908 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, 909 const Function &Fn, 910 const DiagnosticLocation &Loc, 911 const Twine &Msg); 912 913 /// \brief Legacy interface to emit an optimization analysis remark message. 914 /// Use (Machine)OptimizationRemarkEmitter instead. 915 /// 916 /// \p PassName is the name of the pass emitting the message. If 917 /// -Rpass-analysis= is given and \p PassName matches the regular expression in 918 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering 919 /// the remark, \p Loc is the debug location where the diagnostic is 920 /// generated. \p Msg is the message string to use. 921 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, 922 const Function &Fn, 923 const DiagnosticLocation &Loc, 924 const Twine &Msg); 925 926 /// \brief Legacy interface to emit an optimization analysis remark related to 927 /// messages about floating-point non-commutativity. Use 928 /// (Machine)OptimizationRemarkEmitter instead. 929 /// 930 /// \p PassName is the name of the pass emitting the message. If 931 /// -Rpass-analysis= is given and \p PassName matches the regular expression in 932 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering 933 /// the remark, \p Loc is the debug location where the diagnostic is 934 /// generated. \p Msg is the message string to use. 935 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, 936 const char *PassName, 937 const Function &Fn, 938 const DiagnosticLocation &Loc, 939 const Twine &Msg); 940 941 /// \brief Legacy interface to emit an optimization analysis remark related to 942 /// messages about pointer aliasing. Use (Machine)OptimizationRemarkEmitter 943 /// instead. 944 /// 945 /// \p PassName is the name of the pass emitting the message. 946 /// If -Rpass-analysis= is given and \p PassName matches the regular expression 947 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering 948 /// the remark, \p Loc is the debug location where the diagnostic is generated. 949 /// \p Msg is the message string to use. 950 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, 951 const char *PassName, 952 const Function &Fn, 953 const DiagnosticLocation &Loc, 954 const Twine &Msg); 955 956 /// Diagnostic information for optimization failures. 957 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization { 958 public: 959 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 960 /// the location information to use in the diagnostic. If line table 961 /// information is available, the diagnostic will include the source code 962 /// location. \p Msg is the message to show. Note that this class does not 963 /// copy this message, so this reference must be valid for the whole life time 964 /// of the diagnostic. 965 DiagnosticInfoOptimizationFailure(const Function &Fn, 966 const DiagnosticLocation &Loc, 967 const Twine &Msg) 968 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning, 969 nullptr, Fn, Loc, Msg) {} 970 971 /// \p PassName is the name of the pass emitting this diagnostic. \p 972 /// RemarkName is a textual identifier for the remark (single-word, 973 /// camel-case). \p Loc is the debug location and \p CodeRegion is the 974 /// region that the optimization operates on (currently basic block is 975 /// supported). 976 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName, 977 const DiagnosticLocation &Loc, 978 const Value *CodeRegion); 979 980 static bool classof(const DiagnosticInfo *DI) { 981 return DI->getKind() == DK_OptimizationFailure; 982 } 983 984 /// \see DiagnosticInfoOptimizationBase::isEnabled. 985 bool isEnabled() const override; 986 }; 987 988 /// Diagnostic information for unsupported feature in backend. 989 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase { 990 private: 991 Twine Msg; 992 993 public: 994 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 995 /// the location information to use in the diagnostic. If line table 996 /// information is available, the diagnostic will include the source code 997 /// location. \p Msg is the message to show. Note that this class does not 998 /// copy this message, so this reference must be valid for the whole life time 999 /// of the diagnostic. 1000 DiagnosticInfoUnsupported( 1001 const Function &Fn, const Twine &Msg, 1002 const DiagnosticLocation &Loc = DiagnosticLocation(), 1003 DiagnosticSeverity Severity = DS_Error) 1004 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc), 1005 Msg(Msg) {} 1006 1007 static bool classof(const DiagnosticInfo *DI) { 1008 return DI->getKind() == DK_Unsupported; 1009 } 1010 1011 const Twine &getMessage() const { return Msg; } 1012 1013 void print(DiagnosticPrinter &DP) const override; 1014 }; 1015 1016 } // end namespace llvm 1017 1018 #endif // LLVM_IR_DIAGNOSTICINFO_H 1019