//===- PtrState.h - ARC State for a Ptr -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file contains declarations for the ARC state associated with a ptr. It
//  is only used by the ARC Sequence Dataflow computation. By separating this
//  from the actual dataflow, it is easier to consider the mechanics of the ARC
//  optimization separate from the actual predicates being used.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H

#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/Support/Compiler.h"

namespace llvm {

class BasicBlock;
class Instruction;
class MDNode;
class raw_ostream;
class Value;

namespace objcarc {

class ARCMDKindCache;
class BundledRetainClaimRVs;
class ProvenanceAnalysis;

/// \enum Sequence
///
/// A sequence of states that a pointer may go through in which an
/// objc_retain and objc_release are actually needed.
enum Sequence {
  S_None,
  S_Retain,        ///< objc_retain(x).
  S_CanRelease,    ///< foo(x) -- x could possibly see a ref count decrement.
  S_Use,           ///< any use of x.
  S_Stop,          ///< code motion is stopped.
  S_MovableRelease ///< objc_release(x), !clang.imprecise_release.
};

raw_ostream &operator<<(raw_ostream &OS,
                        const Sequence S) LLVM_ATTRIBUTE_UNUSED;

/// Unidirectional information about either a
/// retain-decrement-use-release sequence or release-use-decrement-retain
/// reverse sequence.
struct RRInfo {
  /// After an objc_retain, the reference count of the referenced
  /// object is known to be positive. Similarly, before an objc_release, the
  /// reference count of the referenced object is known to be positive. If
  /// there are retain-release pairs in code regions where the retain count
  /// is known to be positive, they can be eliminated, regardless of any side
  /// effects between them.
  ///
  /// Also, a retain+release pair nested within another retain+release
  /// pair all on the known same pointer value can be eliminated, regardless
  /// of any intervening side effects.
  ///
  /// KnownSafe is true when either of these conditions is satisfied.
  bool KnownSafe = false;

  /// True of the objc_release calls are all marked with the "tail" keyword.
  bool IsTailCallRelease = false;

  /// If the Calls are objc_release calls and they all have a
  /// clang.imprecise_release tag, this is the metadata tag.
  MDNode *ReleaseMetadata = nullptr;

  /// For a top-down sequence, the set of objc_retains or
  /// objc_retainBlocks. For bottom-up, the set of objc_releases.
  SmallPtrSet<Instruction *, 2> Calls;

  /// The set of optimal insert positions for moving calls in the opposite
  /// sequence.
  SmallPtrSet<Instruction *, 2> ReverseInsertPts;

  /// If this is true, we cannot perform code motion but can still remove
  /// retain/release pairs.
  bool CFGHazardAfflicted = false;

  RRInfo() = default;

  void clear();

  /// Conservatively merge the two RRInfo. Returns true if a partial merge has
  /// occurred, false otherwise.
  bool Merge(const RRInfo &Other);
};

/// This class summarizes several per-pointer runtime properties which
/// are propagated through the flow graph.
class PtrState {
protected:
  /// True if the reference count is known to be incremented.
  bool KnownPositiveRefCount = false;

  /// True if we've seen an opportunity for partial RR elimination, such as
  /// pushing calls into a CFG triangle or into one side of a CFG diamond.
  bool Partial = false;

  /// The current position in the sequence.
  unsigned char Seq : 8;

  /// Unidirectional information about the current sequence.
  RRInfo RRI;

  PtrState() : Seq(S_None) {}

public:
  bool IsKnownSafe() const { return RRI.KnownSafe; }

  void SetKnownSafe(const bool NewValue) { RRI.KnownSafe = NewValue; }

  bool IsTailCallRelease() const { return RRI.IsTailCallRelease; }

  void SetTailCallRelease(const bool NewValue) {
    RRI.IsTailCallRelease = NewValue;
  }

  bool IsTrackingImpreciseReleases() const {
    return RRI.ReleaseMetadata != nullptr;
  }

  const MDNode *GetReleaseMetadata() const { return RRI.ReleaseMetadata; }

  void SetReleaseMetadata(MDNode *NewValue) { RRI.ReleaseMetadata = NewValue; }

  bool IsCFGHazardAfflicted() const { return RRI.CFGHazardAfflicted; }

  void SetCFGHazardAfflicted(const bool NewValue) {
    RRI.CFGHazardAfflicted = NewValue;
  }

  void SetKnownPositiveRefCount();
  void ClearKnownPositiveRefCount();

  bool HasKnownPositiveRefCount() const { return KnownPositiveRefCount; }

  void SetSeq(Sequence NewSeq);

  Sequence GetSeq() const { return static_cast<Sequence>(Seq); }

  void ClearSequenceProgress() { ResetSequenceProgress(S_None); }

  void ResetSequenceProgress(Sequence NewSeq);
  void Merge(const PtrState &Other, bool TopDown);

  void InsertCall(Instruction *I) { RRI.Calls.insert(I); }

  void InsertReverseInsertPt(Instruction *I) { RRI.ReverseInsertPts.insert(I); }

  void ClearReverseInsertPts() { RRI.ReverseInsertPts.clear(); }

  bool HasReverseInsertPts() const { return !RRI.ReverseInsertPts.empty(); }

  const RRInfo &GetRRInfo() const { return RRI; }
};

struct BottomUpPtrState : PtrState {
  BottomUpPtrState() = default;

  /// (Re-)Initialize this bottom up pointer returning true if we detected a
  /// pointer with nested releases.
  bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I);

  /// Return true if this set of releases can be paired with a release. Modifies
  /// state appropriately to reflect that the matching occurred if it is
  /// successful.
  ///
  /// It is assumed that one has already checked that the RCIdentity of the
  /// retain and the RCIdentity of this ptr state are the same.
  bool MatchWithRetain();

  void HandlePotentialUse(BasicBlock *BB, Instruction *Inst, const Value *Ptr,
                          ProvenanceAnalysis &PA, ARCInstKind Class);
  bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr,
                                    ProvenanceAnalysis &PA, ARCInstKind Class);
};

struct TopDownPtrState : PtrState {
  TopDownPtrState() = default;

  /// (Re-)Initialize this bottom up pointer returning true if we detected a
  /// pointer with nested releases.
  bool InitTopDown(ARCInstKind Kind, Instruction *I);

  /// Return true if this set of retains can be paired with the given
  /// release. Modifies state appropriately to reflect that the matching
  /// occurred.
  bool MatchWithRelease(ARCMDKindCache &Cache, Instruction *Release);

  void HandlePotentialUse(Instruction *Inst, const Value *Ptr,
                          ProvenanceAnalysis &PA, ARCInstKind Class);

  bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr,
                                    ProvenanceAnalysis &PA, ARCInstKind Class,
                                    const BundledRetainClaimRVs &BundledRVs);
};

} // end namespace objcarc

} // end namespace llvm

#endif // LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
