// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
#define RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"

namespace dart {

// Sparse conditional constant propagation and unreachable code elimination.
// Assumes that use lists are computed and preserves them.
class ConstantPropagator : public FlowGraphVisitor {
 public:
  ConstantPropagator(FlowGraph* graph,
                     const GrowableArray<BlockEntryInstr*>& ignored);

  static void Optimize(FlowGraph* graph);

  // (1) Visit branches to optimize away unreachable blocks discovered  by range
  // analysis.
  // (2) Eliminate branches that have the same true- and false-target: For
  // example, this occurs after expressions like
  //
  // if (a == null || b == null) {
  //   ...
  // }
  //
  // where b is known to be null.
  static void OptimizeBranches(FlowGraph* graph);

  // Used to initialize the abstract value of definitions.
  static ObjectPtr Unknown() { return Object::unknown_constant().ptr(); }

 private:
  void Analyze();
  void Transform();
  // Tries to replace uses of [defn] with a constant, returns true if
  // successfull. The [value] is used as a temporary handle.
  bool TransformDefinition(Definition* defn);
  void EliminateRedundantBranches();

  void SetReachable(BlockEntryInstr* block);
  bool SetValue(Definition* definition, const Object& value);

  // Phi might be viewed as redundant based on current reachability of
  // predecessor blocks (i.e. the same definition is flowing from all
  // reachable predecessors). We can use this information to constant
  // fold phi(x) == x and phi(x) != x comparisons.
  Definition* UnwrapPhi(Definition* defn);
  void MarkUnwrappedPhi(Definition* defn);

  // Assign the join (least upper bound) of a pair of abstract values to the
  // first one.
  void Join(Object* left, const Object& right);

  bool IsUnknown(const Object& value) { return value.ptr() == unknown_.ptr(); }
  bool IsNonConstant(const Object& value) {
    return value.ptr() == non_constant_.ptr();
  }
  bool IsConstant(const Object& value) {
    return !IsNonConstant(value) && !IsUnknown(value);
  }

  void VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op);
  void VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op);

  virtual void VisitBlocks() { UNREACHABLE(); }

#define DECLARE_VISIT(type, attrs) virtual void Visit##type(type##Instr* instr);
  FOR_EACH_INSTRUCTION(DECLARE_VISIT)

#undef DECLARE_VISIT
  // Structure tracking visit counts for phis. Used to detect infinite loops.
  struct PhiInfo {
    PhiInstr* phi;
    intptr_t visit_count;
  };

  // Returns PhiInfo associated with the given phi. Note that this
  // pointer can be invalidated by subsequent call to GetPhiInfo and
  // thus should not be stored anywhere.
  PhiInfo* GetPhiInfo(PhiInstr* phi);

  FlowGraph* graph_;

  // Sentinels for unknown constant and non-constant values.
  const Object& unknown_;
  const Object& non_constant_;

  // Temporary handle used in [TransformDefinition].
  Object& constant_value_;

  // Analysis results. For each block, a reachability bit.  Indexed by
  // preorder number.
  BitVector* reachable_;

  // Bitvector of phis that were "unwrapped" into one of their inputs
  // when visiting one of their uses. These uses of these phis
  // should be revisited if reachability of the predecessor blocks
  // changes even if that does not change constant value of the phi.
  BitVector* unwrapped_phis_;

  // List of visited phis indexed by their id (stored as pass specific id on
  // a phi instruction).
  GrowableArray<PhiInfo> phis_;

  // Worklists of blocks and definitions.
  GrowableArray<BlockEntryInstr*> block_worklist_;
  DefinitionWorklist definition_worklist_;
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
