LLVM API Documentation
00001 //===- DataStructureOpt.cpp - Data Structure Analysis Based Optimizations -===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass uses DSA to a series of simple optimizations, like marking 00011 // unwritten global variables 'constant'. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Analysis/DataStructure/DataStructure.h" 00016 #include "llvm/Analysis/DataStructure/DSGraph.h" 00017 #include "llvm/Module.h" 00018 #include "llvm/Constant.h" 00019 #include "llvm/ADT/Statistic.h" 00020 using namespace llvm; 00021 00022 namespace { 00023 Statistic<> 00024 NumGlobalsConstanted("ds-opt", "Number of globals marked constant"); 00025 Statistic<> 00026 NumGlobalsIsolated("ds-opt", "Number of globals with references dropped"); 00027 00028 class DSOpt : public ModulePass { 00029 TDDataStructures *TD; 00030 public: 00031 bool runOnModule(Module &M) { 00032 TD = &getAnalysis<TDDataStructures>(); 00033 bool Changed = OptimizeGlobals(M); 00034 return Changed; 00035 } 00036 00037 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00038 AU.addRequired<TDDataStructures>(); // Uses TD Datastructures 00039 AU.addPreserved<LocalDataStructures>(); // Preserves local... 00040 AU.addPreserved<TDDataStructures>(); // Preserves bu... 00041 AU.addPreserved<BUDataStructures>(); // Preserves td... 00042 } 00043 00044 private: 00045 bool OptimizeGlobals(Module &M); 00046 }; 00047 00048 RegisterOpt<DSOpt> X("ds-opt", "DSA-based simple optimizations"); 00049 } 00050 00051 /// OptimizeGlobals - This method uses information taken from DSA to optimize 00052 /// global variables. 00053 /// 00054 bool DSOpt::OptimizeGlobals(Module &M) { 00055 DSGraph &GG = TD->getGlobalsGraph(); 00056 const DSGraph::ScalarMapTy &SM = GG.getScalarMap(); 00057 bool Changed = false; 00058 00059 for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) 00060 if (!I->isExternal()) { // Loop over all of the non-external globals... 00061 // Look up the node corresponding to this global, if it exists. 00062 DSNode *GNode = 0; 00063 DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I); 00064 if (SMI != SM.end()) GNode = SMI->second.getNode(); 00065 00066 if (GNode == 0 && I->hasInternalLinkage()) { 00067 // If there is no entry in the scalar map for this global, it was never 00068 // referenced in the program. If it has internal linkage, that means we 00069 // can delete it. We don't ACTUALLY want to delete the global, just 00070 // remove anything that references the global: later passes will take 00071 // care of nuking it. 00072 if (!I->use_empty()) { 00073 I->replaceAllUsesWith(Constant::getNullValue((Type*)I->getType())); 00074 ++NumGlobalsIsolated; 00075 } 00076 } else if (GNode && GNode->isComplete()) { 00077 00078 // If the node has not been read or written, and it is not externally 00079 // visible, kill any references to it so it can be DCE'd. 00080 if (!GNode->isModified() && !GNode->isRead() &&I->hasInternalLinkage()){ 00081 if (!I->use_empty()) { 00082 I->replaceAllUsesWith(Constant::getNullValue((Type*)I->getType())); 00083 ++NumGlobalsIsolated; 00084 } 00085 } 00086 00087 // We expect that there will almost always be a node for this global. 00088 // If there is, and the node doesn't have the M bit set, we can set the 00089 // 'constant' bit on the global. 00090 if (!GNode->isModified() && !I->isConstant()) { 00091 I->setConstant(true); 00092 ++NumGlobalsConstanted; 00093 Changed = true; 00094 } 00095 } 00096 } 00097 return Changed; 00098 }