1 | /** |
2 | * Copyright (c) Glow Contributors. See CONTRIBUTORS file. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #ifndef GLOW_SUPPORT_LOG_H |
18 | #define GLOW_SUPPORT_LOG_H |
19 | |
20 | #include "llvm/ADT/StringRef.h" |
21 | |
22 | #include <string> |
23 | #include <vector> |
24 | |
25 | namespace llvm { |
26 | class raw_fd_ostream; |
27 | } |
28 | |
29 | namespace glow { |
30 | |
31 | class Module; |
32 | class Function; |
33 | class Node; |
34 | |
35 | struct NodeValue; |
36 | |
37 | struct LogEvent { |
38 | std::string name; |
39 | LogEvent *parent{nullptr}; |
40 | std::vector<LogEvent *> children; |
41 | |
42 | LogEvent(llvm::StringRef n) : name(n) {} |
43 | |
44 | virtual ~LogEvent() { |
45 | for (auto *c : children) { |
46 | delete c; |
47 | } |
48 | } |
49 | |
50 | void pushEvent(LogEvent *e) { |
51 | e->parent = this; |
52 | children.push_back(e); |
53 | } |
54 | |
55 | /// writes this Event and all children to the provided stream. |
56 | /// \returns true if anything was written. |
57 | virtual bool dump(llvm::raw_fd_ostream &ostream); |
58 | |
59 | virtual bool dumpChildren(llvm::raw_fd_ostream &ostream); |
60 | |
61 | /// \returns true if this even will not log to the stream. |
62 | virtual bool silent() { return false; } |
63 | |
64 | virtual LogEvent *clone(); |
65 | }; |
66 | |
67 | // A special LogEvent for Scope enclosing events. |
68 | struct LogScope : public LogEvent { |
69 | LogScope(llvm::StringRef name) : LogEvent(name) {} |
70 | virtual ~LogScope(){}; |
71 | bool dump(llvm::raw_fd_ostream &ostream) override; |
72 | bool silent() override; |
73 | LogEvent *clone() override; |
74 | }; |
75 | |
76 | struct LogCreate : public LogEvent { |
77 | std::string kindName; |
78 | std::vector<std::string> inputs; |
79 | |
80 | LogCreate(const Node *node); |
81 | LogCreate(llvm::StringRef n, llvm::StringRef k, std::vector<std::string> &i); |
82 | virtual ~LogCreate(){}; |
83 | |
84 | bool dump(llvm::raw_fd_ostream &ostream) override; |
85 | LogEvent *clone() override; |
86 | }; |
87 | |
88 | struct LogDelete : public LogEvent { |
89 | std::string kindName; |
90 | |
91 | LogDelete(const Node *node); |
92 | LogDelete(llvm::StringRef n, llvm::StringRef k); |
93 | virtual ~LogDelete(){}; |
94 | |
95 | bool dump(llvm::raw_fd_ostream &ostream) override; |
96 | LogEvent *clone() override; |
97 | }; |
98 | |
99 | struct LogInputChange : public LogEvent { |
100 | std::string kindName; |
101 | std::string beforeName; |
102 | std::string afterName; |
103 | |
104 | LogInputChange(const Node *user, const NodeValue &before, |
105 | const NodeValue &after); |
106 | LogInputChange(llvm::StringRef n, llvm::StringRef k, llvm::StringRef b, |
107 | llvm::StringRef a); |
108 | |
109 | bool dump(llvm::raw_fd_ostream &ostream) override; |
110 | LogEvent *clone() override; |
111 | }; |
112 | |
113 | /// A class for logging all compilation related activities. |
114 | class LogContext final { |
115 | private: |
116 | LogScope topScope_{"Init" }; |
117 | LogEvent *currentScope_{nullptr}; |
118 | Module *parent_; |
119 | |
120 | public: |
121 | LogContext(Module *parent); |
122 | |
123 | /// Add a new event to the log. |
124 | void pushEvent(LogEvent *ev); |
125 | |
126 | /// Add a new scope. |
127 | void pushLogScope(llvm::StringRef scopeName); |
128 | |
129 | /// Pops out the most recently added scope. |
130 | void popLogScope(); |
131 | |
132 | /// Dumps the log in JSON format into the logfile (configured by command line |
133 | /// option). /p funcName currently unused. |
134 | void dumpLog(llvm::StringRef funcName); |
135 | |
136 | /// Logs the node creation. Also logs into Module log context if \p |
137 | /// logIntoModule set as true. |
138 | void logNodeCreation(const Node &newNode, bool logIntoModule = false); |
139 | |
140 | /// Logs the node deletion. Also logs into Module log context if \p |
141 | /// logIntoModule set as true. |
142 | void logNodeDeletion(const Node &deletedNode, bool logIntoModule = false); |
143 | |
144 | /// Logs node's input changes. |
145 | /// \p user is the user node of the operands |
146 | /// \p prevOpr previous operand |
147 | /// \p newOpr new operand |
148 | void logNodeInputChange(const Node &user, const NodeValue &prevOprVal, |
149 | const NodeValue &newOprVal); |
150 | |
151 | /// Get a deep cloned copy of the top level scope of this LogContext. |
152 | LogEvent *getClonedScope(); |
153 | }; |
154 | |
155 | /// Logs a new log scope. |
156 | #define LOG_SCOPE(ctx, name) ScopedLogBlock __scope__(ctx, name); |
157 | |
158 | /// Helper class which traces the start and end of a compilation log scope. |
159 | class ScopedLogBlock { |
160 | |
161 | /// Reference to the log context. |
162 | std::shared_ptr<LogContext> ctx_; |
163 | |
164 | /// The name of the log scope. |
165 | std::string name_; |
166 | |
167 | /// Whether this log scope has already ended, avoiding logging |
168 | /// it twice. |
169 | bool end_{false}; |
170 | |
171 | public: |
172 | ScopedLogBlock(std::shared_ptr<LogContext> ctx, llvm::StringRef name); |
173 | ~ScopedLogBlock(); |
174 | |
175 | private: |
176 | /// Triggers the endding operation of the current log scope. |
177 | void end(); |
178 | }; |
179 | |
180 | } // namespace glow. |
181 | |
182 | #endif // GLOW_SUPPORT_LOG_H |
183 | |