33#define DEBUG_TYPE "globaldce" 
   42  bool runOnModule(
Module &M)
 override {
 
   48    auto PA = Impl.run(M, 
MAM);
 
   49    return !PA.areAllPreserved();
 
   57char GlobalDCELegacyPass::ID = 0;
 
   66                cl::desc(
"Enable virtual function elimination"));
 
   68STATISTIC(NumAliases  , 
"Number of global aliases removed");
 
   69STATISTIC(NumFunctions, 
"Number of functions removed");
 
   70STATISTIC(NumIFuncs,    
"Number of indirect functions removed");
 
   71STATISTIC(NumVariables, 
"Number of global variables removed");
 
   72STATISTIC(NumVFuncs,    
"Number of virtual functions removed");
 
   77  if (
F->isDeclaration())
 
   80  for (
auto &
I : Entry) {
 
   81    if (
I.isDebugOrPseudoInst())
 
   84      return !RI->getReturnValue();
 
 
   92void GlobalDCEPass::ComputeDependencies(
Value *V,
 
   95    Function *Parent = 
I->getParent()->getParent();
 
  101    auto [Where, 
Inserted] = ConstantDependenciesCache.try_emplace(CE);
 
  102    SmallPtrSetImpl<GlobalValue *> &LocalDeps = Where->second;
 
  104      for (User *CEUser : 
CE->users())
 
  105        ComputeDependencies(CEUser, LocalDeps);
 
  111void GlobalDCEPass::UpdateGVDependencies(
GlobalValue &GV) {
 
  112  SmallPtrSet<GlobalValue *, 8> Deps;
 
  113  for (User *User : GV.
users())
 
  114    ComputeDependencies(User, Deps);
 
  116  for (GlobalValue *GVU : Deps) {
 
  126    GVDependencies[GVU].insert(&GV);
 
  133  auto const Ret = AliveGlobals.insert(&GV);
 
  140    for (
auto &&CM : 
make_range(ComdatMembers.equal_range(
C))) {
 
  141      MarkLive(*CM.second, Updates); 
 
  147void GlobalDCEPass::ScanVTables(
Module &M) {
 
  151  for (GlobalVariable &GV : 
M.globals()) {
 
  160    for (MDNode *
Type : Types) {
 
  180        VFESafeVTables.insert(&GV);
 
  187                                   uint64_t CallOffset) {
 
  188  for (
const auto &VTableInfo : TypeIdMap[TypeId]) {
 
  189    GlobalVariable *
VTable = VTableInfo.first;
 
  190    uint64_t VTableOffset = VTableInfo.second;
 
  194                           *
Caller->getParent(), VTable);
 
  197      VFESafeVTables.erase(VTable);
 
  204      VFESafeVTables.erase(VTable);
 
  209                      << 
Callee->getName() << 
"\n");
 
  210    GVDependencies[
Caller].insert(Callee);
 
  214void GlobalDCEPass::ScanTypeCheckedLoadIntrinsics(
Module &M) {
 
  219      &M, Intrinsic::type_checked_load_relative);
 
  221  auto scan = [&](
Function *CheckedLoadFunc) {
 
  222    if (!CheckedLoadFunc)
 
  225    for (
auto *U : CheckedLoadFunc->users()) {
 
  231      Value *TypeIdValue = CI->getArgOperand(2);
 
  235        ScanVTableLoad(CI->getFunction(), TypeId, 
Offset->getZExtValue());
 
  239        for (
const auto &VTableInfo : TypeIdMap[TypeId]) {
 
  240          VFESafeVTables.erase(VTableInfo.first);
 
  246  scan(TypeCheckedLoadFunc);
 
  247  scan(TypeCheckedLoadRelativeFunc);
 
  250void GlobalDCEPass::AddVirtualFunctionDependencies(
Module &M) {
 
  259      M.getModuleFlag(
"Virtual Function Elim"));
 
  260  if (!Val || Val->isZero())
 
  265  if (VFESafeVTables.empty())
 
  268  ScanTypeCheckedLoadIntrinsics(M);
 
  271    dbgs() << 
"VFE safe vtables:\n";
 
  272    for (
auto *VTable : VFESafeVTables)
 
  295      ComdatMembers.insert(std::make_pair(
C, &
F));
 
  298      ComdatMembers.insert(std::make_pair(
C, &GV));
 
  300    if (
Comdat *
C = GA.getComdat())
 
  301      ComdatMembers.insert(std::make_pair(
C, &GA));
 
  305  AddVirtualFunctionDependencies(M);
 
  309    GO.removeDeadConstantUsers();
 
  313    if (!GO.isDeclaration())
 
  314      if (!GO.isDiscardableIfUnused())
 
  317    UpdateGVDependencies(GO);
 
  322    GA.removeDeadConstantUsers();
 
  324    if (!GA.isDiscardableIfUnused())
 
  327    UpdateGVDependencies(GA);
 
  332    GIF.removeDeadConstantUsers();
 
  334    if (!GIF.isDiscardableIfUnused())
 
  337    UpdateGVDependencies(GIF);
 
  344  while (!NewLiveGVs.
empty()) {
 
  346    for (
auto *GVD : GVDependencies[LGV])
 
  347      MarkLive(*GVD, &NewLiveGVs);
 
  355  std::vector<GlobalVariable *> DeadGlobalVars; 
 
  357    if (!AliveGlobals.count(&GV)) {
 
  358      DeadGlobalVars.push_back(&GV);         
 
  359      if (GV.hasInitializer()) {
 
  361        GV.setInitializer(
nullptr);
 
  363          Init->destroyConstant();
 
  368  std::vector<Function *> DeadFunctions;
 
  370    if (!AliveGlobals.count(&
F)) {
 
  371      DeadFunctions.push_back(&
F);         
 
  372      if (!
F.isDeclaration())
 
  377  std::vector<GlobalAlias*> DeadAliases;
 
  379    if (!AliveGlobals.count(&GA)) {
 
  380      DeadAliases.push_back(&GA);
 
  381      GA.setAliasee(
nullptr);
 
  385  std::vector<GlobalIFunc*> DeadIFuncs;
 
  387    if (!AliveGlobals.count(&GIF)) {
 
  388      DeadIFuncs.push_back(&GIF);
 
  389      GIF.setResolver(
nullptr);
 
  394  auto EraseUnusedGlobalValue = [&](
GlobalValue *GV) {
 
  400  NumFunctions += DeadFunctions.size();
 
  402    if (!
F->use_empty()) {
 
  420    EraseUnusedGlobalValue(
F);
 
  423  NumVariables += DeadGlobalVars.size();
 
  425    EraseUnusedGlobalValue(GV);
 
  427  NumAliases += DeadAliases.size();
 
  429    EraseUnusedGlobalValue(GA);
 
  431  NumIFuncs += DeadIFuncs.size();
 
  433    EraseUnusedGlobalValue(GIF);
 
  436  AliveGlobals.clear();
 
  437  ConstantDependenciesCache.clear();
 
  438  GVDependencies.clear();
 
  439  ComdatMembers.clear();
 
  441  VFESafeVTables.clear();
 
 
  451      OS, MapClassName2PassName);
 
  453    OS << 
"<vfe-linkage-unit-visibility>";
 
 
static bool isEmptyFunction(Function *F)
Returns true if F is effectively empty.
 
static cl::opt< bool > ClEnableVFE("enable-vfe", cl::Hidden, cl::init(true), cl::desc("Enable virtual function elimination"))
 
Module.h This file contains the declarations for the Module class.
 
ModuleAnalysisManager MAM
 
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
 
This file defines the SmallPtrSet class.
 
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
 
#define STATISTIC(VARNAME, DESC)
 
LLVM Basic Block Representation.
 
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
 
This is an important base class in LLVM.
 
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
 
Pass to remove unused function declarations.
 
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
 
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
 
@ VCallVisibilityLinkageUnit
 
@ VCallVisibilityTranslationUnit
 
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
 
LLVM_ABI const Comdat * getComdat() const
 
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
 
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
 
A Module instance is used to store all the information related to an LLVM module.
 
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
 
A set of analyses that are preserved following a run of a transformation pass.
 
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
 
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
 
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
 
bool erase(PtrType Ptr)
Remove pointer from the set.
 
void insert_range(Range &&R)
 
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
 
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
StringRef - Represent a constant reference to a string, i.e.
 
LLVM Value Representation.
 
iterator_range< user_iterator > users()
 
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
 
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
 
An efficient, type-erasing, non-owning reference to a callable.
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
 
@ C
The default llvm calling convention, compatible with C.
 
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
 
@ CE
Windows NT (Windows on ARM)
 
initializer< Ty > init(const Ty &Val)
 
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
 
This is an optimization pass for GlobalISel generic memory operations.
 
FunctionAddr VTableAddr Value
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
 
LLVM_ABI ModulePass * createGlobalDCEPass()
 
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
 
LLVM_ABI void initializeGlobalDCELegacyPassPass(PassRegistry &)
 
bool optimizeGlobalCtorsList(Module &M, function_ref< bool(uint32_t, Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it retur...
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
void replaceRelativePointerUsersWithZero(Constant *C)
Finds the same "relative pointer" pattern as described above, where the target is C,...
 
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
 
Constant * getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, Constant *TopLevelGlobal=nullptr)
Processes a Constant recursively looking into elements of arrays, structs and expressions to find a t...
 
A CRTP mix-in to automatically provide informational APIs needed for passes.