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