1//===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
10#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
11
12#include "llvm/Support/AtomicOrdering.h"
13
14namespace llvm {
15
16class Constant;
17class Function;
18class Value;
19
20/// It is safe to destroy a constant iff it is only used by constants itself.
21/// Note that constants cannot be cyclic, so this test is pretty easy to
22/// implement recursively.
23///
24bool isSafeToDestroyConstant(const Constant *C);
25
26/// As we analyze each global, keep track of some information about it.  If we
27/// find out that the address of the global is taken, none of this info will be
28/// accurate.
29struct GlobalStatus {
30  /// True if the global's address is used in a comparison.
31  bool IsCompared = false;
32
33  /// True if the global is ever loaded.  If the global isn't ever loaded it
34  /// can be deleted.
35  bool IsLoaded = false;
36
37  /// Keep track of what stores to the global look like.
38  enum StoredType {
39    /// There is no store to this global.  It can thus be marked constant.
40    NotStored,
41
42    /// This global is stored to, but the only thing stored is the constant it
43    /// was initialized with. This is only tracked for scalar globals.
44    InitializerStored,
45
46    /// This global is stored to, but only its initializer and one other value
47    /// is ever stored to it.  If this global isStoredOnce, we track the value
48    /// stored to it in StoredOnceValue below.  This is only tracked for scalar
49    /// globals.
50    StoredOnce,
51
52    /// This global is stored to by multiple values or something else that we
53    /// cannot track.
54    Stored
55  } StoredType = NotStored;
56
57  /// If only one value (besides the initializer constant) is ever stored to
58  /// this global, keep track of what value it is.
59  Value *StoredOnceValue = nullptr;
60
61  /// These start out null/false.  When the first accessing function is noticed,
62  /// it is recorded. When a second different accessing function is noticed,
63  /// HasMultipleAccessingFunctions is set to true.
64  const Function *AccessingFunction = nullptr;
65  bool HasMultipleAccessingFunctions = false;
66
67  /// Set to true if this global has a user that is not an instruction (e.g. a
68  /// constant expr or GV initializer).
69  bool HasNonInstructionUser = false;
70
71  /// Set to the strongest atomic ordering requirement.
72  AtomicOrdering Ordering = AtomicOrdering::NotAtomic;
73
74  GlobalStatus();
75
76  /// Look at all uses of the global and fill in the GlobalStatus structure.  If
77  /// the global has its address taken, return true to indicate we can't do
78  /// anything with it.
79  static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
80};
81
82} // end namespace llvm
83
84#endif // LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
85