3939#define OMPTARGET_SHARED_DEBUG_H
4040
4141#include < atomic>
42+ #include < cstdarg>
4243#include < mutex>
4344#include < string>
4445
@@ -78,17 +79,6 @@ inline std::atomic<uint32_t> &getInfoLevelInternal() {
7879
7980inline uint32_t getInfoLevel () { return getInfoLevelInternal ().load (); }
8081
81- inline uint32_t getDebugLevel () {
82- static uint32_t DebugLevel = 0 ;
83- static std::once_flag Flag{};
84- std::call_once (Flag, []() {
85- if (char *EnvStr = getenv (" LIBOMPTARGET_DEBUG" ))
86- DebugLevel = std::stoi (EnvStr);
87- });
88-
89- return DebugLevel;
90- }
91-
9282#undef USED
9383#undef GCC_VERSION
9484
@@ -147,46 +137,11 @@ inline uint32_t getDebugLevel() {
147137 fprintf (_stdDst, __VA_ARGS__); \
148138 } while (0 )
149139
150- // Debugging messages
151- #ifdef OMPTARGET_DEBUG
152- #include < stdio.h>
153-
154- #define DEBUGP (prefix, ...) \
155- { \
156- fprintf (stderr, " %s --> " , prefix); \
157- fprintf (stderr, __VA_ARGS__); \
158- }
159-
160- // / Emit a message for debugging
161- #define DP (...) \
162- do { \
163- if (getDebugLevel () > 0 ) { \
164- DEBUGP (DEBUG_PREFIX, __VA_ARGS__); \
165- } \
166- } while (false )
167-
168- // / Emit a message for debugging or failure if debugging is disabled
169- #define REPORT (...) \
170- do { \
171- if (getDebugLevel () > 0 ) { \
172- DP (__VA_ARGS__); \
173- } else { \
174- FAILURE_MESSAGE (__VA_ARGS__); \
175- } \
176- } while (false )
177- #else
178- #define DEBUGP (prefix, ...) \
179- {}
180- #define DP (...) \
181- {}
182- #define REPORT (...) FAILURE_MESSAGE(__VA_ARGS__);
183- #endif // OMPTARGET_DEBUG
184-
185140// / Emit a message giving the user extra information about the runtime if
186141#define INFO (_flags, _id, ...) \
187142 do { \
188- if (getDebugLevel () > 0 ) { \
189- DEBUGP (DEBUG_PREFIX, __VA_ARGS__); \
143+ if (:: llvm::offload::debug::isDebugEnabled () ) { \
144+ DP ( __VA_ARGS__); \
190145 } else if (getInfoLevel () & _flags) { \
191146 INFO_MESSAGE (_id, __VA_ARGS__); \
192147 } \
@@ -203,17 +158,92 @@ inline uint32_t getDebugLevel() {
203158
204159namespace llvm ::offload::debug {
205160
206- #ifdef OMPTARGET_DEBUG
161+ // / A raw_ostream that tracks `\n` and print the prefix after each
162+ // / newline. Based on raw_ldbg_ostream from Support/DebugLog.h
163+ class LLVM_ABI odbg_ostream final : public raw_ostream {
164+ public:
165+ enum IfLevel : uint32_t ;
166+ enum OnlyLevel : uint32_t ;
207167
208- struct DebugFilter {
209- StringRef Type;
210- uint32_t Level;
211- };
168+ private:
169+ std::string Prefix;
170+ raw_ostream &Os;
171+ uint32_t BaseLevel;
172+ bool ShouldPrefixNextString;
173+ bool ShouldEmitNewLineOnDestruction;
174+ bool NeedEndNewLine = false ;
212175
213- struct DebugSettings {
214- bool Enabled = false ;
215- uint32_t DefaultLevel = 1 ;
216- llvm::SmallVector<DebugFilter> Filters;
176+ // / If the stream is muted, writes to it are ignored
177+ bool Muted = false ;
178+
179+ // / Split the line on newlines and insert the prefix before each
180+ // / newline. Forward everything to the underlying stream.
181+ void write_impl (const char *Ptr, size_t Size) final {
182+ if (Muted)
183+ return ;
184+
185+ NeedEndNewLine = false ;
186+ auto Str = StringRef (Ptr, Size);
187+ auto Eol = Str.find (' \n ' );
188+ // Handle `\n` occurring in the string, ensure to print the prefix at the
189+ // beginning of each line.
190+ while (Eol != StringRef::npos) {
191+ // Take the line up to the newline (including the newline).
192+ StringRef Line = Str.take_front (Eol + 1 );
193+ if (!Line.empty ())
194+ writeWithPrefix (Line);
195+ // We printed a newline, record here to print a prefix.
196+ ShouldPrefixNextString = true ;
197+ Str = Str.drop_front (Eol + 1 );
198+ Eol = Str.find (' \n ' );
199+ }
200+ if (!Str.empty ()) {
201+ writeWithPrefix (Str);
202+ NeedEndNewLine = true ;
203+ }
204+ }
205+ void emitPrefix () { Os.write (Prefix.c_str (), Prefix.size ()); }
206+ void writeWithPrefix (StringRef Str) {
207+ if (ShouldPrefixNextString) {
208+ emitPrefix ();
209+ ShouldPrefixNextString = false ;
210+ }
211+ Os.write (Str.data (), Str.size ());
212+ }
213+
214+ public:
215+ explicit odbg_ostream (std::string Prefix, raw_ostream &Os, uint32_t BaseLevel,
216+ bool ShouldPrefixNextString = true ,
217+ bool ShouldEmitNewLineOnDestruction = true )
218+ : Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel),
219+ ShouldPrefixNextString(ShouldPrefixNextString),
220+ ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) {
221+ SetUnbuffered ();
222+ }
223+ ~odbg_ostream () final {
224+ if (ShouldEmitNewLineOnDestruction && NeedEndNewLine)
225+ Os << ' \n ' ;
226+ }
227+ odbg_ostream (const odbg_ostream &) = delete ;
228+ odbg_ostream &operator =(const odbg_ostream &) = delete ;
229+ odbg_ostream (odbg_ostream &&other) : Os(other.Os) {
230+ Prefix = std::move (other.Prefix );
231+ BaseLevel = other.BaseLevel ;
232+ ShouldPrefixNextString = other.ShouldPrefixNextString ;
233+ ShouldEmitNewLineOnDestruction = other.ShouldEmitNewLineOnDestruction ;
234+ NeedEndNewLine = other.NeedEndNewLine ;
235+ Muted = other.Muted ;
236+ }
237+
238+ // / Forward the current_pos method to the underlying stream.
239+ uint64_t current_pos () const final { return Os.tell (); }
240+
241+ // / Some of the `<<` operators expect an lvalue, so we trick the type
242+ // / system.
243+ odbg_ostream &asLvalue () { return *this ; }
244+
245+ void shouldMute (const IfLevel Filter) { Muted = Filter > BaseLevel; }
246+ void shouldMute (const OnlyLevel Filter) { Muted = BaseLevel != Filter; }
217247};
218248
219249// / dbgs - Return a circular-buffered debug stream.
@@ -228,6 +258,19 @@ struct DebugSettings {
228258 return thestrm.strm ;
229259}
230260
261+ #ifdef OMPTARGET_DEBUG
262+
263+ struct DebugFilter {
264+ StringRef Type;
265+ uint32_t Level;
266+ };
267+
268+ struct DebugSettings {
269+ bool Enabled = false ;
270+ uint32_t DefaultLevel = 1 ;
271+ llvm::SmallVector<DebugFilter> Filters;
272+ };
273+
231274[[maybe_unused]] static DebugFilter parseDebugFilter (StringRef Filter) {
232275 size_t Pos = Filter.find (' :' );
233276 if (Pos == StringRef::npos)
@@ -309,80 +352,6 @@ shouldPrintDebug(const char *Component, const char *Type, uint32_t &Level) {
309352 return false ;
310353}
311354
312- // / A raw_ostream that tracks `\n` and print the prefix after each
313- // / newline. Based on raw_ldbg_ostream from Support/DebugLog.h
314- class LLVM_ABI odbg_ostream final : public raw_ostream {
315- public:
316- enum IfLevel : uint32_t ;
317- enum OnlyLevel : uint32_t ;
318-
319- private:
320- std::string Prefix;
321- raw_ostream &Os;
322- uint32_t BaseLevel;
323- bool ShouldPrefixNextString;
324- bool ShouldEmitNewLineOnDestruction;
325-
326- // / If the stream is muted, writes to it are ignored
327- bool Muted = false ;
328-
329- // / Split the line on newlines and insert the prefix before each
330- // / newline. Forward everything to the underlying stream.
331- void write_impl (const char *Ptr, size_t Size) final {
332- if (Muted)
333- return ;
334-
335- auto Str = StringRef (Ptr, Size);
336- auto Eol = Str.find (' \n ' );
337- // Handle `\n` occurring in the string, ensure to print the prefix at the
338- // beginning of each line.
339- while (Eol != StringRef::npos) {
340- // Take the line up to the newline (including the newline).
341- StringRef Line = Str.take_front (Eol + 1 );
342- if (!Line.empty ())
343- writeWithPrefix (Line);
344- // We printed a newline, record here to print a prefix.
345- ShouldPrefixNextString = true ;
346- Str = Str.drop_front (Eol + 1 );
347- Eol = Str.find (' \n ' );
348- }
349- if (!Str.empty ())
350- writeWithPrefix (Str);
351- }
352- void emitPrefix () { Os.write (Prefix.c_str (), Prefix.size ()); }
353- void writeWithPrefix (StringRef Str) {
354- if (ShouldPrefixNextString) {
355- emitPrefix ();
356- ShouldPrefixNextString = false ;
357- }
358- Os.write (Str.data (), Str.size ());
359- }
360-
361- public:
362- explicit odbg_ostream (std::string Prefix, raw_ostream &Os, uint32_t BaseLevel,
363- bool ShouldPrefixNextString = true ,
364- bool ShouldEmitNewLineOnDestruction = false )
365- : Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel),
366- ShouldPrefixNextString(ShouldPrefixNextString),
367- ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) {
368- SetUnbuffered ();
369- }
370- ~odbg_ostream () final {
371- if (ShouldEmitNewLineOnDestruction)
372- Os << ' \n ' ;
373- }
374-
375- // / Forward the current_pos method to the underlying stream.
376- uint64_t current_pos () const final { return Os.tell (); }
377-
378- // / Some of the `<<` operators expect an lvalue, so we trick the type
379- // / system.
380- odbg_ostream &asLvalue () { return *this ; }
381-
382- void shouldMute (const IfLevel Filter) { Muted = Filter > BaseLevel; }
383- void shouldMute (const OnlyLevel Filter) { Muted = BaseLevel != Filter; }
384- };
385-
386355// / Compute the prefix for the debug log in the form of:
387356// / "Component --> "
388357[[maybe_unused]] static std::string computePrefix (StringRef Component,
@@ -463,6 +432,8 @@ static inline raw_ostream &operator<<(raw_ostream &Os,
463432
464433#else
465434
435+ inline bool isDebugEnabled () { return false ; }
436+
466437#define ODBG_NULL \
467438 for (bool _c = false ; _c; _c = false ) \
468439 ::llvm::nulls ()
@@ -479,4 +450,94 @@ static inline raw_ostream &operator<<(raw_ostream &Os,
479450
480451} // namespace llvm::offload::debug
481452
453+ namespace llvm ::omp::target::debug {
454+ using namespace llvm ::offload::debug;
455+
456+ enum OmpDebugLevel : uint32_t {
457+ ODL_Default = 1 ,
458+ ODL_Error = ODL_Default,
459+ ODL_Detailed = 2 ,
460+ ODL_Verbose = 3 ,
461+ ODL_VeryVerbose = 4 ,
462+ ODL_Dumping = 5
463+ };
464+
465+ /* Debug types to use in libomptarget */
466+ constexpr const char *ODT_Init = " Init" ;
467+ constexpr const char *ODT_Mapping = " Mapping" ;
468+ constexpr const char *ODT_Kernel = " Kernel" ;
469+ constexpr const char *ODT_DataTransfer = " DataTransfer" ;
470+ constexpr const char *ODT_Sync = " Sync" ;
471+ constexpr const char *ODT_Deinit = " Deinit" ;
472+ constexpr const char *ODT_Error = " Error" ;
473+ constexpr const char *ODT_KernelArgs = " KernelArgs" ;
474+ constexpr const char *ODT_MappingExists = " MappingExists" ;
475+ constexpr const char *ODT_DumpTable = " DumpTable" ;
476+ constexpr const char *ODT_MappingChanged = " MappingChanged" ;
477+ constexpr const char *ODT_PluginKernel = " PluginKernel" ;
478+ constexpr const char *ODT_EmptyMapping = " EmptyMapping" ;
479+
480+ static inline odbg_ostream reportErrorStream () {
481+ #ifdef OMPTARGET_DEBUG
482+ if (::llvm::offload::debug::isDebugEnabled ()) {
483+ uint32_t RealLevel = ODL_Error;
484+ if (::llvm::offload::debug::shouldPrintDebug (GETNAME (TARGET_NAME),
485+ (ODT_Error), RealLevel))
486+ return odbg_ostream{
487+ ::llvm::offload::debug::computePrefix (DEBUG_PREFIX, ODT_Error),
488+ ::llvm::offload::debug::dbgs(), RealLevel};
489+ else
490+ return odbg_ostream{" " , ::llvm::nulls (), 1 };
491+ }
492+ #endif
493+ return odbg_ostream{GETNAME (TARGET_NAME) " error: " ,
494+ ::llvm::offload::debug::dbgs (), ODL_Error};
495+ }
496+
497+ #ifdef OMPTARGET_DEBUG
498+ // Deprecated debug print macros
499+ [[maybe_unused]] static std::string formatToStr (const char *format, ...) {
500+ va_list args;
501+ va_start (args, format);
502+ size_t len = std::vsnprintf (NULL , 0 , format, args);
503+ va_end (args);
504+ llvm::SmallVector<char , 128 > vec (len + 1 );
505+ va_start (args, format);
506+ std::vsnprintf (&vec[0 ], len + 1 , format, args);
507+ va_end (args);
508+ return &vec[0 ];
509+ }
510+
511+ // helper macro to support old DP and REPORT macros with printf syntax
512+ #define FORMAT_TO_STR (Format, ...) \
513+ ::llvm::omp::target::debug::formatToStr (Format __VA_OPT__ (, ) __VA_ARGS__)
514+
515+ #define DP (...) ODBG() << FORMAT_TO_STR(__VA_ARGS__);
516+
517+ #define REPORT_INT_OLD (...) \
518+ do { \
519+ if (::llvm::offload::debug::isDebugEnabled ()) { \
520+ ODBG (::llvm::omp::target::debug::ODT_Error, \
521+ ::llvm::omp::target::debug::ODL_Error) \
522+ << FORMAT_TO_STR (__VA_ARGS__); \
523+ } else { \
524+ FAILURE_MESSAGE (__VA_ARGS__); \
525+ } \
526+ } while (false )
527+
528+ #else
529+ #define DP (...) \
530+ { \
531+ }
532+ #define REPORT_INT_OLD (...) FAILURE_MESSAGE(__VA_ARGS__);
533+ #endif // OMPTARGET_DEBUG
534+
535+ // This is used for the new style REPORT macro
536+ #define REPORT_INT () ::llvm::omp::target::debug::reportErrorStream()
537+
538+ // Make REPORT compatible with old and new syntax
539+ #define REPORT (...) REPORT_INT##__VA_OPT__(_OLD)(__VA_ARGS__)
540+
541+ } // namespace llvm::omp::target::debug
542+
482543#endif // OMPTARGET_SHARED_DEBUG_H
0 commit comments