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