bool MipsOs16::runOnModule(Module &M) { DEBUG(errs() << "Run on Module MipsOs16\n"); bool modified = false; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; DEBUG(dbgs() << "Working on " << F->getName() << "\n"); if (needsFP(*F)) { DEBUG(dbgs() << " need to compile as nomips16 \n"); F->addFnAttr("nomips16"); } else { F->addFnAttr("mips16"); DEBUG(dbgs() << " no need to compile as nomips16 \n"); } } return modified; }
bool AddAlwaysInlineAttributePass::runOnModule(Module &M) { bool modified = false; for (Module::iterator funcIt = M.begin(); funcIt != M.end(); ++funcIt) { if (std::find(targetFunctions.begin(), targetFunctions.end(), funcIt->getName()) != targetFunctions.end()) { funcIt->addFnAttr(Attribute::AlwaysInline); modified = true; } } return modified; }
bool MipsOs16::runOnModule(Module &M) { bool usingMask = Mips32FunctionMask.length() > 0; bool doneUsingMask = false; // this will make it stop repeating DEBUG(dbgs() << "Run on Module MipsOs16 \n" << Mips32FunctionMask << "\n"); if (usingMask) DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n"); unsigned int functionIndex = 0; bool modified = false; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; DEBUG(dbgs() << "Working on " << F->getName() << "\n"); if (usingMask) { if (!doneUsingMask) { if (functionIndex == Mips32FunctionMask.length()) functionIndex = 0; switch (Mips32FunctionMask[functionIndex]) { case '1': DEBUG(dbgs() << "mask forced mips32: " << F->getName() << "\n"); F->addFnAttr("nomips16"); break; case '.': doneUsingMask = true; break; default: break; } functionIndex++; } } else { if (needsFP(*F)) { DEBUG(dbgs() << "os16 forced mips32: " << F->getName() << "\n"); F->addFnAttr("nomips16"); } else { DEBUG(dbgs() << "os16 forced mips16: " << F->getName() << "\n"); F->addFnAttr("mips16"); } } } return modified; }
std::vector<Function*> functions(Module &M) { std::vector<Function*> functions; for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (!F->isDeclaration()) { F->addFnAttr("kernel"); } functions.push_back(F); } return functions; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllAsmPrinters(); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); // Load the module to be compiled... SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } Module &mod = *M.get(); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod.setTargetTriple(TargetTriple); Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); // Allocate target machine. First, check whether the user has explicitly // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. const Target *TheTarget = 0; if (!MArch.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { if (MArch == it->getName()) { TheTarget = &*it; break; } } if (!TheTarget) { errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; return 1; } // Adjust the triple to match (if known), otherwise stick with the // module/host triple. Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); if (Type != Triple::UnknownArch) TheTriple.setArch(Type); } else { std::string Err; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); if (TheTarget == 0) { errs() << argv[0] << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MCPU.size() || MAttrs.size()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); // Figure out where we are going to send the output... formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]); if (Out == 0) return 1; CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } // Request that addPassesToEmitFile run the Verifier after running // passes which modify the IR. #ifndef NDEBUG bool DisableVerify = false; #else bool DisableVerify = true; #endif // If this target requires addPassesToEmitWholeFile, do it now. This is // used by strange things like the C backend. if (Target.WantsWholeFile()) { PassManager PM; // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(&mod)); if (!NoVerify) PM.add(createVerifierPass()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl, DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } PM.run(mod); } else { // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(M.get()); // Add the target data from the target machine, if it exists, or the module. if (const TargetData *TD = Target.getTargetData()) Passes.add(new TargetData(*TD)); else Passes.add(new TargetData(&mod)); #ifndef NDEBUG if (!NoVerify) Passes.add(createVerifierPass()); #endif // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl, DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. // TODO: this could lazily stream functions out of the module. for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) if (!I->isDeclaration()) { if (DisableRedZone) I->addFnAttr(Attribute::NoRedZone); if (NoImplicitFloats) I->addFnAttr(Attribute::NoImplicitFloat); Passes.run(*I); } Passes.doFinalization(); } // Delete the ostream if it's not a stdout stream if (Out != &fouts()) delete Out; return 0; }