|
29 | 29 | #ifndef LLVM_PASS_H
|
30 | 30 | #define LLVM_PASS_H
|
31 | 31 |
|
| 32 | +#include <assert.h> |
32 | 33 | #include <string>
|
33 | 34 |
|
34 | 35 | namespace llvm {
|
@@ -82,17 +83,40 @@ class Pass {
|
82 | 83 | AnalysisResolver *Resolver; // Used to resolve analysis
|
83 | 84 | const void *PassID;
|
84 | 85 | PassKind Kind;
|
| 86 | + bool Executed; |
| 87 | + |
85 | 88 | void operator=(const Pass&) = delete;
|
86 | 89 | Pass(const Pass &) = delete;
|
87 | 90 |
|
88 | 91 | public:
|
89 | 92 | explicit Pass(PassKind K, char &pid)
|
90 |
| - : Resolver(nullptr), PassID(&pid), Kind(K) { } |
| 93 | + : Resolver(nullptr), PassID(&pid), Kind(K), Executed(false) { } |
91 | 94 | virtual ~Pass();
|
92 | 95 |
|
93 |
| - |
94 | 96 | PassKind getPassKind() const { return Kind; }
|
95 | 97 |
|
| 98 | + /// Returns true if the pass has already executed. |
| 99 | + /// |
| 100 | + /// For an analysis pass it means the result is available. If the function |
| 101 | + /// returns false, the pass was not run, was skipped or freed. |
| 102 | + /// |
| 103 | + bool isExecuted() const { return Executed; } |
| 104 | + |
| 105 | + /// Marks the pass as executed or not. |
| 106 | + /// |
| 107 | + /// A pass should be marked as executed, if its 'runOn*' method successfully |
| 108 | + /// finished. When the pass is not needed anymore, it is marked as |
| 109 | + /// 'non-executed', it takes place in \c freePass. It also occurs when the |
| 110 | + /// pass is skipped for some reason. |
| 111 | + /// |
| 112 | + /// The flag should be set prior to call to 'runOn*' method. If it decides |
| 113 | + /// that the pass should be skipped, it will reset the flag. |
| 114 | + /// |
| 115 | + void setExecuted(bool x) { |
| 116 | + assert(x || !getAsImmutablePass()); // Immutable pass cannot be invalidated. |
| 117 | + Executed = x; |
| 118 | + } |
| 119 | + |
96 | 120 | /// getPassName - Return a nice clean name for a pass. This usually
|
97 | 121 | /// implemented in terms of the name that is registered by one of the
|
98 | 122 | /// Registration templates, but can be overloaded directly.
|
@@ -279,8 +303,7 @@ class ImmutablePass : public ModulePass {
|
279 | 303 | ///
|
280 | 304 | bool runOnModule(Module &) override { return false; }
|
281 | 305 |
|
282 |
| - explicit ImmutablePass(char &pid) |
283 |
| - : ModulePass(pid) {} |
| 306 | + explicit ImmutablePass(char &pid) : ModulePass(pid) { setExecuted(true); } |
284 | 307 |
|
285 | 308 | // Force out-of-line virtual method.
|
286 | 309 | ~ImmutablePass() override;
|
@@ -316,8 +339,9 @@ class FunctionPass : public Pass {
|
316 | 339 | protected:
|
317 | 340 | /// Optional passes call this function to check whether the pass should be
|
318 | 341 | /// skipped. This is the case when Attribute::OptimizeNone is set or when
|
319 |
| - /// optimization bisect is over the limit. |
320 |
| - bool skipFunction(const Function &F) const; |
| 342 | + /// optimization bisect is over the limit. It also resets flag Executed on |
| 343 | + /// the pass. |
| 344 | + bool skipFunction(const Function &F); |
321 | 345 | };
|
322 | 346 |
|
323 | 347 |
|
|
0 commit comments