GlobalStatus.h revision 259698
1139825Simp//===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===//
2103785Sjeff//
3207223Slstewart//                     The LLVM Compiler Infrastructure
4207223Slstewart//
5103785Sjeff// This file is distributed under the University of Illinois Open Source
6103785Sjeff// License. See LICENSE.TXT for details.
7207223Slstewart//
8207223Slstewart//===----------------------------------------------------------------------===//
9207223Slstewart
10207223Slstewart#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
11103785Sjeff#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
12103785Sjeff
13103785Sjeff#include "llvm/IR/Instructions.h"
14103785Sjeff
15103785Sjeffnamespace llvm {
16103785Sjeffclass Value;
17103785Sjeffclass Function;
18103785Sjeff
19103785Sjeff/// It is safe to destroy a constant iff it is only used by constants itself.
20103785Sjeff/// Note that constants cannot be cyclic, so this test is pretty easy to
21103785Sjeff/// implement recursively.
22103785Sjeff///
23103785Sjeffbool isSafeToDestroyConstant(const Constant *C);
24103785Sjeff
25103785Sjeff/// As we analyze each global, keep track of some information about it.  If we
26103785Sjeff/// find out that the address of the global is taken, none of this info will be
27103785Sjeff/// accurate.
28103785Sjeffstruct GlobalStatus {
29103785Sjeff  /// True if the global's address is used in a comparison.
30103785Sjeff  bool IsCompared;
31103785Sjeff
32103785Sjeff  /// True if the global is ever loaded.  If the global isn't ever loaded it
33103785Sjeff  /// can be deleted.
34103785Sjeff  bool IsLoaded;
35103812Sjeff
36103812Sjeff  /// Keep track of what stores to the global look like.
37103785Sjeff  enum StoredType {
38103785Sjeff    /// There is no store to this global.  It can thus be marked constant.
39103785Sjeff    NotStored,
40103785Sjeff
41103785Sjeff    /// This global is stored to, but the only thing stored is the constant it
42103785Sjeff    /// was initialized with. This is only tracked for scalar globals.
43103995Sjeff    InitializerStored,
44103995Sjeff
45103995Sjeff    /// This global is stored to, but only its initializer and one other value
46103785Sjeff    /// is ever stored to it.  If this global isStoredOnce, we track the value
47103785Sjeff    /// stored to it in StoredOnceValue below.  This is only tracked for scalar
48103785Sjeff    /// globals.
49103785Sjeff    StoredOnce,
50207223Slstewart
51207223Slstewart    /// This global is stored to by multiple values or something else that we
52207223Slstewart    /// cannot track.
53103785Sjeff    Stored
54103785Sjeff  } StoredType;
55207223Slstewart
56207223Slstewart  /// If only one value (besides the initializer constant) is ever stored to
57207223Slstewart  /// this global, keep track of what value it is.
58207223Slstewart  Value *StoredOnceValue;
59207223Slstewart
60103785Sjeff  /// These start out null/false.  When the first accessing function is noticed,
61145142Srwatson  /// it is recorded. When a second different accessing function is noticed,
62145142Srwatson  /// HasMultipleAccessingFunctions is set to true.
63145142Srwatson  const Function *AccessingFunction;
64103785Sjeff  bool HasMultipleAccessingFunctions;
65207223Slstewart
66103785Sjeff  /// Set to true if this global has a user that is not an instruction (e.g. a
67103785Sjeff  /// constant expr or GV initializer).
68103785Sjeff  bool HasNonInstructionUser;
69103785Sjeff
70145142Srwatson  /// Set to the strongest atomic ordering requirement.
71145142Srwatson  AtomicOrdering Ordering;
72207223Slstewart
73207223Slstewart  /// Look at all uses of the global and fill in the GlobalStatus structure.  If
74103785Sjeff  /// the global has its address taken, return true to indicate we can't do
75103785Sjeff  /// anything with it.
76103785Sjeff  static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
77116697Srwatson
78207223Slstewart  GlobalStatus();
79207223Slstewart};
80207223Slstewart}
81145142Srwatson
82103785Sjeff#endif
83103785Sjeff