clang API Documentation

BackendUtil.cpp
Go to the documentation of this file.
00001 //===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "clang/CodeGen/BackendUtil.h"
00011 #include "clang/Basic/Diagnostic.h"
00012 #include "clang/Basic/TargetOptions.h"
00013 #include "clang/Basic/LangOptions.h"
00014 #include "clang/Frontend/CodeGenOptions.h"
00015 #include "clang/Frontend/FrontendDiagnostic.h"
00016 #include "llvm/Module.h"
00017 #include "llvm/PassManager.h"
00018 #include "llvm/Analysis/Verifier.h"
00019 #include "llvm/Assembly/PrintModulePass.h"
00020 #include "llvm/Bitcode/ReaderWriter.h"
00021 #include "llvm/CodeGen/RegAllocRegistry.h"
00022 #include "llvm/CodeGen/SchedulerRegistry.h"
00023 #include "llvm/MC/SubtargetFeature.h"
00024 #include "llvm/Support/CommandLine.h"
00025 #include "llvm/Support/FormattedStream.h"
00026 #include "llvm/Support/PrettyStackTrace.h"
00027 #include "llvm/Support/TargetRegistry.h"
00028 #include "llvm/Support/Timer.h"
00029 #include "llvm/Support/raw_ostream.h"
00030 #include "llvm/Target/TargetData.h"
00031 #include "llvm/Target/TargetLibraryInfo.h"
00032 #include "llvm/Target/TargetMachine.h"
00033 #include "llvm/Target/TargetOptions.h"
00034 #include "llvm/Transforms/Instrumentation.h"
00035 #include "llvm/Transforms/IPO.h"
00036 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
00037 #include "llvm/Transforms/Scalar.h"
00038 using namespace clang;
00039 using namespace llvm;
00040 
00041 namespace {
00042 
00043 class EmitAssemblyHelper {
00044   DiagnosticsEngine &Diags;
00045   const CodeGenOptions &CodeGenOpts;
00046   const clang::TargetOptions &TargetOpts;
00047   const LangOptions &LangOpts;
00048   Module *TheModule;
00049 
00050   Timer CodeGenerationTime;
00051 
00052   mutable PassManager *CodeGenPasses;
00053   mutable PassManager *PerModulePasses;
00054   mutable FunctionPassManager *PerFunctionPasses;
00055 
00056 private:
00057   PassManager *getCodeGenPasses() const {
00058     if (!CodeGenPasses) {
00059       CodeGenPasses = new PassManager();
00060       CodeGenPasses->add(new TargetData(TheModule));
00061     }
00062     return CodeGenPasses;
00063   }
00064 
00065   PassManager *getPerModulePasses() const {
00066     if (!PerModulePasses) {
00067       PerModulePasses = new PassManager();
00068       PerModulePasses->add(new TargetData(TheModule));
00069     }
00070     return PerModulePasses;
00071   }
00072 
00073   FunctionPassManager *getPerFunctionPasses() const {
00074     if (!PerFunctionPasses) {
00075       PerFunctionPasses = new FunctionPassManager(TheModule);
00076       PerFunctionPasses->add(new TargetData(TheModule));
00077     }
00078     return PerFunctionPasses;
00079   }
00080 
00081   void CreatePasses();
00082 
00083   /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
00084   ///
00085   /// \return True on success.
00086   bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
00087 
00088 public:
00089   EmitAssemblyHelper(DiagnosticsEngine &_Diags,
00090                      const CodeGenOptions &CGOpts,
00091                      const clang::TargetOptions &TOpts,
00092                      const LangOptions &LOpts,
00093                      Module *M)
00094     : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
00095       TheModule(M), CodeGenerationTime("Code Generation Time"),
00096       CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {}
00097 
00098   ~EmitAssemblyHelper() {
00099     delete CodeGenPasses;
00100     delete PerModulePasses;
00101     delete PerFunctionPasses;
00102   }
00103 
00104   void EmitAssembly(BackendAction Action, raw_ostream *OS);
00105 };
00106 
00107 }
00108 
00109 static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
00110   if (Builder.OptLevel > 0)
00111     PM.add(createObjCARCAPElimPass());
00112 }
00113 
00114 static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
00115   if (Builder.OptLevel > 0)
00116     PM.add(createObjCARCExpandPass());
00117 }
00118 
00119 static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
00120   if (Builder.OptLevel > 0)
00121     PM.add(createObjCARCOptPass());
00122 }
00123 
00124 static void addAddressSanitizerPass(const PassManagerBuilder &Builder,
00125                                     PassManagerBase &PM) {
00126   PM.add(createAddressSanitizerPass());
00127 }
00128 
00129 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
00130                                    PassManagerBase &PM) {
00131   PM.add(createThreadSanitizerPass());
00132 }
00133 
00134 void EmitAssemblyHelper::CreatePasses() {
00135   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
00136   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
00137 
00138   // Handle disabling of LLVM optimization, where we want to preserve the
00139   // internal module before any optimization.
00140   if (CodeGenOpts.DisableLLVMOpts) {
00141     OptLevel = 0;
00142     Inlining = CodeGenOpts.NoInlining;
00143   }
00144   
00145   PassManagerBuilder PMBuilder;
00146   PMBuilder.OptLevel = OptLevel;
00147   PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
00148 
00149   PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls;
00150   PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
00151   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
00152 
00153   // In ObjC ARC mode, add the main ARC optimization passes.
00154   if (LangOpts.ObjCAutoRefCount) {
00155     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
00156                            addObjCARCExpandPass);
00157     PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
00158                            addObjCARCAPElimPass);
00159     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
00160                            addObjCARCOptPass);
00161   }
00162 
00163   if (LangOpts.AddressSanitizer) {
00164     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
00165                            addAddressSanitizerPass);
00166     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
00167                            addAddressSanitizerPass);
00168   }
00169 
00170   if (LangOpts.ThreadSanitizer) {
00171     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
00172                            addThreadSanitizerPass);
00173     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
00174                            addThreadSanitizerPass);
00175   }
00176 
00177   // Figure out TargetLibraryInfo.
00178   Triple TargetTriple(TheModule->getTargetTriple());
00179   PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
00180   if (!CodeGenOpts.SimplifyLibCalls)
00181     PMBuilder.LibraryInfo->disableAllFunctions();
00182   
00183   switch (Inlining) {
00184   case CodeGenOptions::NoInlining: break;
00185   case CodeGenOptions::NormalInlining: {
00186     // FIXME: Derive these constants in a principled fashion.
00187     unsigned Threshold = 225;
00188     if (CodeGenOpts.OptimizeSize == 1)      // -Os
00189       Threshold = 75;
00190     else if (CodeGenOpts.OptimizeSize == 2) // -Oz
00191       Threshold = 25;
00192     else if (OptLevel > 2)
00193       Threshold = 275;
00194     PMBuilder.Inliner = createFunctionInliningPass(Threshold);
00195     break;
00196   }
00197   case CodeGenOptions::OnlyAlwaysInlining:
00198     // Respect always_inline.
00199     if (OptLevel == 0)
00200       // Do not insert lifetime intrinsics at -O0.
00201       PMBuilder.Inliner = createAlwaysInlinerPass(false);
00202     else
00203       PMBuilder.Inliner = createAlwaysInlinerPass();
00204     break;
00205   }
00206 
00207  
00208   // Set up the per-function pass manager.
00209   FunctionPassManager *FPM = getPerFunctionPasses();
00210   if (CodeGenOpts.VerifyModule)
00211     FPM->add(createVerifierPass());
00212   PMBuilder.populateFunctionPassManager(*FPM);
00213 
00214   // Set up the per-module pass manager.
00215   PassManager *MPM = getPerModulePasses();
00216 
00217   if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {
00218     MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,
00219                                     CodeGenOpts.EmitGcovArcs,
00220                                     TargetTriple.isMacOSX()));
00221 
00222     if (CodeGenOpts.DebugInfo == CodeGenOptions::NoDebugInfo)
00223       MPM->add(createStripSymbolsPass(true));
00224   }
00225   
00226   
00227   PMBuilder.populateModulePassManager(*MPM);
00228 }
00229 
00230 bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
00231                                        formatted_raw_ostream &OS) {
00232   // Create the TargetMachine for generating code.
00233   std::string Error;
00234   std::string Triple = TheModule->getTargetTriple();
00235   const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
00236   if (!TheTarget) {
00237     Diags.Report(diag::err_fe_unable_to_create_target) << Error;
00238     return false;
00239   }
00240 
00241   // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
00242   // being gross, this is also totally broken if we ever care about
00243   // concurrency.
00244 
00245   TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
00246 
00247   TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
00248   TargetMachine::setDataSections    (CodeGenOpts.DataSections);
00249 
00250   // FIXME: Parse this earlier.
00251   llvm::CodeModel::Model CM;
00252   if (CodeGenOpts.CodeModel == "small") {
00253     CM = llvm::CodeModel::Small;
00254   } else if (CodeGenOpts.CodeModel == "kernel") {
00255     CM = llvm::CodeModel::Kernel;
00256   } else if (CodeGenOpts.CodeModel == "medium") {
00257     CM = llvm::CodeModel::Medium;
00258   } else if (CodeGenOpts.CodeModel == "large") {
00259     CM = llvm::CodeModel::Large;
00260   } else {
00261     assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
00262     CM = llvm::CodeModel::Default;
00263   }
00264 
00265   SmallVector<const char *, 16> BackendArgs;
00266   BackendArgs.push_back("clang"); // Fake program name.
00267   if (!CodeGenOpts.DebugPass.empty()) {
00268     BackendArgs.push_back("-debug-pass");
00269     BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
00270   }
00271   if (!CodeGenOpts.LimitFloatPrecision.empty()) {
00272     BackendArgs.push_back("-limit-float-precision");
00273     BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
00274   }
00275   if (llvm::TimePassesIsEnabled)
00276     BackendArgs.push_back("-time-passes");
00277   for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
00278     BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
00279   if (CodeGenOpts.NoGlobalMerge)
00280     BackendArgs.push_back("-global-merge=false");
00281   BackendArgs.push_back(0);
00282   llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
00283                                     BackendArgs.data());
00284 
00285   std::string FeaturesStr;
00286   if (TargetOpts.Features.size()) {
00287     SubtargetFeatures Features;
00288     for (std::vector<std::string>::const_iterator
00289            it = TargetOpts.Features.begin(),
00290            ie = TargetOpts.Features.end(); it != ie; ++it)
00291       Features.AddFeature(*it);
00292     FeaturesStr = Features.getString();
00293   }
00294 
00295   llvm::Reloc::Model RM = llvm::Reloc::Default;
00296   if (CodeGenOpts.RelocationModel == "static") {
00297     RM = llvm::Reloc::Static;
00298   } else if (CodeGenOpts.RelocationModel == "pic") {
00299     RM = llvm::Reloc::PIC_;
00300   } else {
00301     assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
00302            "Invalid PIC model!");
00303     RM = llvm::Reloc::DynamicNoPIC;
00304   }
00305 
00306   CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
00307   switch (CodeGenOpts.OptimizationLevel) {
00308   default: break;
00309   case 0: OptLevel = CodeGenOpt::None; break;
00310   case 3: OptLevel = CodeGenOpt::Aggressive; break;
00311   }
00312 
00313   llvm::TargetOptions Options;
00314 
00315   // Set frame pointer elimination mode.
00316   if (!CodeGenOpts.DisableFPElim) {
00317     Options.NoFramePointerElim = false;
00318     Options.NoFramePointerElimNonLeaf = false;
00319   } else if (CodeGenOpts.OmitLeafFramePointer) {
00320     Options.NoFramePointerElim = false;
00321     Options.NoFramePointerElimNonLeaf = true;
00322   } else {
00323     Options.NoFramePointerElim = true;
00324     Options.NoFramePointerElimNonLeaf = true;
00325   }
00326 
00327   // Set float ABI type.
00328   if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp")
00329     Options.FloatABIType = llvm::FloatABI::Soft;
00330   else if (CodeGenOpts.FloatABI == "hard")
00331     Options.FloatABIType = llvm::FloatABI::Hard;
00332   else {
00333     assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
00334     Options.FloatABIType = llvm::FloatABI::Default;
00335   }
00336 
00337   Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
00338   Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
00339   Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
00340   Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
00341   Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
00342   Options.UseSoftFloat = CodeGenOpts.SoftFloat;
00343   Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
00344   Options.RealignStack = CodeGenOpts.StackRealignment;
00345   Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
00346   Options.TrapFuncName = CodeGenOpts.TrapFuncName;
00347   Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
00348 
00349   TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
00350                                                      FeaturesStr, Options,
00351                                                      RM, CM, OptLevel);
00352 
00353   if (CodeGenOpts.RelaxAll)
00354     TM->setMCRelaxAll(true);
00355   if (CodeGenOpts.SaveTempLabels)
00356     TM->setMCSaveTempLabels(true);
00357   if (CodeGenOpts.NoDwarf2CFIAsm)
00358     TM->setMCUseCFI(false);
00359   if (!CodeGenOpts.NoDwarfDirectoryAsm)
00360     TM->setMCUseDwarfDirectory(true);
00361   if (CodeGenOpts.NoExecStack)
00362     TM->setMCNoExecStack(true);
00363 
00364   // Create the code generator passes.
00365   PassManager *PM = getCodeGenPasses();
00366 
00367   // Add LibraryInfo.
00368   TargetLibraryInfo *TLI = new TargetLibraryInfo();
00369   if (!CodeGenOpts.SimplifyLibCalls)
00370     TLI->disableAllFunctions();
00371   PM->add(TLI);
00372 
00373   // Normal mode, emit a .s or .o file by running the code generator. Note,
00374   // this also adds codegenerator level optimization passes.
00375   TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
00376   if (Action == Backend_EmitObj)
00377     CGFT = TargetMachine::CGFT_ObjectFile;
00378   else if (Action == Backend_EmitMCNull)
00379     CGFT = TargetMachine::CGFT_Null;
00380   else
00381     assert(Action == Backend_EmitAssembly && "Invalid action!");
00382 
00383   // Add ObjC ARC final-cleanup optimizations. This is done as part of the
00384   // "codegen" passes so that it isn't run multiple times when there is
00385   // inlining happening.
00386   if (LangOpts.ObjCAutoRefCount &&
00387       CodeGenOpts.OptimizationLevel > 0)
00388     PM->add(createObjCARCContractPass());
00389 
00390   if (TM->addPassesToEmitFile(*PM, OS, CGFT,
00391                               /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
00392     Diags.Report(diag::err_fe_unable_to_interface_with_target);
00393     return false;
00394   }
00395 
00396   return true;
00397 }
00398 
00399 void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
00400   TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
00401   llvm::formatted_raw_ostream FormattedOS;
00402 
00403   CreatePasses();
00404   switch (Action) {
00405   case Backend_EmitNothing:
00406     break;
00407 
00408   case Backend_EmitBC:
00409     getPerModulePasses()->add(createBitcodeWriterPass(*OS));
00410     break;
00411 
00412   case Backend_EmitLL:
00413     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
00414     getPerModulePasses()->add(createPrintModulePass(&FormattedOS));
00415     break;
00416 
00417   default:
00418     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
00419     if (!AddEmitPasses(Action, FormattedOS))
00420       return;
00421   }
00422 
00423   // Before executing passes, print the final values of the LLVM options.
00424   cl::PrintOptionValues();
00425 
00426   // Run passes. For now we do all passes at once, but eventually we
00427   // would like to have the option of streaming code generation.
00428 
00429   if (PerFunctionPasses) {
00430     PrettyStackTraceString CrashInfo("Per-function optimization");
00431 
00432     PerFunctionPasses->doInitialization();
00433     for (Module::iterator I = TheModule->begin(),
00434            E = TheModule->end(); I != E; ++I)
00435       if (!I->isDeclaration())
00436         PerFunctionPasses->run(*I);
00437     PerFunctionPasses->doFinalization();
00438   }
00439 
00440   if (PerModulePasses) {
00441     PrettyStackTraceString CrashInfo("Per-module optimization passes");
00442     PerModulePasses->run(*TheModule);
00443   }
00444 
00445   if (CodeGenPasses) {
00446     PrettyStackTraceString CrashInfo("Code generation");
00447     CodeGenPasses->run(*TheModule);
00448   }
00449 }
00450 
00451 void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
00452                               const CodeGenOptions &CGOpts,
00453                               const clang::TargetOptions &TOpts,
00454                               const LangOptions &LOpts,
00455                               Module *M,
00456                               BackendAction Action, raw_ostream *OS) {
00457   EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
00458 
00459   AsmHelper.EmitAssembly(Action, OS);
00460 }