// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef LIBSPIRV_OPT_PROPAGATOR_H_
#define LIBSPIRV_OPT_PROPAGATOR_H_

#include <functional>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "ir_context.h"
#include "module.h"

namespace spvtools {
namespace opt {

// Represents a CFG control edge.
struct Edge {
  Edge(ir::BasicBlock* b1, ir::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.");
  }
  ir::BasicBlock* source;
  ir::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());
  }
};

// This class implements a generic value propagation algorithm based on the
// conditional constant propagation algorithm proposed in
//
//      Constant propagation with conditional branches,
//      Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
//
//      A Propagation Engine for GCC
//      Diego Novillo, GCC Summit 2005
//      http://ols.fedoraproject.org/GCC/Reprints-2005/novillo-Reprint.pdf
//
// The purpose of this implementation is to act as a common framework for any
// transformation that needs to propagate values from statements producing new
// values to statements using those values.  Simulation proceeds as follows:
//
// 1- Initially, all edges of the CFG are marked not executable and the CFG
//    worklist is seeded with all the statements in the entry basic block.
//
// 2- Every instruction I is simulated by calling a pass-provided function
//    |visit_fn|. This function is responsible for three things:
//
//    (a) Keep a value table of interesting values.  This table maps SSA IDs to
//        their values.  For instance, when implementing constant propagation,
//        given a store operation 'OpStore %f %int_3', |visit_fn| should assign
//        the value 3 to the table slot for %f.
//
//        In general, |visit_fn| will need to use the value table to replace its
//        operands, fold the result and decide whether a new value needs to be
//        stored in the table. |visit_fn| should only create a new mapping in
//        the value table if all the operands in the instruction are known and
//        present in the value table.
//
//    (b) Return a status indicator to direct the propagator logic.  Once the
//        instruction is simulated, the propagator needs to know whether this
//        instruction produced something interesting.  This is indicated via
//        |visit_fn|'s return value:
//
//         SSAPropagator::kNotInteresting: Instruction I produces nothing of
//             interest and does not affect any of the work lists.  The
//             propagator will visit the statement again if any of its operands
//             produce an interesting value in the future.
//
//             |visit_fn| should always return this value when it is not sure
//             whether the instruction will produce an interesting value in the
//             future or not.  For instance, for constant propagation, an OpIAdd
//             instruction may produce a constant if its two operands are
//             constant, but the first time we visit the instruction, we still
//             may not have its operands in the value table.
//
//         SSAPropagator::kVarying: The value produced by I cannot be determined
//             at compile time.  Further simulation of I is not required.  The
//             propagator will not visit this instruction again.  Additionally,
//             the propagator will add all the instructions at the end of SSA
//             def-use edges to be simulated again.
//
//             If I is a basic block terminator, it will mark all outgoing edges
//             as executable so they are traversed one more time.  Eventually
//             the kVarying attribute will be spread out to all the data and
//             control dependents for I.
//
//             It is important for propagation to use kVarying as a bottom value
//             for the propagation lattice.  It should never be possible for an
//             instruction to return kVarying once and kInteresting on a second
//             visit.  Otherwise, propagation would not stabilize.
//
//         SSAPropagator::kInteresting: Instruction I produces a value that can
//             be computed at compile time.  In this case, |visit_fn| should
//             create a new mapping between I's result ID and the produced
//             value.  Much like the kNotInteresting case, the propagator will
//             visit this instruction again if any of its operands changes.
//             This is useful when the statement changes from one interesting
//             state to another.
//
//    (c) For conditional branches, |visit_fn| may decide which edge to take out
//        of I's basic block.  For example, if the operand for an OpSwitch is
//        known to take a specific constant value, |visit_fn| should figure out
//        the destination basic block and pass it back by setting the second
//        argument to |visit_fn|.
//
//    At the end of propagation, values in the value table are guaranteed to be
//    stable and can be replaced in the IR.
//
// 3- The propagator keeps two work queues.  Instructions are only added to
//    these queues if they produce an interesting or varying value. None of this
//    should be handled by |visit_fn|. The propagator keeps track of this
//    automatically (see SSAPropagator::Simulate for implementation).
//
//      CFG blocks: contains the queue of blocks to be simulated.
//             Blocks are added to this queue if their incoming edges are
//             executable.
//
//      SSA Edges: An SSA edge is a def-use edge between a value-producing
//              instruction and its use instruction.  The SSA edges list
//              contains the statements at the end of a def-use edge that need
//              to be re-visited when an instruction produces a kVarying or
//              kInteresting result.
//
// 4- Simulation terminates when all work queues are drained.
//
//
// EXAMPLE: Basic constant store propagator.
//
// Suppose we want to propagate all constant assignments of the form "OpStore
// %id %cst" where "%id" is some variable and "%cst" an OpConstant.  The
// following code builds a table |values| where every id that was assigned a
// constant value is mapped to the constant value it was assigned.
//
//   auto ctx = spvtools::BuildModule(...);
//   std::map<uint32_t, uint32_t> values;
//   const auto visit_fn = [&ctx, &values](ir::Instruction* instr,
//                                         ir::BasicBlock** dest_bb) {
//     if (instr->opcode() == SpvOpStore) {
//       uint32_t rhs_id = instr->GetSingleWordOperand(1);
//       ir::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 opt::SSAPropagator::kVarying;
//   };
//   opt::SSAPropagator propagator(ctx.get(), &cfg, visit_fn);
//   propagator.Run(&fn);
//
// Given the code:
//
//       %int_4 = OpConstant %int 4
//       %int_3 = OpConstant %int 3
//       %int_1 = OpConstant %int 1
//                OpStore %x %int_4
//                OpStore %y %int_3
//                OpStore %z %int_1
//
// After SSAPropagator::Run returns, the |values| map will contain the entries:
// values[%x] = 4, values[%y] = 3, and, values[%z] = 1.
class SSAPropagator {
 public:
  // Lattice values used for propagation. See class documentation for
  // a description.
  enum PropStatus { kNotInteresting, kInteresting, kVarying };

