zcov: / lib/Frontend/Backend.cpp


Files: 1 Branches Taken: 70.5% 105 / 149
Generated: 2010-02-10 01:31 Branches Executed: 90.6% 135 / 149
Line Coverage: 86.9% 172 / 198


Programs: 1 Runs 2897


       1                 : //===--- Backend.cpp - Interface to LLVM backend technologies -------------===//
       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/Frontend/ASTConsumers.h"
      11                 : #include "clang/AST/ASTConsumer.h"
      12                 : #include "clang/AST/ASTContext.h"
      13                 : #include "clang/AST/DeclGroup.h"
      14                 : #include "clang/Basic/TargetInfo.h"
      15                 : #include "clang/Basic/TargetOptions.h"
      16                 : #include "clang/CodeGen/CodeGenOptions.h"
      17                 : #include "clang/CodeGen/ModuleBuilder.h"
      18                 : #include "clang/Frontend/FrontendDiagnostic.h"
      19                 : #include "llvm/Module.h"
      20                 : #include "llvm/PassManager.h"
      21                 : #include "llvm/ADT/OwningPtr.h"
      22                 : #include "llvm/Assembly/PrintModulePass.h"
      23                 : #include "llvm/Analysis/CallGraph.h"
      24                 : #include "llvm/Analysis/Verifier.h"
      25                 : #include "llvm/Bitcode/ReaderWriter.h"
      26                 : #include "llvm/CodeGen/RegAllocRegistry.h"
      27                 : #include "llvm/CodeGen/SchedulerRegistry.h"
      28                 : #include "llvm/Support/FormattedStream.h"
      29                 : #include "llvm/Support/StandardPasses.h"
      30                 : #include "llvm/Support/Timer.h"
      31                 : #include "llvm/Target/SubtargetFeature.h"
      32                 : #include "llvm/Target/TargetData.h"
      33                 : #include "llvm/Target/TargetMachine.h"
      34                 : #include "llvm/Target/TargetOptions.h"
      35                 : #include "llvm/Target/TargetRegistry.h"
      36                 : using namespace clang;
      37                 : using namespace llvm;
      38                 : 
      39                 : namespace {
      40                 :   class BackendConsumer : public ASTConsumer {
      41                 :     Diagnostic &Diags;
      42                 :     BackendAction Action;
      43                 :     const CodeGenOptions &CodeGenOpts;
      44                 :     const LangOptions &LangOpts;
      45                 :     const TargetOptions &TargetOpts;
      46                 :     llvm::raw_ostream *AsmOutStream;
      47                 :     llvm::formatted_raw_ostream FormattedOutStream;
      48                 :     ASTContext *Context;
      49                 : 
      50                 :     Timer LLVMIRGeneration;
      51                 :     Timer CodeGenerationTime;
      52                 : 
      53                 :     llvm::OwningPtr<CodeGenerator> Gen;
      54                 : 
      55                 :     llvm::Module *TheModule;
      56                 :     llvm::TargetData *TheTargetData;
      57                 : 
      58                 :     mutable FunctionPassManager *CodeGenPasses;
      59                 :     mutable PassManager *PerModulePasses;
      60                 :     mutable FunctionPassManager *PerFunctionPasses;
      61                 : 
      62                 :     FunctionPassManager *getCodeGenPasses() const;
      63                 :     PassManager *getPerModulePasses() const;
      64                 :     FunctionPassManager *getPerFunctionPasses() const;
      65                 : 
      66                 :     void CreatePasses();
      67                 : 
      68                 :     /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
      69                 :     ///
      70                 :     /// \return True on success.
      71                 :     bool AddEmitPasses();
      72                 : 
      73                 :     void EmitAssembly();
      74                 : 
      75                 :   public:
      76                 :     BackendConsumer(BackendAction action, Diagnostic &_Diags,
      77                 :                     const LangOptions &langopts, const CodeGenOptions &compopts,
      78                 :                     const TargetOptions &targetopts, bool TimePasses,
      79                 :                     const std::string &infile, llvm::raw_ostream *OS,
      80              625:                     LLVMContext& C) :
      81                 :       Diags(_Diags),
      82                 :       Action(action),
      83                 :       CodeGenOpts(compopts),
      84                 :       LangOpts(langopts),
      85                 :       TargetOpts(targetopts),
      86                 :       AsmOutStream(OS),
      87                 :       LLVMIRGeneration("LLVM IR Generation Time"),
      88                 :       CodeGenerationTime("Code Generation Time"),
      89                 :       Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
      90                 :       TheModule(0), TheTargetData(0),
      91              625:       CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
      92                 : 
                      590: branch 0 taken
                       35: branch 1 taken
      93              625:       if (AsmOutStream)
      94                 :         FormattedOutStream.setStream(*AsmOutStream,
      95              590:                                      formatted_raw_ostream::PRESERVE_STREAM);
      96                 : 
      97              625:       llvm::TimePassesIsEnabled = TimePasses;
      98              625:     }
      99                 : 
     100              599:     ~BackendConsumer() {
                      599: branch 0 taken
                        0: branch 1 not taken
                      599: branch 3 taken
                      599: branch 4 taken
     101              599:       delete TheTargetData;
                      596: branch 0 taken
                        3: branch 1 taken
                      596: branch 4 taken
                      596: branch 5 taken
     102              599:       delete TheModule;
                       53: branch 0 taken
                      546: branch 1 taken
                       53: branch 3 taken
                       53: branch 4 taken
     103              599:       delete CodeGenPasses;
                      596: branch 0 taken
                        3: branch 1 taken
                      596: branch 3 taken
                      596: branch 4 taken
     104              599:       delete PerModulePasses;
                      596: branch 0 taken
                        3: branch 1 taken
                      596: branch 3 taken
                      596: branch 4 taken
     105              599:       delete PerFunctionPasses;
                      599: branch 5 taken
                        0: branch 6 not taken
                        0: branch 13 not taken
                        0: branch 14 not taken
     106              599:     }
     107                 : 
     108              625:     virtual void Initialize(ASTContext &Ctx) {
     109              625:       Context = &Ctx;
     110                 : 
                        0: branch 0 not taken
                      625: branch 1 taken
     111              625:       if (llvm::TimePassesIsEnabled)
     112                0:         LLVMIRGeneration.startTimer();
     113                 : 
     114              625:       Gen->Initialize(Ctx);
     115                 : 
     116              625:       TheModule = Gen->GetModule();
     117              625:       TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
     118                 : 
                        0: branch 0 not taken
                      625: branch 1 taken
     119              625:       if (llvm::TimePassesIsEnabled)
     120                0:         LLVMIRGeneration.stopTimer();
     121              625:     }
     122                 : 
     123             5785:     virtual void HandleTopLevelDecl(DeclGroupRef D) {
     124                 :       PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
     125                 :                                      Context->getSourceManager(),
     126             5785:                                      "LLVM IR generation of declaration");
     127                 : 
                        0: branch 0 not taken
                     5785: branch 1 taken
     128             5785:       if (llvm::TimePassesIsEnabled)
     129                0:         LLVMIRGeneration.startTimer();
     130                 : 
     131             5785:       Gen->HandleTopLevelDecl(D);
     132                 : 
                        0: branch 0 not taken
                     5785: branch 1 taken
     133             5785:       if (llvm::TimePassesIsEnabled)
     134                0:         LLVMIRGeneration.stopTimer();
     135             5785:     }
     136                 : 
     137              625:     virtual void HandleTranslationUnit(ASTContext &C) {
     138                 :       {
     139              625:         PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
                        0: branch 0 not taken
                      625: branch 1 taken
     140              625:         if (llvm::TimePassesIsEnabled)
     141                0:           LLVMIRGeneration.startTimer();
     142                 : 
     143              625:         Gen->HandleTranslationUnit(C);
     144                 : 
                        0: branch 0 not taken
                      625: branch 1 taken
     145              625:         if (llvm::TimePassesIsEnabled)
     146                0:           LLVMIRGeneration.stopTimer();
     147                 :       }
     148                 : 
     149                 :       // EmitAssembly times and registers crash info itself.
     150              625:       EmitAssembly();
     151                 : 
     152                 :       // Force a flush here in case we never get released.
                      590: branch 0 taken
                       35: branch 1 taken
     153              625:       if (AsmOutStream)
     154              590:         FormattedOutStream.flush();
     155              625:     }
     156                 : 
     157             1509:     virtual void HandleTagDeclDefinition(TagDecl *D) {
     158                 :       PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
     159                 :                                      Context->getSourceManager(),
     160             1509:                                      "LLVM IR generation of declaration");
     161             1509:       Gen->HandleTagDeclDefinition(D);
     162             1509:     }
     163                 : 
     164              256:     virtual void CompleteTentativeDefinition(VarDecl *D) {
     165              256:       Gen->CompleteTentativeDefinition(D);
     166              256:     }
     167                 :   };
     168                 : }
     169                 : 
     170               57: FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
                       57: branch 0 taken
                        0: branch 1 not taken
     171               57:   if (!CodeGenPasses) {
     172               57:     CodeGenPasses = new FunctionPassManager(TheModule);
     173               57:     CodeGenPasses->add(new TargetData(*TheTargetData));
     174                 :   }
     175                 : 
     176               57:   return CodeGenPasses;
     177                 : }
     178                 : 
     179             1153: PassManager *BackendConsumer::getPerModulePasses() const {
                      622: branch 0 taken
                      531: branch 1 taken
     180             1153:   if (!PerModulePasses) {
     181              622:     PerModulePasses = new PassManager();
     182              622:     PerModulePasses->add(new TargetData(*TheTargetData));
     183                 :   }
     184                 : 
     185             1153:   return PerModulePasses;
     186                 : }
     187                 : 
     188              652: FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
                      622: branch 0 taken
                       30: branch 1 taken
     189              652:   if (!PerFunctionPasses) {
     190              622:     PerFunctionPasses = new FunctionPassManager(TheModule);
     191              622:     PerFunctionPasses->add(new TargetData(*TheTargetData));
     192                 :   }
     193                 : 
     194              652:   return PerFunctionPasses;
     195                 : }
     196                 : 
     197              622: bool BackendConsumer::AddEmitPasses() {
                       34: branch 0 taken
                      588: branch 1 taken
     198              622:   if (Action == Backend_EmitNothing)
     199               34:     return true;
     200                 : 
                       17: branch 0 taken
                      571: branch 1 taken
     201              588:   if (Action == Backend_EmitBC) {
     202               17:     getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
                      514: branch 0 taken
                       57: branch 1 taken
     203              571:   } else if (Action == Backend_EmitLL) {
     204              514:     getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
     205                 :   } else {
     206               57:     bool Fast = CodeGenOpts.OptimizationLevel == 0;
     207                 : 
     208                 :     // Create the TargetMachine for generating code.
     209               57:     std::string Error;
     210               57:     std::string Triple = TheModule->getTargetTriple();
     211               57:     const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
                        0: branch 0 not taken
                       57: branch 1 taken
     212               57:     if (!TheTarget) {
     213                0:       Diags.Report(diag::err_fe_unable_to_create_target) << Error;
     214                0:       return false;
     215                 :     }
     216                 : 
     217                 :     // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
     218                 :     // being gross, this is also totally broken if we ever care about
     219                 :     // concurrency.
     220               57:     llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
                        0: branch 1 not taken
                       57: branch 2 taken
     221               57:     if (CodeGenOpts.FloatABI == "soft")
     222                0:       llvm::FloatABIType = llvm::FloatABI::Soft;
                        0: branch 1 not taken
                       57: branch 2 taken
     223               57:     else if (CodeGenOpts.FloatABI == "hard")
     224                0:       llvm::FloatABIType = llvm::FloatABI::Hard;
     225                 :     else {
                       57: branch 1 taken
                        0: branch 2 not taken
     226               57:       assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
     227               57:       llvm::FloatABIType = llvm::FloatABI::Default;
     228                 :     }
     229               57:     NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
     230               57:     llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
     231               57:     UnwindTablesMandatory = CodeGenOpts.UnwindTables;
     232                 : 
     233               57:     TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
     234                 : 
     235                 :     // FIXME: Parse this earlier.
                        3: branch 1 taken
                       54: branch 2 taken
     236               57:     if (CodeGenOpts.RelocationModel == "static") {
     237                3:       TargetMachine::setRelocationModel(llvm::Reloc::Static);
                       54: branch 1 taken
                        0: branch 2 not taken
     238               54:     } else if (CodeGenOpts.RelocationModel == "pic") {
     239               54:       TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
     240                 :     } else {
     241                 :       assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
                        0: branch 1 not taken
                        0: branch 2 not taken
     242                0:              "Invalid PIC model!");
     243                0:       TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
     244                 :     }
     245                 :     // FIXME: Parse this earlier.
                        0: branch 1 not taken
                       57: branch 2 taken
     246               57:     if (CodeGenOpts.CodeModel == "small") {
     247                0:       TargetMachine::setCodeModel(llvm::CodeModel::Small);
                        0: branch 1 not taken
                       57: branch 2 taken
     248               57:     } else if (CodeGenOpts.CodeModel == "kernel") {
     249                0:       TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
                        0: branch 1 not taken
                       57: branch 2 taken
     250               57:     } else if (CodeGenOpts.CodeModel == "medium") {
     251                0:       TargetMachine::setCodeModel(llvm::CodeModel::Medium);
                        0: branch 1 not taken
                       57: branch 2 taken
     252               57:     } else if (CodeGenOpts.CodeModel == "large") {
     253                0:       TargetMachine::setCodeModel(llvm::CodeModel::Large);
     254                 :     } else {
                       57: branch 1 taken
                        0: branch 2 not taken
     255               57:       assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
     256               57:       TargetMachine::setCodeModel(llvm::CodeModel::Default);
     257                 :     }
     258                 : 
     259               57:     std::vector<const char *> BackendArgs;
     260               57:     BackendArgs.push_back("clang"); // Fake program name.
                        0: branch 1 not taken
                       57: branch 2 taken
     261               57:     if (!CodeGenOpts.DebugPass.empty()) {
     262                0:       BackendArgs.push_back("-debug-pass");
     263                0:       BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
     264                 :     }
                        0: branch 1 not taken
                       57: branch 2 taken
     265               57:     if (!CodeGenOpts.LimitFloatPrecision.empty()) {
     266                0:       BackendArgs.push_back("-limit-float-precision");
     267                0:       BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
     268                 :     }
                        0: branch 0 not taken
                       57: branch 1 taken
     269               57:     if (llvm::TimePassesIsEnabled)
     270                0:       BackendArgs.push_back("-time-passes");
     271               57:     BackendArgs.push_back(0);
     272                 :     llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
     273               57:                                       (char**) &BackendArgs[0]);
     274                 : 
     275               57:     std::string FeaturesStr;
                       53: branch 1 taken
                        4: branch 2 taken
                       53: branch 4 taken
                        0: branch 5 not taken
                       57: branch 6 taken
                        0: branch 7 not taken
     276               57:     if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
     277               57:       SubtargetFeatures Features;
     278               57:       Features.setCPU(TargetOpts.CPU);
                      513: branch 2 taken
                       57: branch 3 taken
     279              570:       for (std::vector<std::string>::const_iterator
     280               57:              it = TargetOpts.Features.begin(),
     281               57:              ie = TargetOpts.Features.end(); it != ie; ++it)
     282              513:         Features.AddFeature(*it);
     283               57:       FeaturesStr = Features.getString();
     284                 :     }
     285               57:     TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
     286                 : 
     287                 :     // Set register scheduler & allocation policy.
     288               57:     RegisterScheduler::setDefault(createDefaultScheduler);
     289                 :     RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
                       56: branch 0 taken
                        1: branch 1 taken
     290               57:                                  createLinearScanRegisterAllocator);
     291                 : 
     292                 :     // From llvm-gcc:
     293                 :     // If there are passes we have to run on the entire module, we do codegen
     294                 :     // as a separate "pass" after that happens.
     295                 :     // FIXME: This is disabled right now until bugs can be worked out.  Reenable
     296                 :     // this for fast -O0 compiles!
     297               57:     FunctionPassManager *PM = getCodeGenPasses();
     298               57:     CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
     299                 : 
                        1: branch 0 taken
                       56: branch 1 taken
                        0: branch 2 not taken
     300               57:     switch (CodeGenOpts.OptimizationLevel) {
     301                1:     default: break;
     302               56:     case 0: OptLevel = CodeGenOpt::None; break;
     303                0:     case 3: OptLevel = CodeGenOpt::Aggressive; break;
     304                 :     }
     305                 : 
     306                 :     // Normal mode, emit a .s or .o file by running the code generator. Note,
     307                 :     // this also adds codegenerator level optimization passes.
     308               57:     TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
                        0: branch 0 not taken
                       57: branch 1 taken
     309               57:     if (Action == Backend_EmitObj)
     310                0:       CGFT = TargetMachine::CGFT_ObjectFile;
                        0: branch 1 not taken
                       57: branch 2 taken
     311               57:     if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel)) {
     312                0:       Diags.Report(diag::err_fe_unable_to_interface_with_target);
     313                0:       return false;
                       57: branch 1 taken
                        0: branch 2 not taken
                       57: branch 4 taken
                        0: branch 5 not taken
                       57: branch 7 taken
                        0: branch 8 not taken
                       57: branch 10 taken
                        0: branch 11 not taken
     314               57:     }
     315                 :   }
     316                 : 
     317              588:   return true;
     318                 : }
     319                 : 
     320              622: void BackendConsumer::CreatePasses() {
     321              622:   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
     322              622:   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
     323                 : 
     324                 :   // Handle disabling of LLVM optimization, where we want to preserve the
     325                 :   // internal module before any optimization.
                        1: branch 0 taken
                      621: branch 1 taken
     326              622:   if (CodeGenOpts.DisableLLVMOpts) {
     327                1:     OptLevel = 0;
     328                1:     Inlining = CodeGenOpts.NoInlining;
     329                 :   }
     330                 : 
     331                 :   // In -O0 if checking is disabled, we don't even have per-function passes.
                      622: branch 0 taken
                        0: branch 1 not taken
     332              622:   if (CodeGenOpts.VerifyModule)
     333              622:     getPerFunctionPasses()->add(createVerifierPass());
     334                 : 
     335                 :   // Assume that standard function passes aren't run for -O0.
                       30: branch 0 taken
                      592: branch 1 taken
     336              622:   if (OptLevel > 0)
     337               30:     llvm::createStandardFunctionPasses(getPerFunctionPasses(), OptLevel);
     338                 : 
     339              622:   llvm::Pass *InliningPass = 0;
                        1: branch 0 taken
                       25: branch 1 taken
                      596: branch 2 taken
                        0: branch 3 not taken
     340              622:   switch (Inlining) {
     341                1:   case CodeGenOptions::NoInlining: break;
     342                 :   case CodeGenOptions::NormalInlining: {
     343                 :     // Set the inline threshold following llvm-gcc.
     344                 :     //
     345                 :     // FIXME: Derive these constants in a principled fashion.
     346               25:     unsigned Threshold = 225;
                        2: branch 0 taken
                       23: branch 1 taken
     347               25:     if (CodeGenOpts.OptimizeSize)
     348                2:       Threshold = 75;
                       15: branch 0 taken
                        8: branch 1 taken
     349               23:     else if (OptLevel > 2)
     350               15:       Threshold = 275;
     351               25:     InliningPass = createFunctionInliningPass(Threshold);
     352               25:     break;
     353                 :   }
     354                 :   case CodeGenOptions::OnlyAlwaysInlining:
     355              596:     InliningPass = createAlwaysInlinerPass();         // Respect always_inline
     356                 :     break;
     357                 :   }
     358                 : 
     359                 :   // For now we always create per module passes.
     360              622:   PassManager *PM = getPerModulePasses();
     361                 :   llvm::createStandardModulePasses(PM, OptLevel, CodeGenOpts.OptimizeSize,
     362                 :                                    CodeGenOpts.UnitAtATime,
     363                 :                                    CodeGenOpts.UnrollLoops,
     364                 :                                    /*SimplifyLibCalls=*/!LangOpts.NoBuiltin,
     365                 :                                    /*HaveExceptions=*/true,
     366              622:                                    InliningPass);
     367              622: }
     368                 : 
     369                 : /// EmitAssembly - Handle interaction with LLVM backend to generate
     370                 : /// actual machine code.
     371              625: void BackendConsumer::EmitAssembly() {
     372                 :   // Silently ignore if we weren't initialized for some reason.
                      625: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                      625: branch 3 taken
     373              625:   if (!TheModule || !TheTargetData)
     374                0:     return;
     375                 : 
                        0: branch 0 not taken
                      625: branch 1 taken
     376              625:   TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
     377                 : 
     378                 :   // Make sure IR generation is happy with the module. This is
     379                 :   // released by the module provider.
     380              625:   Module *M = Gen->ReleaseModule();
                        3: branch 0 taken
                      622: branch 1 taken
     381              625:   if (!M) {
     382                 :     // The module has been released by IR gen on failures, do not
     383                 :     // double free.
     384                3:     TheModule = 0;
     385                3:     return;
     386                 :   }
     387                 : 
                        0: branch 0 not taken
                      622: branch 1 taken
     388              622:   assert(TheModule == M && "Unexpected module change during IR generation");
     389                 : 
     390              622:   CreatePasses();
                        0: branch 1 not taken
                      622: branch 2 taken
     391              622:   if (!AddEmitPasses())
     392                 :     return;
     393                 : 
     394                 :   // Run passes. For now we do all passes at once, but eventually we
     395                 :   // would like to have the option of streaming code generation.
     396                 : 
                      622: branch 0 taken
                        0: branch 1 not taken
     397              622:   if (PerFunctionPasses) {
     398              622:     PrettyStackTraceString CrashInfo("Per-function optimization");
     399                 : 
     400              622:     PerFunctionPasses->doInitialization();
                     4282: branch 4 taken
                      622: branch 5 taken
     401             4904:     for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
                     3080: branch 2 taken
                     1202: branch 3 taken
     402             4282:       if (!I->isDeclaration())
     403             3080:         PerFunctionPasses->run(*I);
     404              622:     PerFunctionPasses->doFinalization();
     405                 :   }
     406                 : 
                      622: branch 0 taken
                        0: branch 1 not taken
     407              622:   if (PerModulePasses) {
     408              622:     PrettyStackTraceString CrashInfo("Per-module optimization passes");
     409              622:     PerModulePasses->run(*M);
     410                 :   }
     411                 : 
                       57: branch 0 taken
                      565: branch 1 taken
     412              622:   if (CodeGenPasses) {
     413               57:     PrettyStackTraceString CrashInfo("Code generation");
     414               57:     CodeGenPasses->doInitialization();
                      780: branch 4 taken
                       57: branch 5 taken
     415              837:     for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
                      626: branch 2 taken
                      154: branch 3 taken
     416              780:       if (!I->isDeclaration())
     417              626:         CodeGenPasses->run(*I);
     418               57:     CodeGenPasses->doFinalization();
                      622: branch 1 taken
                        3: branch 2 taken
     419              625:   }
     420                 : }
     421                 : 
     422                 : ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
     423                 :                                           Diagnostic &Diags,
     424                 :                                           const LangOptions &LangOpts,
     425                 :                                           const CodeGenOptions &CodeGenOpts,
     426                 :                                           const TargetOptions &TargetOpts,
     427                 :                                           bool TimePasses,
     428                 :                                           const std::string& InFile,
     429                 :                                           llvm::raw_ostream* OS,
     430              625:                                           LLVMContext& C) {
     431                 :   return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts,
     432              625:                              TargetOpts, TimePasses, InFile, OS, C);
     433                 : }

Generated: 2010-02-10 01:31 by zcov