Home | History | Annotate | Download | only in CodeGen
      1 //===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "clang/CodeGen/BackendUtil.h"
     11 #include "clang/Basic/Diagnostic.h"
     12 #include "clang/Basic/TargetOptions.h"
     13 #include "clang/Basic/LangOptions.h"
     14 #include "clang/Frontend/CodeGenOptions.h"
     15 #include "clang/Frontend/FrontendDiagnostic.h"
     16 #include "llvm/Module.h"
     17 #include "llvm/PassManager.h"
     18 #include "llvm/Assembly/PrintModulePass.h"
     19 #include "llvm/Bitcode/ReaderWriter.h"
     20 #include "llvm/CodeGen/RegAllocRegistry.h"
     21 #include "llvm/CodeGen/SchedulerRegistry.h"
     22 #include "llvm/MC/SubtargetFeature.h"
     23 #include "llvm/Support/CommandLine.h"
     24 #include "llvm/Support/FormattedStream.h"
     25 #include "llvm/Support/PrettyStackTrace.h"
     26 #include "llvm/Support/PassManagerBuilder.h"
     27 #include "llvm/Support/Timer.h"
     28 #include "llvm/Support/raw_ostream.h"
     29 #include "llvm/Target/TargetData.h"
     30 #include "llvm/Target/TargetMachine.h"
     31 #include "llvm/Target/TargetOptions.h"
     32 #include "llvm/Target/TargetRegistry.h"
     33 #include "llvm/Transforms/Instrumentation.h"
     34 using namespace clang;
     35 using namespace llvm;
     36 
     37 namespace {
     38 
     39 class EmitAssemblyHelper {
     40   Diagnostic &Diags;
     41   const CodeGenOptions &CodeGenOpts;
     42   const TargetOptions &TargetOpts;
     43   const LangOptions &LangOpts;
     44   Module *TheModule;
     45 
     46   Timer CodeGenerationTime;
     47 
     48   mutable PassManager *CodeGenPasses;
     49   mutable PassManager *PerModulePasses;
     50   mutable FunctionPassManager *PerFunctionPasses;
     51 
     52 private:
     53   PassManager *getCodeGenPasses() const {
     54     if (!CodeGenPasses) {
     55       CodeGenPasses = new PassManager();
     56       CodeGenPasses->add(new TargetData(TheModule));
     57     }
     58     return CodeGenPasses;
     59   }
     60 
     61   PassManager *getPerModulePasses() const {
     62     if (!PerModulePasses) {
     63       PerModulePasses = new PassManager();
     64       PerModulePasses->add(new TargetData(TheModule));
     65     }
     66     return PerModulePasses;
     67   }
     68 
     69   FunctionPassManager *getPerFunctionPasses() const {
     70     if (!PerFunctionPasses) {
     71       PerFunctionPasses = new FunctionPassManager(TheModule);
     72       PerFunctionPasses->add(new TargetData(TheModule));
     73     }
     74     return PerFunctionPasses;
     75   }
     76 
     77   void CreatePasses();
     78 
     79   /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
     80   ///
     81   /// \return True on success.
     82   bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
     83 
     84 public:
     85   EmitAssemblyHelper(Diagnostic &_Diags,
     86                      const CodeGenOptions &CGOpts, const TargetOptions &TOpts,
     87                      const LangOptions &LOpts,
     88                      Module *M)
     89     : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
     90       TheModule(M), CodeGenerationTime("Code Generation Time"),
     91       CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {}
     92 
     93   ~EmitAssemblyHelper() {
     94     delete CodeGenPasses;
     95     delete PerModulePasses;
     96     delete PerFunctionPasses;
     97   }
     98 
     99   void EmitAssembly(BackendAction Action, raw_ostream *OS);
    100 };
    101 
    102 }
    103 
    104 static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
    105   if (Builder.OptLevel > 0)
    106     PM.add(createObjCARCExpandPass());
    107 }
    108 
    109 static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
    110   if (Builder.OptLevel > 0)
    111     PM.add(createObjCARCOptPass());
    112 }
    113 
    114 void EmitAssemblyHelper::CreatePasses() {
    115   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
    116   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
    117 
    118   // Handle disabling of LLVM optimization, where we want to preserve the
    119   // internal module before any optimization.
    120   if (CodeGenOpts.DisableLLVMOpts) {
    121     OptLevel = 0;
    122     Inlining = CodeGenOpts.NoInlining;
    123   }
    124 
    125   PassManagerBuilder PMBuilder;
    126   PMBuilder.OptLevel = OptLevel;
    127   PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
    128 
    129   PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls;
    130   PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
    131   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
    132 
    133   // In ObjC ARC mode, add the main ARC optimization passes.
    134   if (LangOpts.ObjCAutoRefCount) {
    135     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
    136                            addObjCARCExpandPass);
    137     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
    138                            addObjCARCOptPass);
    139   }
    140 
    141   // Figure out TargetLibraryInfo.
    142   Triple TargetTriple(TheModule->getTargetTriple());
    143   PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
    144   if (!CodeGenOpts.SimplifyLibCalls)
    145     PMBuilder.LibraryInfo->disableAllFunctions();
    146 
    147   switch (Inlining) {
    148   case CodeGenOptions::NoInlining: break;
    149   case CodeGenOptions::NormalInlining: {
    150     // FIXME: Derive these constants in a principled fashion.
    151     unsigned Threshold = 225;
    152     if (CodeGenOpts.OptimizeSize == 1)      // -Os
    153       Threshold = 75;
    154     else if (CodeGenOpts.OptimizeSize == 2) // -Oz
    155       Threshold = 25;
    156     else if (OptLevel > 2)
    157       Threshold = 275;
    158     PMBuilder.Inliner = createFunctionInliningPass(Threshold);
    159     break;
    160   }
    161   case CodeGenOptions::OnlyAlwaysInlining:
    162     // Respect always_inline.
    163     PMBuilder.Inliner = createAlwaysInlinerPass();
    164     break;
    165   }
    166 
    167 
    168   // Set up the per-function pass manager.
    169   FunctionPassManager *FPM = getPerFunctionPasses();
    170   if (CodeGenOpts.VerifyModule)
    171     FPM->add(createVerifierPass());
    172   PMBuilder.populateFunctionPassManager(*FPM);
    173 
    174   // Set up the per-module pass manager.
    175   PassManager *MPM = getPerModulePasses();
    176 
    177   if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {
    178     MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,
    179                                     CodeGenOpts.EmitGcovArcs,
    180                                     TargetTriple.isMacOSX()));
    181 
    182     if (!CodeGenOpts.DebugInfo)
    183       MPM->add(createStripSymbolsPass(true));
    184   }
    185 
    186 
    187   PMBuilder.populateModulePassManager(*MPM);
    188 }
    189 
    190 bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
    191                                        formatted_raw_ostream &OS) {
    192   // Create the TargetMachine for generating code.
    193   std::string Error;
    194   std::string Triple = TheModule->getTargetTriple();
    195   const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
    196   if (!TheTarget) {
    197     Diags.Report(diag::err_fe_unable_to_create_target) << Error;
    198     return false;
    199   }
    200 
    201   // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
    202   // being gross, this is also totally broken if we ever care about
    203   // concurrency.
    204 
    205   // Set frame pointer elimination mode.
    206   if (!CodeGenOpts.DisableFPElim) {
    207     llvm::NoFramePointerElim = false;
    208     llvm::NoFramePointerElimNonLeaf = false;
    209   } else if (CodeGenOpts.OmitLeafFramePointer) {
    210     llvm::NoFramePointerElim = false;
    211     llvm::NoFramePointerElimNonLeaf = true;
    212   } else {
    213     llvm::NoFramePointerElim = true;
    214     llvm::NoFramePointerElimNonLeaf = true;
    215   }
    216 
    217   // Set float ABI type.
    218   if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp")
    219     llvm::FloatABIType = llvm::FloatABI::Soft;
    220   else if (CodeGenOpts.FloatABI == "hard")
    221     llvm::FloatABIType = llvm::FloatABI::Hard;
    222   else {
    223     assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
    224     llvm::FloatABIType = llvm::FloatABI::Default;
    225   }
    226 
    227   llvm::LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
    228   llvm::NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
    229   llvm::NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
    230   NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
    231   llvm::UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
    232   llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
    233 
    234   TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
    235 
    236   TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
    237   TargetMachine::setDataSections    (CodeGenOpts.DataSections);
    238 
    239   // FIXME: Parse this earlier.
    240   if (CodeGenOpts.CodeModel == "small") {
    241     TargetMachine::setCodeModel(llvm::CodeModel::Small);
    242   } else if (CodeGenOpts.CodeModel == "kernel") {
    243     TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
    244   } else if (CodeGenOpts.CodeModel == "medium") {
    245     TargetMachine::setCodeModel(llvm::CodeModel::Medium);
    246   } else if (CodeGenOpts.CodeModel == "large") {
    247     TargetMachine::setCodeModel(llvm::CodeModel::Large);
    248   } else {
    249     assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
    250     TargetMachine::setCodeModel(llvm::CodeModel::Default);
    251   }
    252 
    253   std::vector<const char *> BackendArgs;
    254   BackendArgs.push_back("clang"); // Fake program name.
    255   if (!CodeGenOpts.DebugPass.empty()) {
    256     BackendArgs.push_back("-debug-pass");
    257     BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
    258   }
    259   if (!CodeGenOpts.LimitFloatPrecision.empty()) {
    260     BackendArgs.push_back("-limit-float-precision");
    261     BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
    262   }
    263   if (llvm::TimePassesIsEnabled)
    264     BackendArgs.push_back("-time-passes");
    265   for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
    266     BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
    267   BackendArgs.push_back(0);
    268   llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
    269                                     const_cast<char **>(&BackendArgs[0]));
    270 
    271   std::string FeaturesStr;
    272   if (TargetOpts.Features.size()) {
    273     SubtargetFeatures Features;
    274     for (std::vector<std::string>::const_iterator
    275            it = TargetOpts.Features.begin(),
    276            ie = TargetOpts.Features.end(); it != ie; ++it)
    277       Features.AddFeature(*it);
    278     FeaturesStr = Features.getString();
    279   }
    280 
    281   llvm::Reloc::Model RM = llvm::Reloc::Default;
    282   if (CodeGenOpts.RelocationModel == "static") {
    283     RM = llvm::Reloc::Static;
    284   } else if (CodeGenOpts.RelocationModel == "pic") {
    285     RM = llvm::Reloc::PIC_;
    286   } else {
    287     assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
    288            "Invalid PIC model!");
    289     RM = llvm::Reloc::DynamicNoPIC;
    290   }
    291 
    292   TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
    293                                                      FeaturesStr, RM);
    294 
    295   if (CodeGenOpts.RelaxAll)
    296     TM->setMCRelaxAll(true);
    297   if (CodeGenOpts.SaveTempLabels)
    298     TM->setMCSaveTempLabels(true);
    299   if (CodeGenOpts.NoDwarf2CFIAsm)
    300     TM->setMCUseCFI(false);
    301   if (CodeGenOpts.NoExecStack)
    302     TM->setMCNoExecStack(true);
    303 
    304   // Create the code generator passes.
    305   PassManager *PM = getCodeGenPasses();
    306   CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
    307 
    308   switch (CodeGenOpts.OptimizationLevel) {
    309   default: break;
    310   case 0: OptLevel = CodeGenOpt::None; break;
    311   case 3: OptLevel = CodeGenOpt::Aggressive; break;
    312   }
    313 
    314   // Normal mode, emit a .s or .o file by running the code generator. Note,
    315   // this also adds codegenerator level optimization passes.
    316   TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
    317   if (Action == Backend_EmitObj)
    318     CGFT = TargetMachine::CGFT_ObjectFile;
    319   else if (Action == Backend_EmitMCNull)
    320     CGFT = TargetMachine::CGFT_Null;
    321   else
    322     assert(Action == Backend_EmitAssembly && "Invalid action!");
    323 
    324   // Add ObjC ARC final-cleanup optimizations. This is done as part of the
    325   // "codegen" passes so that it isn't run multiple times when there is
    326   // inlining happening.
    327   if (LangOpts.ObjCAutoRefCount)
    328     PM->add(createObjCARCContractPass());
    329 
    330   if (TM->addPassesToEmitFile(*PM, OS, CGFT, OptLevel,
    331                               /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
    332     Diags.Report(diag::err_fe_unable_to_interface_with_target);
    333     return false;
    334   }
    335 
    336   return true;
    337 }
    338 
    339 void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
    340   TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
    341   llvm::formatted_raw_ostream FormattedOS;
    342 
    343   CreatePasses();
    344   switch (Action) {
    345   case Backend_EmitNothing:
    346     break;
    347 
    348   case Backend_EmitBC:
    349     getPerModulePasses()->add(createBitcodeWriterPass(*OS));
    350     break;
    351 
    352   case Backend_EmitLL:
    353     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
    354     getPerModulePasses()->add(createPrintModulePass(&FormattedOS));
    355     break;
    356 
    357   default:
    358     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
    359     if (!AddEmitPasses(Action, FormattedOS))
    360       return;
    361   }
    362 
    363   // Before executing passes, print the final values of the LLVM options.
    364   cl::PrintOptionValues();
    365 
    366   // Run passes. For now we do all passes at once, but eventually we
    367   // would like to have the option of streaming code generation.
    368 
    369   if (PerFunctionPasses) {
    370     PrettyStackTraceString CrashInfo("Per-function optimization");
    371 
    372     PerFunctionPasses->doInitialization();
    373     for (Module::iterator I = TheModule->begin(),
    374            E = TheModule->end(); I != E; ++I)
    375       if (!I->isDeclaration())
    376         PerFunctionPasses->run(*I);
    377     PerFunctionPasses->doFinalization();
    378   }
    379 
    380   if (PerModulePasses) {
    381     PrettyStackTraceString CrashInfo("Per-module optimization passes");
    382     PerModulePasses->run(*TheModule);
    383   }
    384 
    385   if (CodeGenPasses) {
    386     PrettyStackTraceString CrashInfo("Code generation");
    387     CodeGenPasses->run(*TheModule);
    388   }
    389 }
    390 
    391 void clang::EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
    392                               const TargetOptions &TOpts,
    393                               const LangOptions &LOpts,
    394                               Module *M,
    395                               BackendAction Action, raw_ostream *OS) {
    396   EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
    397 
    398   AsmHelper.EmitAssembly(Action, OS);
    399 }
    400