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