| //===- 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; |
| |
| /// 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 |