/// Emit extern decls for functions imported from other modules, and emit /// global declarations for function defined in this module and which are /// available to other modules. /// void PIC16AsmPrinter::EmitFunctionDecls(Module &M) { // Emit declarations for external functions. O <<"\n"<<TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { if (I->isIntrinsic()) continue; std::string Name = Mang->getMangledName(I); if (Name.compare("@abort") == 0) continue; if (!I->isDeclaration() && !I->hasExternalLinkage()) continue; // Do not emit memcpy, memset, and memmove here. // Calls to these routines can be generated in two ways, // 1. User calling the standard lib function // 2. Codegen generating these calls for llvm intrinsics. // In the first case a prototype is alread availale, while in // second case the call is via and externalsym and the prototype is missing. // So declarations for these are currently always getting printing by // tracking both kind of references in printInstrunction. if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue; const char *directive = I->isDeclaration() ? TAI->getExternDirective() : TAI->getGlobalDirective(); O << directive << Name << "\n"; O << directive << PAN::getRetvalLabel(Name) << "\n"; O << directive << PAN::getArgsLabel(Name) << "\n"; } O << TAI->getCommentString() << "Function Declarations - END." <<"\n"; }
// Emit extern decls for functions imported from other modules, and emit // global declarations for function defined in this module and which are // available to other modules. void PIC16AsmPrinter::EmitFunctionDecls (Module &M) { // Emit declarations for external functions. O << TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { std::string Name = Mang->getValueName(I); if (Name.compare("@abort") == 0) continue; // If it is llvm intrinsic call then don't emit if (Name.find("llvm.") != std::string::npos) continue; if (! (I->isDeclaration() || I->hasExternalLinkage())) continue; const char *directive = I->isDeclaration() ? TAI->getExternDirective() : TAI->getGlobalDirective(); O << directive << Name << "\n"; O << directive << PAN::getRetvalLabel(Name) << "\n"; O << directive << PAN::getArgsLabel(Name) << "\n"; } O << TAI->getCommentString() << "Function Declarations - END." <<"\n"; }
bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; std::map<unsigned long, std::vector<Function *> > FnMap; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration() || F->isIntrinsic()) continue; if (!F->hasLocalLinkage() && !F->hasExternalLinkage() && !F->hasWeakLinkage()) continue; if (hasAddressTaken(F)) continue; FnMap[hash(F)].push_back(F); } // TODO: instead of running in a loop, we could also fold functions in callgraph // order. Constructing the CFG probably isn't cheaper than just running in a loop. bool LocalChanged; do { LocalChanged = false; for (std::map<unsigned long, std::vector<Function *> >::iterator I = FnMap.begin(), E = FnMap.end(); I != E; ++I) { DOUT << "size: " << FnMap.size() << "\n"; std::vector<Function *> &FnVec = I->second; DOUT << "hash (" << I->first << "): " << FnVec.size() << "\n"; for (int i = 0, e = FnVec.size(); i != e; ++i) { for (int j = i + 1; j != e; ++j) { bool isEqual = equals(FnVec[i], FnVec[j]); DOUT << " " << FnVec[i]->getName() << (isEqual ? " == " : " != ") << FnVec[j]->getName() << "\n"; if (isEqual) { if (fold(FnVec, i, j)) { LocalChanged = true; FnVec.erase(FnVec.begin() + j); --j, --e; } } } } } Changed |= LocalChanged; } while (LocalChanged); return Changed; }
/* 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 PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) { // Emit declarations for external functions. O << "section.0" <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { std::string Name = Mang->getValueName(I); if (Name.compare("abort") == 0) continue; if (I->isDeclaration()) { O << "\textern " <<Name << "\n"; O << "\textern " << Name << ".retval\n"; O << "\textern " << Name << ".args\n"; } else if (I->hasExternalLinkage()) { O << "\tglobal " << Name << "\n"; O << "\tglobal " << Name << ".retval\n"; O << "\tglobal " << Name << ".args\n"; } } // Emit header file to include declaration of library functions O << "\t#include C16IntrinsicCalls.INC\n"; // Emit declarations for external globals. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; I++) { // Any variables reaching here with ".auto." in its name is a local scope // variable and should not be printed in global data section. std::string Name = Mang->getValueName(I); if (isLocalName (Name)) continue; if (I->isDeclaration()) O << "\textern "<< Name << "\n"; else if (I->hasCommonLinkage() || I->hasExternalLinkage()) O << "\tglobal "<< Name << "\n"; } }