//===- GlobalStatus.h - Compute status info for globals ---------*- 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
 
//
 
//===----------------------------------------------------------------------===//
 
 
 
#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
 
#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
 
 
 
#include "llvm/IR/Instructions.h"
 
#include "llvm/Support/AtomicOrdering.h"
 
 
 
namespace llvm {
 
 
 
class Constant;
 
class Function;
 
class Value;
 
 
 
/// It is safe to destroy a constant iff it is only used by constants itself.
 
/// Note that constants cannot be cyclic, so this test is pretty easy to
 
/// implement recursively.
 
///
 
bool isSafeToDestroyConstant(const Constant *C);
 
 
 
/// As we analyze each global, keep track of some information about it.  If we
 
/// find out that the address of the global is taken, none of this info will be
 
/// accurate.
 
struct GlobalStatus {
 
  /// True if the global's address is used in a comparison.
 
  bool IsCompared = false;
 
 
 
  /// True if the global is ever loaded.  If the global isn't ever loaded it
 
  /// can be deleted.
 
  bool IsLoaded = false;
 
 
 
  /// Number of stores to the global.
 
  unsigned NumStores = 0;
 
 
 
  /// Keep track of what stores to the global look like.
 
  enum StoredType {
 
    /// There is no store to this global.  It can thus be marked constant.
 
    NotStored,
 
 
 
    /// This global is stored to, but the only thing stored is the constant it
 
    /// was initialized with. This is only tracked for scalar globals.
 
    InitializerStored,
 
 
 
    /// This global is stored to, but only its initializer and one other value
 
    /// is ever stored to it.  If this global isStoredOnce, we track the value
 
    /// stored to it via StoredOnceStore below.  This is only tracked for scalar
 
    /// globals.
 
    StoredOnce,
 
 
 
    /// This global is stored to by multiple values or something else that we
 
    /// cannot track.
 
    Stored
 
  } StoredType = NotStored;
 
 
 
  /// If only one value (besides the initializer constant) is ever stored to
 
  /// this global, keep track of what value it is via the store instruction.
 
  const StoreInst *StoredOnceStore = nullptr;
 
 
 
  /// If only one value (besides the initializer constant) is ever stored to
 
  /// this global return the stored value.
 
  Value *getStoredOnceValue() const {
 
    return (StoredType == StoredOnce && StoredOnceStore)
 
               ? StoredOnceStore->getOperand(0)
 
               : nullptr;
 
  }
 
 
 
  /// These start out null/false.  When the first accessing function is noticed,
 
  /// it is recorded. When a second different accessing function is noticed,
 
  /// HasMultipleAccessingFunctions is set to true.
 
  const Function *AccessingFunction = nullptr;
 
  bool HasMultipleAccessingFunctions = false;
 
 
 
  /// Set to the strongest atomic ordering requirement.
 
  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
 
 
 
  GlobalStatus();
 
 
 
  /// Look at all uses of the global and fill in the GlobalStatus structure.  If
 
  /// the global has its address taken, return true to indicate we can't do
 
  /// anything with it.
 
  static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
 
};
 
 
 
} // end namespace llvm
 
 
 
#endif // LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H