1713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===//
2713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//
3713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//                     The LLVM Compiler Infrastructure
4713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//
5713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola// This file is distributed under the University of Illinois Open Source
6713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola// License. See LICENSE.TXT for details.
7713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//
8713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola//===----------------------------------------------------------------------===//
9713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
10713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
11713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
12713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
13713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola#include "llvm/IR/Instructions.h"
14713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
15713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindolanamespace llvm {
16713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindolaclass Value;
17713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindolaclass Function;
18713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
19713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// It is safe to destroy a constant iff it is only used by constants itself.
20713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// Note that constants cannot be cyclic, so this test is pretty easy to
21713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// implement recursively.
22713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola///
23713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindolabool isSafeToDestroyConstant(const Constant *C);
24713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
25713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// As we analyze each global, keep track of some information about it.  If we
26713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// find out that the address of the global is taken, none of this info will be
27713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola/// accurate.
28713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindolastruct GlobalStatus {
29713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// True if the global's address is used in a comparison.
30713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  bool IsCompared;
31713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
32713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// True if the global is ever loaded.  If the global isn't ever loaded it
33713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// can be deleted.
34713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  bool IsLoaded;
35713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
36713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// Keep track of what stores to the global look like.
37713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  enum StoredType {
38713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// There is no store to this global.  It can thus be marked constant.
39713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    NotStored,
40713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
41713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// This global is stored to, but the only thing stored is the constant it
42713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// was initialized with. This is only tracked for scalar globals.
43713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    InitializerStored,
44713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
45713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// This global is stored to, but only its initializer and one other value
46713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// is ever stored to it.  If this global isStoredOnce, we track the value
47713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// stored to it in StoredOnceValue below.  This is only tracked for scalar
48713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// globals.
49713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    StoredOnce,
50713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
51713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// This global is stored to by multiple values or something else that we
52713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    /// cannot track.
53713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola    Stored
54713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  } StoredType;
55713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
56713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// If only one value (besides the initializer constant) is ever stored to
57713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// this global, keep track of what value it is.
58713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  Value *StoredOnceValue;
59713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
60713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// These start out null/false.  When the first accessing function is noticed,
61713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// it is recorded. When a second different accessing function is noticed,
62713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// HasMultipleAccessingFunctions is set to true.
63713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  const Function *AccessingFunction;
64713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  bool HasMultipleAccessingFunctions;
65713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
66713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// Set to true if this global has a user that is not an instruction (e.g. a
67713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// constant expr or GV initializer).
68713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  bool HasNonInstructionUser;
69713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
70713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// Set to the strongest atomic ordering requirement.
71713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  AtomicOrdering Ordering;
72713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
73713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// Look at all uses of the global and fill in the GlobalStatus structure.  If
74713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// the global has its address taken, return true to indicate we can't do
75713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  /// anything with it.
76713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
77713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
78713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola  GlobalStatus();
79713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola};
80713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola}
81713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola
82713cab059ebb67c2f51d8da9d8e57be2b1dcd9c2Rafael Espindola#endif
83