SizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){ if (!GV.hasDefinitiveInitializer()) return unknown(); APInt Size(IntTyBits, TD->getTypeAllocSize(GV.getType()->getElementType())); return std::make_pair(align(Size, GV.getAlignment()), Zero); }
bool runOnModule(Module &M) override { // function pointer initialized at compile time for (Module::global_iterator G = M.global_begin(); G != M.global_end(); G++) { GlobalVariable *gv = &*G; if (!gv->hasDefinitiveInitializer()) continue; Constant *initor = gv->getInitializer(); if (constantFunctionPointerName(initor) || constantTravel(initor)) errs() << *gv << "\n"; } // function pointer initialized at runtime for (Module::iterator F = M.begin(); F != M.end(); F++) { for (inst_iterator I = inst_begin(F); I != inst_end(F); I++) { if (StoreInst *si = dyn_cast<StoreInst>(&*I)) { Value *val = si->getValueOperand(); if (constantFunctionPointerName(val)) errs() << *I << "\n"; } else if (CallInst *ci = dyn_cast<CallInst>(&*I)) { for (unsigned i = 0; i < ci->getNumArgOperands(); i++) { Value *operand = ci->getArgOperand(i); if (constantFunctionPointerName(operand)) errs() << *I << "\n"; } } else if (ReturnInst *ri = dyn_cast<ReturnInst>(&*I)) { Value *ret = ri->getReturnValue(); if (constantFunctionPointerName(ret)) errs() << *I << "\n"; } } } return false; }
static void initialiseStore(ShadowBB* BB) { for(uint32_t i = 0, ilim = GlobalIHP->heap.size(); i != ilim; ++i) { AllocData& AD = GlobalIHP->heap[i]; ImprovedValSetSingle* Init = new ImprovedValSetSingle(); if(AD.allocValue.isGV()) { GlobalVariable* G = AD.allocValue.getGV()->G; if(GlobalIHP->useGlobalInitialisers && G->hasDefinitiveInitializer()) { Constant* I = G->getInitializer(); if(isa<ConstantAggregateZero>(I)) { Init->SetType = ValSetTypeScalarSplat; Type* I8 = Type::getInt8Ty(BB->invar->BB->getContext()); Constant* I8Z = Constant::getNullValue(I8); Init->insert(ImprovedVal(I8Z)); } else { std::pair<ValSetType, ImprovedVal> InitIV = getValPB(I); (*Init) = ImprovedValSetSingle(InitIV.second, InitIV.first); } } else { // Start off overdef, and known-older-than-specialisation. Init->SetType = ValSetTypeOldOverdef; } } else { // All non-GVs initialise to an old value. Init->SetType = ValSetTypeOldOverdef; } LocStore* LS = BB->getWritableStoreFor(AD.allocValue, 0, AD.storeSize, true); release_assert(LS && "Non-writable location in initialiseStore?"); LS->store->dropReference(); LS->store = Init; } }
bool ObjCARCAPElim::runOnModule(Module &M) { if (!EnableARCOpts) return false; // If nothing in the Module uses ARC, don't do anything. if (!ModuleHasARC(M)) return false; // Find the llvm.global_ctors variable, as the first step in // identifying the global constructors. In theory, unnecessary autorelease // pools could occur anywhere, but in practice it's pretty rare. Global // ctors are a place where autorelease pools get inserted automatically, // so it's pretty common for them to be unnecessary, and it's pretty // profitable to eliminate them. GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); if (!GV) return false; assert(GV->hasDefinitiveInitializer() && "llvm.global_ctors is uncooperative!"); bool Changed = false; // Dig the constructor functions out of GV's initializer. ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end(); OI != OE; ++OI) { Value *Op = *OI; // llvm.global_ctors is an array of three-field structs where the second // members are constructor functions. Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1)); // If the user used a constructor function with the wrong signature and // it got bitcasted or whatever, look the other way. if (!F) continue; // Only look at function definitions. if (F->isDeclaration()) continue; // Only look at functions with one basic block. if (std::next(F->begin()) != F->end()) continue; // Ok, a single-block constructor function definition. Try to optimize it. Changed |= OptimizeBB(F->begin()); } return Changed; }
// doInitialization - Initializes the vector of functions that have been // annotated with the noinline attribute. bool SimpleInliner::doInitialization(CallGraph &CG) { CA.setTargetData(getAnalysisIfAvailable<TargetData>()); Module &M = CG.getModule(); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && I->hasFnAttr(Attribute::NoInline)) NeverInline.insert(I); // Get llvm.noinline GlobalVariable *GV = M.getNamedGlobal("llvm.noinline"); if (GV == 0) return false; // Don't crash on invalid code if (!GV->hasDefinitiveInitializer()) return false; const ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); if (InitList == 0) return false; // Iterate over each element and add to the NeverInline set for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { // Get Source const Constant *Elt = InitList->getOperand(i); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Elt)) if (CE->getOpcode() == Instruction::BitCast) Elt = CE->getOperand(0); // Insert into set of functions to never inline if (const Function *F = dyn_cast<Function>(Elt)) NeverInline.insert(F); } return false; }
/// Return the value that would be computed by a load from P after the stores /// reflected by 'memory' have been performed. If we can't decide, return null. Constant *Evaluator::ComputeLoadResult(Constant *P) { // If this memory location has been recently stored, use the stored value: it // is the most up-to-date. DenseMap<Constant*, Constant*>::const_iterator I = MutatedMemory.find(P); if (I != MutatedMemory.end()) return I->second; // Access it. if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P)) { if (GV->hasDefinitiveInitializer()) return GV->getInitializer(); return nullptr; } // Handle a constantexpr getelementptr. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(P)) if (CE->getOpcode() == Instruction::GetElementPtr && isa<GlobalVariable>(CE->getOperand(0))) { GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0)); if (GV->hasDefinitiveInitializer()) return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); } return nullptr; // don't know how to evaluate. }
bool ConstantMerge::runOnModule(Module &M) { TD = getAnalysisIfAvailable<TargetData>(); // Find all the globals that are marked "used". These cannot be merged. SmallPtrSet<const GlobalValue*, 8> UsedGlobals; FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals); // Map unique <constants, has-unknown-alignment> pairs to globals. We don't // want to merge globals of unknown alignment with those of explicit // alignment. If we have TargetData, we always know the alignment. DenseMap<PointerIntPair<Constant*, 1, bool>, GlobalVariable*> CMap; // Replacements - This vector contains a list of replacements to perform. SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements; bool MadeChange = false; // Iterate constant merging while we are still making progress. Merging two // constants together may allow us to merge other constants together if the // second level constants have initializers which point to the globals that // were just merged. while (1) { // First: Find the canonical constants others will be merged with. for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); GVI != E; ) { GlobalVariable *GV = GVI++; // If this GV is dead, remove it. GV->removeDeadConstantUsers(); if (GV->use_empty() && GV->hasLocalLinkage()) { GV->eraseFromParent(); continue; } // Only process constants with initializers in the default address space. if (!GV->isConstant() || !GV->hasDefinitiveInitializer() || GV->getType()->getAddressSpace() != 0 || GV->hasSection() || // Don't touch values marked with attribute(used). UsedGlobals.count(GV)) continue; // This transformation is legal for weak ODR globals in the sense it // doesn't change semantics, but we really don't want to perform it // anyway; it's likely to pessimize code generation, and some tools // (like the Darwin linker in cases involving CFString) don't expect it. if (GV->isWeakForLinker()) continue; Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. PointerIntPair<Constant*, 1, bool> Pair(Init, hasKnownAlignment(GV)); GlobalVariable *&Slot = CMap[Pair]; // If this is the first constant we find or if the old one is local, // replace with the current one. If the current is externally visible // it cannot be replace, but can be the canonical constant we merge with. if (Slot == 0 || IsBetterCannonical(*GV, *Slot)) Slot = GV; } // Second: identify all globals that can be merged together, filling in // the Replacements vector. We cannot do the replacement in this pass // because doing so may cause initializers of other globals to be rewritten, // invalidating the Constant* pointers in CMap. for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); GVI != E; ) { GlobalVariable *GV = GVI++; // Only process constants with initializers in the default address space. if (!GV->isConstant() || !GV->hasDefinitiveInitializer() || GV->getType()->getAddressSpace() != 0 || GV->hasSection() || // Don't touch values marked with attribute(used). UsedGlobals.count(GV)) continue; // We can only replace constant with local linkage. if (!GV->hasLocalLinkage()) continue; Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. PointerIntPair<Constant*, 1, bool> Pair(Init, hasKnownAlignment(GV)); GlobalVariable *Slot = CMap[Pair]; if (!Slot || Slot == GV) continue; if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr()) continue; if (!GV->hasUnnamedAddr()) Slot->setUnnamedAddr(false); // Make all uses of the duplicate constant use the canonical version. Replacements.push_back(std::make_pair(GV, Slot)); } if (Replacements.empty()) return MadeChange; CMap.clear(); // Now that we have figured out which replacements must be made, do them all // now. This avoid invalidating the pointers in CMap, which are unneeded // now. for (unsigned i = 0, e = Replacements.size(); i != e; ++i) { // Bump the alignment if necessary. if (Replacements[i].first->getAlignment() || Replacements[i].second->getAlignment()) { Replacements[i].second->setAlignment(std::max( Replacements[i].first->getAlignment(), Replacements[i].second->getAlignment())); } // Eliminate any uses of the dead global. Replacements[i].first->replaceAllUsesWith(Replacements[i].second); // Delete the global value from the module. assert(Replacements[i].first->hasLocalLinkage() && "Refusing to delete an externally visible global variable."); Replacements[i].first->eraseFromParent(); } NumMerged += Replacements.size(); Replacements.clear(); } }
bool ConstantMerge::runOnModule(Module &M) { // Find all the globals that are marked "used". These cannot be merged. SmallPtrSet<const GlobalValue*, 8> UsedGlobals; FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals); // Map unique constant/section pairs to globals. We don't want to merge // globals in different sections. DenseMap<Constant*, GlobalVariable*> CMap; // Replacements - This vector contains a list of replacements to perform. SmallVector<std::pair<GlobalVariable*, GlobalVariable*>, 32> Replacements; bool MadeChange = false; // Iterate constant merging while we are still making progress. Merging two // constants together may allow us to merge other constants together if the // second level constants have initializers which point to the globals that // were just merged. while (1) { // First pass: identify all globals that can be merged together, filling in // the Replacements vector. We cannot do the replacement in this pass // because doing so may cause initializers of other globals to be rewritten, // invalidating the Constant* pointers in CMap. // for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); GVI != E; ) { GlobalVariable *GV = GVI++; // If this GV is dead, remove it. GV->removeDeadConstantUsers(); if (GV->use_empty() && GV->hasLocalLinkage()) { GV->eraseFromParent(); continue; } // Only process constants with initializers in the default addres space. if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty() || // Don't touch values marked with attribute(used). UsedGlobals.count(GV)) continue; Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. GlobalVariable *&Slot = CMap[Init]; if (Slot == 0) { // Nope, add it to the map. Slot = GV; } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the canonical version. Replacements.push_back(std::make_pair(GV, Slot)); } } if (Replacements.empty()) return MadeChange; CMap.clear(); // Now that we have figured out which replacements must be made, do them all // now. This avoid invalidating the pointers in CMap, which are unneeded // now. for (unsigned i = 0, e = Replacements.size(); i != e; ++i) { // Eliminate any uses of the dead global. Replacements[i].first->replaceAllUsesWith(Replacements[i].second); // Delete the global value from the module. Replacements[i].first->eraseFromParent(); } NumMerged += Replacements.size(); Replacements.clear(); } }