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"; } } }
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; }
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); }
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); } } } }
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); } } }
static int runCompilePasses(Module *ModuleRef, unsigned ModuleIndex, ThreadedFunctionQueue *FuncQueue, const Triple &TheTriple, TargetMachine &Target, StringRef ProgramName, raw_pwrite_stream &OS){ PNaClABIErrorReporter ABIErrorReporter; if (SplitModuleCount > 1 || ExternalizeAll) { // Add function and global names, and give them external linkage. // This relies on LLVM's consistent auto-generation of names, we could // maybe do our own in case something changes there. for (Function &F : *ModuleRef) { if (!F.hasName()) F.setName("Function"); if (F.hasInternalLinkage()) F.setLinkage(GlobalValue::ExternalLinkage); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->hasName()) GI->setName("Global"); if (GI->hasInternalLinkage()) GI->setLinkage(GlobalValue::ExternalLinkage); } if (ModuleIndex > 0) { // Remove the initializers for all global variables, turning them into // declarations. for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { assert(GI->hasInitializer() && "Global variable missing initializer"); Constant *Init = GI->getInitializer(); GI->setInitializer(nullptr); if (Init->getNumUses() == 0) Init->destroyConstant(); } } } // Make all non-weak symbols hidden for better code. We cannot do // this for weak symbols. The linker complains when some weak // symbols are not resolved. for (Function &F : *ModuleRef) { if (!F.isWeakForLinker() && !F.hasLocalLinkage()) F.setVisibility(GlobalValue::HiddenVisibility); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) GI->setVisibility(GlobalValue::HiddenVisibility); } // Build up all of the passes that we want to do to the module. std::unique_ptr<legacy::PassManagerBase> PM; if (LazyBitcode) PM.reset(new legacy::FunctionPassManager(ModuleRef)); else PM.reset(new legacy::PassManager()); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getDataLayout()) ModuleRef->setDataLayout(*DL); // For conformance with llc, we let the user disable LLVM IR verification with // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only // run it once, before PNaCl ABI verification. if (!NoVerify) PM->add(createVerifierPass()); // Add the ABI verifier pass before the analysis and code emission passes. if (PNaClABIVerify) PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); // Add the intrinsic resolution pass. It assumes ABI-conformant code. PM->add(createResolvePNaClIntrinsicsPass()); // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(TheTriple); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM->add(new TargetLibraryInfoWrapperPass(TLII)); // Allow subsequent passes and the backend to better optimize instructions // that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo // above. PM->add(createBackendCanonicalizePass()); // Ask the target to add backend passes as necessary. We explicitly ask it // not to add the verifier pass because we added it earlier. if (Target.addPassesToEmitFile(*PM, OS, FileType, /* DisableVerify */ true)) { errs() << ProgramName << ": target does not support generation of this file type!\n"; return 1; } if (LazyBitcode) { auto FPM = static_cast<legacy::FunctionPassManager *>(PM.get()); FPM->doInitialization(); unsigned FuncIndex = 0; switch (SplitModuleSched) { case SplitModuleStatic: for (Function &F : *ModuleRef) { if (FuncQueue->GrabFunctionStatic(FuncIndex, ModuleIndex)) { FPM->run(F); CheckABIVerifyErrors(ABIErrorReporter, "Function " + F.getName()); F.Dematerialize(); } ++FuncIndex; } break; case SplitModuleDynamic: unsigned ChunkSize = 0; unsigned NumFunctions = FuncQueue->Size(); Module::iterator I = ModuleRef->begin(); while (FuncIndex < NumFunctions) { ChunkSize = FuncQueue->RecommendedChunkSize(); unsigned NextIndex; bool grabbed = FuncQueue->GrabFunctionDynamic(FuncIndex, ChunkSize, NextIndex); if (grabbed) { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } FPM->run(*I); CheckABIVerifyErrors(ABIErrorReporter, "Function " + I->getName()); I->Dematerialize(); ++FuncIndex; ++I; } } else { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } ++FuncIndex; ++I; } } } break; } FPM->doFinalization(); } else static_cast<legacy::PassManager *>(PM.get())->run(*ModuleRef); return 0; }
bool GlobalDCE::runOnModule(Module &M) { bool Changed = false; // Remove empty functions from the global ctors list. Changed |= optimizeGlobalCtorsList(M, isEmptyFunction); // Loop over the module, adding globals which are obviously necessary. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Functions with external linkage are needed if they have a body if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { if (!I->isDiscardableIfUnused()) GlobalIsNeeded(I); } } for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Externally visible & appending globals are needed, if they have an // initializer. if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { if (!I->isDiscardableIfUnused()) GlobalIsNeeded(I); } } for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Externally visible aliases are needed. if (!I->isDiscardableIfUnused()) { GlobalIsNeeded(I); } } // Now that all globals which are needed are in the AliveGlobals set, we loop // through the program, deleting those which are not alive. // // The first pass is to drop initializers of global variables which are dead. std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadGlobalVars.push_back(I); // Keep track of dead globals if (I->hasInitializer()) { Constant *Init = I->getInitializer(); I->setInitializer(nullptr); if (isSafeToDestroyConstant(Init)) Init->destroyConstant(); } } // The second pass drops the bodies of functions which are dead... std::vector<Function*> DeadFunctions; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadFunctions.push_back(I); // Keep track of dead globals if (!I->isDeclaration()) I->deleteBody(); } // The third pass drops targets of aliases which are dead... std::vector<GlobalAlias*> DeadAliases; for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!AliveGlobals.count(I)) { DeadAliases.push_back(I); I->setAliasee(nullptr); } if (!DeadFunctions.empty()) { // Now that all interferences have been dropped, delete the actual objects // themselves. for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadFunctions[i]); M.getFunctionList().erase(DeadFunctions[i]); } NumFunctions += DeadFunctions.size(); Changed = true; } if (!DeadGlobalVars.empty()) { for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadGlobalVars[i]); M.getGlobalList().erase(DeadGlobalVars[i]); } NumVariables += DeadGlobalVars.size(); Changed = true; } // Now delete any dead aliases. if (!DeadAliases.empty()) { for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadAliases[i]); M.getAliasList().erase(DeadAliases[i]); } NumAliases += DeadAliases.size(); Changed = true; } // Make sure that all memory is released AliveGlobals.clear(); SeenConstants.clear(); return Changed; }
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) { std::vector<Type*> FieldBssTypes; std::vector<Type*> FieldInitTypes; std::vector<Constant*> FieldInitValues; PassState State(&M); for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal()) { if (!GV->hasInitializer()) { // Since this is a whole-program transformation, "extern" TLS // variables are not allowed at this point. report_fatal_error(std::string("TLS variable without an initializer: ") + GV->getName()); } if (!GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldInitTypes, &FieldInitValues, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = false; Info.TemplateIndex = FieldInitTypes.size() - 1; TlsVars->push_back(Info); } } } // Handle zero-initialized TLS variables in a second pass, because // these should follow non-zero-initialized TLS variables. for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = true; Info.TemplateIndex = FieldBssTypes.size() - 1; TlsVars->push_back(Info); } } // Add final alignment padding so that // (struct tls_struct *) __nacl_read_tp() - 1 // gives the correct, aligned start of the TLS variables given the // x86-style layout we are using. This requires some more bytes to // be memset() to zero at runtime. This wastage doesn't seem // important gives that we're not trying to optimize packing by // reordering to put similarly-aligned variables together. padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment); // We create the TLS template structs as "packed" because we insert // alignment padding ourselves, and LLVM's implicit insertion of // padding would interfere with ours. tls_bss_template can start at // a non-aligned address immediately following the last field in // tls_init_template. StructType *InitTemplateType = StructType::create(M.getContext(), "tls_init_template"); InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true); StructType *BssTemplateType = StructType::create(M.getContext(), "tls_bss_template"); BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true); StructType *TemplateType = StructType::create(M.getContext(), "tls_struct"); SmallVector<Type*, 2> TemplateTopFields; TemplateTopFields.push_back(InitTemplateType); TemplateTopFields.push_back(BssTemplateType); TemplateType->setBody(TemplateTopFields, /*isPacked=*/true); PointerType *TemplatePtrType = PointerType::get(TemplateType, 0); // We define the following symbols, which are the same as those // defined by NaCl's original customized binutils linker scripts: // __tls_template_start // __tls_template_tdata_end // __tls_template_end // We also define __tls_template_alignment, which was not defined by // the original linker scripts. const char *StartSymbol = "__tls_template_start"; Constant *TemplateData = ConstantStruct::get(InitTemplateType, FieldInitValues); GlobalVariable *TemplateDataVar = new GlobalVariable(M, InitTemplateType, /*isConstant=*/true, GlobalValue::InternalLinkage, TemplateData); setGlobalVariableValue(M, StartSymbol, TemplateDataVar); TemplateDataVar->setName(StartSymbol); Constant *TdataEnd = ConstantExpr::getGetElementPtr( TemplateDataVar, ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd); Constant *TotalEnd = ConstantExpr::getGetElementPtr( ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType), ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_end", TotalEnd); const char *AlignmentSymbol = "__tls_template_alignment"; Type *i32 = Type::getInt32Ty(M.getContext()); GlobalVariable *AlignmentVar = new GlobalVariable( M, i32, /*isConstant=*/true, GlobalValue::InternalLinkage, ConstantInt::get(M.getContext(), APInt(32, State.Alignment))); setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar); AlignmentVar->setName(AlignmentSymbol); return TemplatePtrType; }