diff options
Diffstat (limited to 'source/opt/propagator.h')
-rw-r--r-- | source/opt/propagator.h | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/source/opt/propagator.h b/source/opt/propagator.h index 52e7bba7..aef21de4 100644 --- a/source/opt/propagator.h +++ b/source/opt/propagator.h @@ -30,12 +30,12 @@ namespace opt { // Represents a CFG control edge. struct Edge { - Edge(opt::BasicBlock* b1, opt::BasicBlock* b2) : source(b1), dest(b2) { + Edge(BasicBlock* b1, BasicBlock* b2) : source(b1), dest(b2) { assert(source && "CFG edges cannot have a null source block."); assert(dest && "CFG edges cannot have a null destination block."); } - opt::BasicBlock* source; - opt::BasicBlock* dest; + BasicBlock* source; + BasicBlock* dest; bool operator<(const Edge& o) const { return std::make_pair(source->id(), dest->id()) < std::make_pair(o.source->id(), o.dest->id()); @@ -150,20 +150,20 @@ struct Edge { // // auto ctx = BuildModule(...); // std::map<uint32_t, uint32_t> values; -// const auto visit_fn = [&ctx, &values](opt::Instruction* instr, -// opt::BasicBlock** dest_bb) { +// const auto visit_fn = [&ctx, &values](Instruction* instr, +// BasicBlock** dest_bb) { // if (instr->opcode() == SpvOpStore) { // uint32_t rhs_id = instr->GetSingleWordOperand(1); -// opt::Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id); +// Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id); // if (rhs_def->opcode() == SpvOpConstant) { // uint32_t val = rhs_def->GetSingleWordOperand(2); // values[rhs_id] = val; -// return opt::SSAPropagator::kInteresting; +// return SSAPropagator::kInteresting; // } // } -// return opt::SSAPropagator::kVarying; +// return SSAPropagator::kVarying; // }; -// opt::SSAPropagator propagator(ctx.get(), &cfg, visit_fn); +// SSAPropagator propagator(ctx.get(), &cfg, visit_fn); // propagator.Run(&fn); // // Given the code: @@ -183,66 +183,63 @@ class SSAPropagator { // a description. enum PropStatus { kNotInteresting, kInteresting, kVarying }; - using VisitFunction = - std::function<PropStatus(opt::Instruction*, opt::BasicBlock**)>; + using VisitFunction = std::function<PropStatus(Instruction*, BasicBlock**)>; - SSAPropagator(opt::IRContext* context, const VisitFunction& visit_fn) + SSAPropagator(IRContext* context, const VisitFunction& visit_fn) : ctx_(context), visit_fn_(visit_fn) {} // Runs the propagator on function |fn|. Returns true if changes were made to // the function. Otherwise, it returns false. - bool Run(opt::Function* fn); + bool Run(Function* fn); // Returns true if the |i|th argument for |phi| comes through a CFG edge that // has been marked executable. |i| should be an index value accepted by // Instruction::GetSingleWordOperand. - bool IsPhiArgExecutable(opt::Instruction* phi, uint32_t i) const; + bool IsPhiArgExecutable(Instruction* phi, uint32_t i) const; // Returns true if |inst| has a recorded status. This will be true once |inst| // has been simulated once. - bool HasStatus(opt::Instruction* inst) const { return statuses_.count(inst); } + bool HasStatus(Instruction* inst) const { return statuses_.count(inst); } // Returns the current propagation status of |inst|. Assumes // |HasStatus(inst)| returns true. - PropStatus Status(opt::Instruction* inst) const { + PropStatus Status(Instruction* inst) const { return statuses_.find(inst)->second; } // Records the propagation status |status| for |inst|. Returns true if the // status for |inst| has changed or set was set for the first time. - bool SetStatus(opt::Instruction* inst, PropStatus status); + bool SetStatus(Instruction* inst, PropStatus status); private: // Initialize processing. - void Initialize(opt::Function* fn); + void Initialize(Function* fn); // Simulate the execution |block| by calling |visit_fn_| on every instruction // in it. - bool Simulate(opt::BasicBlock* block); + bool Simulate(BasicBlock* block); // Simulate the execution of |instr| by replacing all the known values in // every operand and determining whether the result is interesting for // propagation. This invokes the callback function |visit_fn_| to determine // the value computed by |instr|. - bool Simulate(opt::Instruction* instr); + bool Simulate(Instruction* instr); // Returns true if |instr| should be simulated again. - bool ShouldSimulateAgain(opt::Instruction* instr) const { + bool ShouldSimulateAgain(Instruction* instr) const { return do_not_simulate_.find(instr) == do_not_simulate_.end(); } // Add |instr| to the set of instructions not to simulate again. - void DontSimulateAgain(opt::Instruction* instr) { - do_not_simulate_.insert(instr); - } + void DontSimulateAgain(Instruction* instr) { do_not_simulate_.insert(instr); } // Returns true if |block| has been simulated already. - bool BlockHasBeenSimulated(opt::BasicBlock* block) const { + bool BlockHasBeenSimulated(BasicBlock* block) const { return simulated_blocks_.find(block) != simulated_blocks_.end(); } // Marks block |block| as simulated. - void MarkBlockSimulated(opt::BasicBlock* block) { + void MarkBlockSimulated(BasicBlock* block) { simulated_blocks_.insert(block); } @@ -268,10 +265,10 @@ class SSAPropagator { // Adds all the instructions that use the result of |instr| to the SSA edges // work list. If |instr| produces no result id, this does nothing. - void AddSSAEdges(opt::Instruction* instr); + void AddSSAEdges(Instruction* instr); // IR context to use. - opt::IRContext* ctx_; + IRContext* ctx_; // Function that visits instructions during simulation. The output of this // function is used to determine if the simulated instruction produced a value @@ -281,33 +278,33 @@ class SSAPropagator { // SSA def-use edges to traverse. Each entry is a destination statement for an // SSA def-use edge as returned by |def_use_manager_|. - std::queue<opt::Instruction*> ssa_edge_uses_; + std::queue<Instruction*> ssa_edge_uses_; // Blocks to simulate. - std::queue<opt::BasicBlock*> blocks_; + std::queue<BasicBlock*> blocks_; // Blocks simulated during propagation. - std::unordered_set<opt::BasicBlock*> simulated_blocks_; + std::unordered_set<BasicBlock*> simulated_blocks_; // Set of instructions that should not be simulated again because they have // been found to be in the kVarying state. - std::unordered_set<opt::Instruction*> do_not_simulate_; + std::unordered_set<Instruction*> do_not_simulate_; // Map between a basic block and its predecessor edges. - // TODO(dnovillo): Move this to opt::CFG and always build them. Alternately, + // TODO(dnovillo): Move this to CFG and always build them. Alternately, // move it to IRContext and build CFG preds/succs on-demand. - std::unordered_map<opt::BasicBlock*, std::vector<Edge>> bb_preds_; + std::unordered_map<BasicBlock*, std::vector<Edge>> bb_preds_; // Map between a basic block and its successor edges. - // TODO(dnovillo): Move this to opt::CFG and always build them. Alternately, + // TODO(dnovillo): Move this to CFG and always build them. Alternately, // move it to IRContext and build CFG preds/succs on-demand. - std::unordered_map<opt::BasicBlock*, std::vector<Edge>> bb_succs_; + std::unordered_map<BasicBlock*, std::vector<Edge>> bb_succs_; // Set of executable CFG edges. std::set<Edge> executable_edges_; // Tracks instruction propagation status. - std::unordered_map<opt::Instruction*, SSAPropagator::PropStatus> statuses_; + std::unordered_map<Instruction*, SSAPropagator::PropStatus> statuses_; }; std::ostream& operator<<(std::ostream& str, |