  using VisitFunction =
      std::function<PropStatus(ir::Instruction*, ir::BasicBlock**)>;

  SSAPropagator(ir::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(ir::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(ir::Instruction* phi, uint32_t i) const;

 private:
  // Initialize processing.
  void Initialize(ir::Function* fn);

  // Simulate the execution |block| by calling |visit_fn_| on every instruction
  // in it.
  bool Simulate(ir::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(ir::Instruction* instr);

  // Returns true if |instr| should be simulated again.
  bool ShouldSimulateAgain(ir::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(ir::Instruction* instr) {
    do_not_simulate_.insert(instr);
  }

  // Returns true if |block| has been simulated already.
  bool BlockHasBeenSimulated(ir::BasicBlock* block) const {
    return simulated_blocks_.find(block) != simulated_blocks_.end();
  }

  // Marks block |block| as simulated.
  void MarkBlockSimulated(ir::BasicBlock* block) {
    simulated_blocks_.insert(block);
  }

  // Marks |edge| as executable.  Returns false if the edge was already marked
  // as executable.
  bool MarkEdgeExecutable(const Edge& edge) {
    return executable_edges_.insert(edge).second;
  }

  // Returns true if |edge| has been marked as executable.
  bool IsEdgeExecutable(const Edge& edge) const {
    return executable_edges_.find(edge) != executable_edges_.end();
  }

  // Returns a pointer to the def-use manager for |ctx_|.
  analysis::DefUseManager* get_def_use_mgr() const {
    return ctx_->get_def_use_mgr();
  }

  // If the CFG edge |e| has not been executed, this function adds |e|'s
  // destination block to the work list.
  void AddControlEdge(const Edge& e);

  // 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.  This also
  // does nothing if the instruction at the end of the def-use is a Phi
  // instruction.  Phi instructions are treated specially because (a) they can
  // be in def-use cycles with other Phi instructions, and (b) they are always
  // executed when a basic block is simulated (see the description of the Sparse
  // Conditional Constant algorithm in the original paper).
  void AddSSAEdges(ir::Instruction* instr, bool traverse_phis = false);

  // IR context to use.
  ir::IRContext* ctx_;

  // Function that visits instructions during simulation. The output of this
  // function is used to determine if the simulated instruction produced a value
  // interesting for propagation. The function is responsible for keeping
  // track of interesting values by storing them in some user-provided map.
  VisitFunction visit_fn_;

  // 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<ir::Instruction*> ssa_edge_uses_;

  // Blocks to simulate.
  std::queue<ir::BasicBlock*> blocks_;

  // Blocks simulated during propagation.
  std::unordered_set<ir::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<ir::Instruction*> do_not_simulate_;

  // Map between a basic block and its predecessor edges.
  // TODO(dnovillo): Move this to ir::CFG and always build them. Alternately,
  // move it to IRContext and build CFG preds/succs on-demand.
  std::unordered_map<ir::BasicBlock*, std::vector<Edge>> bb_preds_;

  // Map between a basic block and its successor edges.
  // TODO(dnovillo): Move this to ir::CFG and always build them. Alternately,
  // move it to IRContext and build CFG preds/succs on-demand.
  std::unordered_map<ir::BasicBlock*, std::vector<Edge>> bb_succs_;

  // Set of executable CFG edges.
  std::set<Edge> executable_edges_;
};

}  // namespace opt
}  // namespace spvtools

#endif  // LIBSPIRV_OPT_PROPAGATOR_H_
