void LTOCodeGenerator::applyScopeRestrictions() { if (_scopeRestrictionsDone) return; Module *mergedModule = _linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized if (!_mustPreserveSymbols.empty()) { MCContext Context(*_target->getMCAsmInfo(), NULL); Mangler mangler(Context, *_target->getTargetData()); std::vector<const char*> mustPreserveList; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) { if (!f->isDeclaration() && _mustPreserveSymbols.count(mangler.getNameWithPrefix(f))) mustPreserveList.push_back(::strdup(f->getNameStr().c_str())); } for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) { if (!v->isDeclaration() && _mustPreserveSymbols.count(mangler.getNameWithPrefix(v))) mustPreserveList.push_back(::strdup(v->getNameStr().c_str())); } passes.add(createInternalizePass(mustPreserveList)); } // apply scope restrictions passes.run(*mergedModule); _scopeRestrictionsDone = true; }
/// doInitialization - Perfrom Module level initializations here. /// One task that we do here is to sectionize all global variables. /// The MemSelOptimizer pass depends on the sectionizing. /// bool PIC16AsmPrinter::doInitialization(Module &M) { bool Result = AsmPrinter::doInitialization(M); // FIXME:: This is temporary solution to generate the include file. // The processor should be passed to llc as in input and the header file // should be generated accordingly. O << "\n\t#include P16F1937.INC\n"; // Set the section names for all globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM); I->setSection(((const MCSectionPIC16*)S)->getName()); } DbgInfo.BeginModule(M); EmitFunctionDecls(M); EmitUndefinedVars(M); EmitDefinedVars(M); EmitIData(M); EmitUData(M); EmitRomData(M); return Result; }
/// StripSymbolNames - Strip symbol names. static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage } for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); } // Remove all names from types. StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); return true; }
void PIC16AsmPrinter::EmitRomData (Module &M) { SwitchToSection(TAI->getReadOnlySection()); IsRomData = true; for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (!I->hasInitializer()) // External global require no code. continue; Constant *C = I->getInitializer(); const PointerType *PtrTy = I->getType(); int AddrSpace = PtrTy->getAddressSpace(); if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) { if (EmitSpecialLLVMGlobal(I)) continue; // Any variables reaching here with "." in its name is a local scope // variable and should not be printed in global data section. std::string name = Mang->getValueName(I); if (name.find(".") != std::string::npos) continue; I->setSection(TAI->getReadOnlySection()->getName()); O << name; EmitGlobalConstant(C, AddrSpace); O << "\n"; } } IsRomData = false; }
/// AnalyzeGlobals - Scan through the users of all of the internal /// GlobalValue's in the program. If none of them have their "address taken" /// (really, their address passed to something nontrivial), record this fact, /// and record the functions that they are used directly in. void GlobalsModRef::AnalyzeGlobals(Module &M) { std::vector<Function*> Readers, Writers; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (I->hasLocalLinkage()) { if (!AnalyzeUsesOfPointer(I, Readers, Writers)) { // Remember that we are tracking this global. NonAddressTakenGlobals.insert(I); ++NumNonAddrTakenFunctions; } Readers.clear(); Writers.clear(); } for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasLocalLinkage()) { if (!AnalyzeUsesOfPointer(I, Readers, Writers)) { // Remember that we are tracking this global, and the mod/ref fns NonAddressTakenGlobals.insert(I); for (unsigned i = 0, e = Readers.size(); i != e; ++i) FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref; if (!I->isConstant()) // No need to keep track of writers to constants for (unsigned i = 0, e = Writers.size(); i != e; ++i) FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod; ++NumNonAddrTakenGlobalVars; // If this global holds a pointer type, see if it is an indirect global. if (I->getType()->getElementType()->isPointerTy() && AnalyzeIndirectGlobalMemory(I)) ++NumIndirectGlobalVars; } Readers.clear(); Writers.clear(); } }
void PIC16AsmPrinter::EmitUnInitData (Module &M) { SwitchToSection(TAI->getBSSSection_()); const TargetData *TD = TM.getTargetData(); for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (!I->hasInitializer()) // External global require no code. continue; Constant *C = I->getInitializer(); if (C->isNullValue()) { if (EmitSpecialLLVMGlobal(I)) continue; // Any variables reaching here with "." in its name is a local scope // variable and should not be printed in global data section. std::string name = Mang->getValueName(I); if (name.find(".") != std::string::npos) continue; I->setSection(TAI->getBSSSection_()->getName()); const Type *Ty = C->getType(); unsigned Size = TD->getTypePaddedSize(Ty); O << name << " " <<"RES"<< " " << Size ; O << "\n"; } } }
/// computeTypeMapping - Loop over all of the linked values to compute type /// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then /// we have two struct types 'Foo' but one got renamed when the module was /// loaded into the same LLVMContext. void ModuleLinker::computeTypeMapping() { // Incorporate globals. for (Module::global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) { GlobalValue *DGV = getLinkedToGlobal(I); if (DGV == 0) continue; if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) { TypeMap.addTypeMapping(DGV->getType(), I->getType()); continue; } // Unify the element type of appending arrays. ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType()); ArrayType *SAT = cast<ArrayType>(I->getType()->getElementType()); TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); } // Incorporate functions. for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) { if (GlobalValue *DGV = getLinkedToGlobal(I)) TypeMap.addTypeMapping(DGV->getType(), I->getType()); } // Incorporate types by name, scanning all the types in the source module. // At this point, the destination module may have a type "%foo = { i32 }" for // example. When the source module got loaded into the same LLVMContext, if // it had the same type, it would have been renamed to "%foo.42 = { i32 }". // Though it isn't required for correctness, attempt to link these up to clean // up the IR. std::vector<StructType*> SrcStructTypes; SrcM->findUsedStructTypes(SrcStructTypes); SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(), SrcStructTypes.end()); for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { StructType *ST = SrcStructTypes[i]; if (!ST->hasName()) continue; // Check to see if there is a dot in the name followed by a digit. size_t DotPos = ST->getName().rfind('.'); if (DotPos == 0 || DotPos == StringRef::npos || ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1])) continue; // Check to see if the destination module has a struct with the prefix name. if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos))) // Don't use it if this actually came from the source module. They're in // the same LLVMContext after all. if (!SrcStructTypesSet.count(DST)) TypeMap.addTypeMapping(DST, ST); } // Don't bother incorporating aliases, they aren't generally typed well. // Now that we have discovered all of the type equivalences, get a body for // any 'opaque' types in the dest module that are now resolved. TypeMap.linkDefinedTypeBodies(); }
bool PIC16AsmPrinter::doInitialization (Module &M) { bool Result = AsmPrinter::doInitialization(M); DbgInfo.EmitFileDirective(M); // FIXME:: This is temporary solution to generate the include file. // The processor should be passed to llc as in input and the header file // should be generated accordingly. O << "\n\t#include P16F1937.INC\n"; MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>(); assert(MMI); DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>(); assert(DW && "Dwarf Writer is not available"); DW->BeginModule(&M, MMI, O, this, TAI); // Set the section names for all globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { I->setSection(TAI->SectionForGlobal(I)->getName()); } EmitFunctionDecls(M); EmitUndefinedVars(M); EmitDefinedVars(M); EmitIData(M); EmitUData(M); EmitRomData(M); DbgInfo.PopulateFunctsDI(M); return Result; }
void MemoryInstrumenter::instrumentGlobals(Module &M) { TargetData &TD = getAnalysis<TargetData>(); IDAssigner &IDA = getAnalysis<IDAssigner>(); // Function HookGlobalsAlloc contains only one basic block. // The BB iterates through all global variables, and calls HookMemAlloc // for each of them. BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", GlobalsAllocHook); Instruction *Ret = ReturnInst::Create(M.getContext(), BB); for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { // We are going to delete llvm.global_ctors. // Therefore, don't instrument it. if (GI->getName() == "llvm.global_ctors") continue; // Prevent global variables from sharing the same address, because it // breaks the assumption that global variables do not alias. // The same goes to functions. if (GI->hasUnnamedAddr()) { GI->setUnnamedAddr(false); } uint64_t TypeSize = TD.getTypeStoreSize(GI->getType()->getElementType()); instrumentMemoryAllocation(GI, ConstantInt::get(LongType, TypeSize), NULL, Ret); instrumentPointer(GI, NULL, Ret); } for (Module::iterator F = M.begin(); F != M.end(); ++F) { // These hooks added by us don't have a value ID. if (MemAllocHook == F || MainArgsAllocHook == F || TopLevelHook == F || AddrTakenHook == F || CallHook == F || ReturnHook == F || GlobalsAllocHook == F || MemHooksIniter == F || AfterForkHook == F || BeforeForkHook == F) { continue; } // InvalidID: maybe this is inserted by alias checker in hybrid mode. if (IDA.getValueID(F) == IDAssigner::InvalidID) continue; // Ignore intrinsic functions because we cannot take the address of // an intrinsic. Also, no function pointers will point to instrinsic // functions. if (F->isIntrinsic()) continue; // Prevent functions from sharing the same address. if (F->hasUnnamedAddr()) { F->setUnnamedAddr(false); } uint64_t TypeSize = TD.getTypeStoreSize(F->getType()); assert(TypeSize == TD.getPointerSize()); instrumentMemoryAllocation(F, ConstantInt::get(LongType, TypeSize), NULL, Ret); instrumentPointer(F, NULL, Ret); } }
void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { const Function *F = MF.getFunction(); std::string FuncName = Mang->getValueName(F); Module *M = const_cast<Module *>(F->getParent()); const TargetData *TD = TM.getTargetData(); unsigned FrameSize = 0; // Emit the data section name. O << "\n"; std::string SectionName = "fdata." + CurrentFnName + ".# " + "UDATA"; const Section *fDataSection = TAI->getNamedSection(SectionName.c_str(), SectionFlags::Writeable); SwitchToSection(fDataSection); //Emit function return value. O << CurrentFnName << ".retval:\n"; const Type *RetType = F->getReturnType(); unsigned RetSize = 0; if (RetType->getTypeID() != Type::VoidTyID) RetSize = TD->getTypePaddedSize(RetType); // Emit function arguments. O << CurrentFnName << ".args:\n"; // Emit the function variables. // In PIC16 all the function arguments and local variables are global. // Therefore to get the variable belonging to this function entire // global list will be traversed and variables belonging to this function // will be emitted in the current data section. for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { std::string VarName = Mang->getValueName(I); // The variables of a function are of form FuncName.* . If this variable // does not belong to this function then continue. // Static local varilabes of a function does not have .auto. in their // name. They are not printed as part of function data but module // level global data. if (! isLocalToFunc(FuncName, VarName)) continue; I->setSection("fdata." + CurrentFnName + ".#"); Constant *C = I->getInitializer(); const Type *Ty = C->getType(); unsigned Size = TD->getTypePaddedSize(Ty); FrameSize += Size; // Emit memory reserve directive. O << VarName << " RES " << Size << "\n"; } // Return value can not overlap with temp data, becasue a temp slot // may be read/written after a return value is calculated and saved // within the function. if (RetSize > FrameSize) O << CurrentFnName << ".dummy" << " RES " << (RetSize - FrameSize) << "\n"; emitFunctionTempData(MF, FrameSize); }
/// DisambiguateGlobalSymbols - Give anonymous global values names. /// static void DisambiguateGlobalSymbols(Module *M) { for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (!I->hasName()) I->setName("anon_global"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->hasName()) I->setName("anon_fn"); }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) { User *Usr = *UI; assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr)); CallSite CS(cast<Instruction>(Usr)); for (unsigned i = 0; i < CS.arg_size(); ++i) assert(CS.getArgument(i) != F); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Global variables shouldn't be of the array type. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { assert(!GI->getType()->isArrayTy()); } // A function parameter or an instruction can be an array, but we don't // instrument such constructs for now. Issue a warning on such cases. for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (AI->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *AI << " is an array\n"; errs().resetColor(); } } } for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (Ins->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *Ins << " is an array\n"; errs().resetColor(); } } } } }
// dropAllReferences() - This function causes all the subelements to "let go" // of all references that they are maintaining. This allows one to 'delete' a // whole module at a time, even though there may be circular references... first // all references are dropped, and all use counts go to zero. Then everything // is deleted for real. Note that no operations are valid on an object that // has "dropped all references", except operator delete. // void Module::dropAllReferences() { for(Module::iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I) I->dropAllReferences(); for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I) I->dropAllReferences(); }
bool GlobalMerge::doInitialization(Module &M) { DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals, BSSGlobals; const DataLayout *TD = TLI->getDataLayout(); unsigned MaxOffset = TLI->getMaximalGlobalOffset(); bool Changed = false; // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal globals only if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection()) continue; PointerType *PT = dyn_cast<PointerType>(I->getType()); assert(PT && "Global variable is not a pointer!"); unsigned AddressSpace = PT->getAddressSpace(); // Ignore fancy-aligned globals for now. unsigned Alignment = TD->getPreferredAlignment(I); Type *Ty = I->getType()->getElementType(); if (Alignment > TD->getABITypeAlignment(Ty)) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; if (TD->getTypeAllocSize(Ty) < MaxOffset) { if (TargetLoweringObjectFile::getKindForGlobal(I, TLI->getTargetMachine()) .isBSSLocal()) BSSGlobals[AddressSpace].push_back(I); else if (I->isConstant()) ConstGlobals[AddressSpace].push_back(I); else Globals[AddressSpace].push_back(I); } } for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); // FIXME: This currently breaks the EH processing due to way how the // typeinfo detection works. We might want to detect the TIs and ignore // them in the future. // if (ConstGlobals.size() > 1) // Changed |= doMerge(ConstGlobals, M, true); return Changed; }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) { User *Usr = *UI; assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr)); CallSite CS(cast<Instruction>(Usr)); for (unsigned i = 0; i < CS.arg_size(); ++i) assert(CS.getArgument(i) != F); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Sequential types except pointer types shouldn't be used as the type of // an instruction, a function parameter, or a global variable. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { if (isa<SequentialType>(GI->getType())) assert(GI->getType()->isPointerTy()); } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (isa<SequentialType>(AI->getType())) assert(AI->getType()->isPointerTy()); } } for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (isa<SequentialType>(Ins->getType())) assert(Ins->getType()->isPointerTy()); } } } // We don't support multi-process programs for now. if (!HookFork) assert(M.getFunction("fork") == NULL); }
/// doInitialization - Scan the list of globals and promote any with Private /// linkage to use LinkerPrivate linkage instead. Returns true if changed. bool ARM64SetGlobalLinkage::doInitialization(Module &M) { bool Changed = false; for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasPrivateLinkage()) { I->setLinkage(llvm::GlobalValue::LinkerPrivateLinkage); Changed = true; } } return Changed; }
// Create shadow information for all global variables. void LLPEAnalysisPass::initShadowGlobals(Module& M, uint32_t extraSlots) { uint32_t i = 0; uint32_t nGlobals = std::distance(M.global_begin(), M.global_end()); // extraSlots are reserved for new globals we know will be introduced between now and specialisation start. nGlobals += extraSlots; shadowGlobals = new ShadowGV[nGlobals]; // Assign them all numbers before computing initialisers, because the initialiser can // reference another global, and getValPB will then lookup in shadowGlobalsIdx. for(Module::global_iterator it = M.global_begin(), itend = M.global_end(); it != itend; ++it, ++i) { shadowGlobals[i].G = it; shadowGlobalsIdx[it] = i; } i = 0; for(Module::global_iterator it = M.global_begin(), itend = M.global_end(); it != itend; ++it, ++i) { // getTypeStoreSize can be expensive, so do it once here. if(it->isConstant()) { shadowGlobals[i].storeSize = GlobalAA->getTypeStoreSize(shadowGlobals[i].G->getType()); continue; } // Non-constant global -- assign it a heap slot. shadowGlobals[i].allocIdx = (int32_t)heap.size(); heap.push_back(AllocData()); AllocData& AD = heap.back(); AD.allocIdx = heap.size() - 1; AD.storeSize = GlobalAA->getTypeStoreSize(it->getType()->getElementType()); AD.isCommitted = true; // This usually points to a malloc instruction -- here the global itself. AD.allocValue = ShadowValue(&(shadowGlobals[i])); AD.allocType = shadowGlobals[i].G->getType(); //errs() << "Init store for " << *it << " -> "; //printPB(errs(), *Init); //errs() << "\n"; shadowGlobals[i].storeSize = AD.storeSize; } }
/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by /// modifying predominantly internal symbols rather than external ones. /// static void DisambiguateGlobalSymbols(Module *M) { // Try not to cause collisions by minimizing chances of renaming an // already-external symbol, so take in external globals and functions as-is. // The code should work correctly without disambiguation (assuming the same // mangler is used by the two code generators), but having symbols with the // same name causes warnings to be emitted by the code generator. Mangler Mang(*M); // Agree with the CBE on symbol naming Mang.markCharUnacceptable('.'); Mang.setPreserveAsmNames(true); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) I->setName(Mang.getValueName(I)); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setName(Mang.getValueName(I)); }
/* Change linkages of global values, in order to * improve alias analysis. */ bool DeadStoreEliminationPass::changeLinkageTypes(Module &M) { DEBUG(errs() << "Changing linkages to private...\n"); for (Module::global_iterator git = M.global_begin(), gitE = M.global_end(); git != gitE; ++git) { DEBUG(errs() << " " << *git << "\n"); if (!git->hasExternalLinkage() && !git->hasAppendingLinkage()) git->setLinkage(GlobalValue::PrivateLinkage); } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (!F->isDeclaration()) { if (!F->hasExternalLinkage() && !F->hasAppendingLinkage()) F->setLinkage(GlobalValue::PrivateLinkage); DEBUG(errs() << " " << F->getName() << "\n"); } } DEBUG(errs() << "\n"); return true; }
void Preparer::replaceUndefsWithNull(Module &M) { ValueSet Replaced; for (Module::global_iterator GI = M.global_begin(); GI != M.global_end(); ++GI) { if (GI->hasInitializer()) { replaceUndefsWithNull(GI->getInitializer(), Replaced); } } for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { replaceUndefsWithNull(Ins, Replaced); } } } }
/** * Print the static class initialization method. */ void JVMWriter::printClInit() { //out << ".method public <clinit>()V\n"; out << ".method public initialiseEnvironment(Llljvm/runtime/Environment;)V\n"; printSimpleInstruction(".limit stack 5"); printSimpleInstruction(".limit locals 2"); out << "\n\t; load environment into class\n"; printSimpleInstruction("aload_0"); // this. printSimpleInstruction("aload_1"); // value printSimpleInstruction("putfield "+classname+"/__env Llljvm/runtime/Environment;"); out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printLoadMemoryToStack(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printSimpleInstruction("invokevirtual", "lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("swap"); // move this 1 down the stack printSimpleInstruction("putfield", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialise global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("getfield", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } printSimpleInstruction("return"); out << ".end method\n\n"; }
bool ARMGlobalMerge::doInitialization(Module &M) { SmallVector<GlobalVariable*, 16> Globals, ConstGlobals, BSSGlobals; const TargetData *TD = TLI->getTargetData(); unsigned MaxOffset = TLI->getMaximalGlobalOffset(); bool Changed = false; // Disable this pass on darwin. The debugger is not yet ready to extract // variable's info from a merged global. if (TLI->getTargetMachine().getSubtarget<ARMSubtarget>().isTargetDarwin()) return false; // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal globals only if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection()) continue; // Ignore fancy-aligned globals for now. if (I->getAlignment() != 0) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; if (TD->getTypeAllocSize(I->getType()->getElementType()) < MaxOffset) { const TargetLoweringObjectFile &TLOF = TLI->getObjFileLowering(); if (TLOF.getKindForGlobal(I, TLI->getTargetMachine()).isBSSLocal()) BSSGlobals.push_back(I); else if (I->isConstant()) ConstGlobals.push_back(I); else Globals.push_back(I); } } if (Globals.size() > 1) Changed |= doMerge(Globals, M, false); if (BSSGlobals.size() > 1) Changed |= doMerge(BSSGlobals, M, false); // FIXME: This currently breaks the EH processing due to way how the // typeinfo detection works. We might want to detect the TIs and ignore // them in the future. // if (ConstGlobals.size() > 1) // Changed |= doMerge(ConstGlobals, M, true); return Changed; }
/** * Print the field declarations. */ void JVMWriter::printFields() { out << "; Fields\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(i->isDeclaration()) { out << ".extern field "; externRefs.insert(i); } else out << ".field " << (i->hasLocalLinkage() ? "private " : "public ") << "static final "; out << getValueName(i) << ' ' << getTypeDescriptor(i->getType()); if(debug >= 3) out << " ; " << *i; else out << '\n'; } out << '\n'; }
/// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. Module * llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F, DenseMap<const Value*, Value*> &ValueMap) { // Make sure functions & globals are all external so that linkage // between the two modules will work. for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { if (I->hasName() && *I->getNameStart() == '\01') I->setName(I->getNameStart()+1, I->getNameLen()-1); I->setLinkage(GlobalValue::ExternalLinkage); } DenseMap<const Value*, Value*> NewValueMap; Module *New = CloneModule(M, NewValueMap); // Make sure global initializers exist only in the safe module (CBE->.so) for (Module::global_iterator I = New->global_begin(), E = New->global_end(); I != E; ++I) I->setInitializer(0); // Delete the initializer to make it external // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { Function *TNOF = cast<Function>(ValueMap[F[i]]); DEBUG(std::cerr << "Removing function "); DEBUG(WriteAsOperand(std::cerr, TNOF, false)); DEBUG(std::cerr << "\n"); TestFunctions.insert(cast<Function>(NewValueMap[TNOF])); DeleteFunctionBody(TNOF); // Function is now external in this module! } // Remove the Safe functions from the Test module for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) if (!TestFunctions.count(I)) DeleteFunctionBody(I); // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewValueMap); SplitStaticCtorDtor("llvm.global_dtors", M, New, NewValueMap); return New; }
void CaptureConstraints::identify_fixed_integers(Module &M) { ExecOnce &EO = getAnalysis<ExecOnce>(); fixed_integers.clear(); // Global variables. for (Module::global_iterator gi = M.global_begin(); gi != M.global_end(); ++gi) { if (isa<IntegerType>(gi->getType()) || isa<PointerType>(gi->getType())) { fixed_integers.insert(gi); if (gi->hasInitializer()) extract_from_consts(gi->getInitializer()); } } // Instructions and their constant operands. forallinst(M, ii) { if (EO.not_executed(ii)) continue; if (!EO.executed_once(ii)) continue; if (isa<IntegerType>(ii->getType()) || isa<PointerType>(ii->getType())) { fixed_integers.insert(ii); } // No matter reachable or not, capture its constant operands. for (unsigned i = 0; i < ii->getNumOperands(); ++i) { if (Constant *c = dyn_cast<Constant>(ii->getOperand(i))) extract_from_consts(c); } } // Function parameters. forallfunc(M, f) { if (EO.not_executed(f)) continue; if (!EO.executed_once(f)) continue; for (Function::arg_iterator ai = f->arg_begin(); ai != f->arg_end(); ++ai) { if (isa<IntegerType>(ai->getType()) || isa<PointerType>(ai->getType())) fixed_integers.insert(ai); } } }
bool ReduceCrashingGlobalVariables::TestGlobalVariables( std::vector<GlobalVariable*> &GVs) { // Clone the program to try hacking it apart... ValueMap<const Value*, Value*> VMap; Module *M = CloneModule(BD.getProgram(), VMap); // Convert list to set for fast lookup... std::set<GlobalVariable*> GVSet; for (unsigned i = 0, e = GVs.size(); i != e; ++i) { GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]); assert(CMGV && "Global Variable not in module?!"); GVSet.insert(CMGV); } outs() << "Checking for crash with only these global variables: "; PrintGlobalVariableList(GVs); outs() << ": "; // Loop over and delete any global variables which we aren't supposed to be // playing with... for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasInitializer() && !GVSet.count(I)) { I->setInitializer(0); I->setLinkage(GlobalValue::ExternalLinkage); } // Try running the hacked up program... if (TestFn(BD, M)) { BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use global variable pointers that point into the now-current // module. GVs.assign(GVSet.begin(), GVSet.end()); return true; } delete M; return false; }
static void getSymbols(Module*M, std::vector<std::string>& symbols) { // Loop over global variables for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI) if (!GI->isDeclaration() && !GI->hasLocalLinkage()) if (!GI->getName().empty()) symbols.push_back(GI->getName()); // Loop over functions for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) if (!FI->isDeclaration() && !FI->hasLocalLinkage()) if (!FI->getName().empty()) symbols.push_back(FI->getName()); // Loop over aliases for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end(); AI != AE; ++AI) { if (AI->hasName()) symbols.push_back(AI->getName()); } }
void LTOModule::lazyParseSymbols() { if ( !_symbolsParsed ) { _symbolsParsed = true; // Use mangler to add GlobalPrefix to names to match linker names. Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix()); // add functions for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { if ( f->isDeclaration() ) addPotentialUndefinedSymbol(f, mangler); else addDefinedFunctionSymbol(f, mangler); } // add data for (Module::global_iterator v = _module->global_begin(), e = _module->global_end(); v != e; ++v) { if ( v->isDeclaration() ) addPotentialUndefinedSymbol(v, mangler); else addDefinedDataSymbol(v, mangler); } // make symbols for all undefines for (StringSet::iterator it=_undefines.begin(); it != _undefines.end(); ++it) { // if this symbol also has a definition, then don't make an undefine // because it is a tentative definition if ( _defines.count(it->getKeyData(), it->getKeyData()+ it->getKeyLength()) == 0 ) { NameAndAttributes info; info.name = it->getKeyData(); info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; _symbols.push_back(info); } } } }
/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by /// modifying predominantly internal symbols rather than external ones. /// static void DisambiguateGlobalSymbols(Module *M) { // Try not to cause collisions by minimizing chances of renaming an // already-external symbol, so take in external globals and functions as-is. // The code should work correctly without disambiguation (assuming the same // mangler is used by the two code generators), but having symbols with the // same name causes warnings to be emitted by the code generator. Mangler Mang(*M); // Agree with the CBE on symbol naming Mang.markCharUnacceptable('.'); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { // Don't mangle asm names. if (!I->hasName() || I->getName()[0] != 1) I->setName(Mang.getMangledName(I)); } for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { // Don't mangle asm names or intrinsics. if ((!I->hasName() || I->getName()[0] != 1) && I->getIntrinsicID() == 0) I->setName(Mang.getMangledName(I)); } }
static Error ReduceGlobalInitializers(BugDriver &BD, bool (*TestFn)(const BugDriver &, Module *)) { if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { // Now try to reduce the number of global variable initializers in the // module to something small. Module *M = CloneModule(BD.getProgram()).release(); bool DeletedInit = false; for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasInitializer()) { DeleteGlobalInitializer(&*I); I->setLinkage(GlobalValue::ExternalLinkage); I->setComdat(nullptr); DeletedInit = true; } if (!DeletedInit) { delete M; // No change made... } else { // See if the program still causes a crash... outs() << "\nChecking to see if we can delete global inits: "; if (TestFn(BD, M)) { // Still crashes? BD.setNewProgram(M); outs() << "\n*** Able to remove all global initializers!\n"; } else { // No longer crashes? outs() << " - Removing all global inits hides problem!\n"; delete M; std::vector<GlobalVariable *> GVs; for (Module::global_iterator I = BD.getProgram()->global_begin(), E = BD.getProgram()->global_end(); I != E; ++I) if (I->hasInitializer()) GVs.push_back(&*I); if (GVs.size() > 1 && !BugpointIsInterrupted) { outs() << "\n*** Attempting to reduce the number of global " << "variables in the testcase\n"; unsigned OldSize = GVs.size(); Expected<bool> Result = ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs); if (Error E = Result.takeError()) return E; if (GVs.size() < OldSize) BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables"); } } } } return Error::success(); }