// 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
  // successful. 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_
