// |blk_id|.
ir::BasicBlock* block(uint32_t blk_id) const { return id2block_.at(blk_id); }
- // Return the pseudo entry and exit blocks. TODO(dnovillo): Remove when
- // LocalSingleStoreElimPass::CalculateImmediateDominators() is moved into this
- // class.
+ // Return the pseudo entry and exit blocks.
const ir::BasicBlock* pseudo_entry_block() const {
return &pseudo_entry_block_;
}
block2structured_succs_;
// Extra block whose successors are all blocks with no predecessors
- // in function. TODO(dnovillo): Needed?
+ // in function.
ir::BasicBlock pseudo_entry_block_;
- // Augmented CFG Exit Block. TODO(dnovillo): Needed?
+ // Augmented CFG Exit Block.
ir::BasicBlock pseudo_exit_block_;
// Map from block's label id to its predecessor blocks ids
if (set & kAnalysisDecorations) {
BuildDecorationManager();
}
+ if (set & kAnalysisCFG) {
+ BuildCFG();
+ }
}
void IRContext::InvalidateAnalysesExceptFor(
if (analyses_to_invalidate & kAnalysisCombinators) {
combinator_ops_.clear();
}
+ if (analyses_to_invalidate & kAnalysisCFG) {
+ cfg_.reset(nullptr);
+ }
valid_analyses_ = Analysis(valid_analyses_ & ~analyses_to_invalidate);
}
#ifndef SPIRV_TOOLS_IR_CONTEXT_H
#define SPIRV_TOOLS_IR_CONTEXT_H
+#include "cfg.h"
#include "decoration_manager.h"
#include "def_use_manager.h"
#include "module.h"
// 2. Make sure it gets invalidated or preserved by IRContext methods that add
// or remove IR elements (e.g., KillDef, KillInst, ReplaceAllUsesWith).
//
- // 3. Add handling code in BuildInvalidAnalyses and
- // InvalidateAnalysesExceptFor.
+ // 3. Add handling code in BuildInvalidAnalyses and InvalidateAnalyses
enum Analysis {
kAnalysisNone = 0 << 0,
kAnalysisBegin = 1 << 0,
kAnalysisInstrToBlockMapping = 1 << 1,
kAnalysisDecorations = 1 << 2,
kAnalysisCombinators = 1 << 3,
- kAnalysisEnd = 1 << 4
+ kAnalysisCFG = 1 << 4,
+ kAnalysisEnd = 1 << 5
};
friend inline Analysis operator|(Analysis lhs, Analysis rhs);
}
}
+ // Returns a pointer to the CFG for all the functions in |module_|.
+ ir::CFG* cfg() {
+ if (!AreAnalysesValid(kAnalysisCFG)) {
+ BuildCFG();
+ }
+ return cfg_.get();
+ }
+
private:
// Builds the def-use manager from scratch, even if it was already valid.
void BuildDefUseManager() {
valid_analyses_ = valid_analyses_ | kAnalysisDecorations;
}
+ void BuildCFG() {
+ cfg_.reset(new ir::CFG(module()));
+ valid_analyses_ = valid_analyses_ | kAnalysisCFG;
+ }
+
// Scans a module looking for it capabilities, and initializes combinator_ops_
// accordingly.
void InitializeCombinators();
// Opcodes of shader capability core executable instructions
// without side-effect.
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> combinator_ops_;
+
+ // The CFG for all the functions in |module_|.
+ std::unique_ptr<ir::CFG> cfg_;
};
inline ir::IRContext::Analysis operator|(ir::IRContext::Analysis lhs,
#include <utility>
#include "basic_block.h"
-#include "cfg.h"
#include "def_use_manager.h"
#include "ir_context.h"
#include "module.h"
// Returns a pointer to the current context for this pass.
ir::IRContext* context() const { return context_; }
- // Returns a pointer to the CFG for current module. TODO(dnovillo): This
- // should belong in IRContext.
- ir::CFG* cfg() const { return cfg_.get(); }
+ // Returns a pointer to the CFG for current module.
+ ir::CFG* cfg() const { return context()->cfg(); }
// Add to |todo| all ids of functions called in |func|.
void AddCalls(ir::Function* func, std::queue<uint32_t>* todo);
virtual void InitializeProcessing(ir::IRContext* c) {
context_ = c;
next_id_ = context_->IdBound();
- cfg_.reset(new ir::CFG(get_module()));
}
// Processes the given |module|. Returns Status::Failure if errors occur when
// The context that this pass belongs to.
ir::IRContext* context_;
-
- // The CFG for all the functions in this module.
- std::unique_ptr<ir::CFG> cfg_;
};
} // namespace opt