Home | History | Annotate | Download | only in llvm-ndk-cc
      1 #include "Backend.h"
      2 
      3 #include <cassert>
      4 #include <string>
      5 #include <vector>
      6 
      7 #include "clang/AST/ASTContext.h"
      8 #include "clang/AST/Decl.h"
      9 #include "clang/AST/DeclGroup.h"
     10 
     11 #include "clang/Basic/Diagnostic.h"
     12 #include "clang/Basic/TargetInfo.h"
     13 #include "clang/Basic/TargetOptions.h"
     14 
     15 #include "clang/CodeGen/ModuleBuilder.h"
     16 
     17 #include "clang/Frontend/CodeGenOptions.h"
     18 #include "clang/Frontend/FrontendDiagnostic.h"
     19 
     20 #include "llvm/Assembly/PrintModulePass.h"
     21 
     22 #include "llvm/Bitcode/ReaderWriter.h"
     23 
     24 #include "llvm/CodeGen/RegAllocRegistry.h"
     25 #include "llvm/CodeGen/SchedulerRegistry.h"
     26 
     27 #include "llvm/Instructions.h"
     28 #include "llvm/LLVMContext.h"
     29 #include "llvm/Module.h"
     30 #include "llvm/Metadata.h"
     31 
     32 #include "llvm/MC/SubtargetFeature.h"
     33 
     34 #include "llvm/Support/Casting.h"
     35 #include "llvm/Support/InstIterator.h"
     36 
     37 #include "llvm/Target/TargetData.h"
     38 #include "llvm/Target/TargetMachine.h"
     39 #include "llvm/Target/TargetOptions.h"
     40 #include "llvm/Target/TargetRegistry.h"
     41 
     42 namespace ndkpc {
     43 
     44 void Backend::CreateFunctionPasses() {
     45   if (!mpPerFunctionPasses) {
     46     mpPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
     47     mpPerFunctionPasses->add(new llvm::TargetData(mpModule));
     48 
     49     // FIXME REMOVE
     50     //llvm::createStandardFunctionPasses(mpPerFunctionPasses,
     51     //                                   mCodeGenOpts.OptimizationLevel);
     52     llvm::PassManagerBuilder PMBuilder;
     53     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     54     PMBuilder.populateFunctionPassManager(*mpPerFunctionPasses);
     55   }
     56   return;
     57 }
     58 
     59 void Backend::CreateModulePasses() {
     60   if (!mpPerModulePasses) {
     61 	  mpPerModulePasses = new llvm::PassManager();
     62 	  mpPerModulePasses->add(new llvm::TargetData(mpModule));
     63 
     64 	  llvm::PassManagerBuilder PMBuilder;
     65 	  PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     66 	  PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
     67 	  if (mCodeGenOpts.UnitAtATime) {
     68 		  PMBuilder.DisableUnitAtATime = 0;
     69 	  } else {
     70 		  PMBuilder.DisableUnitAtATime = 1;
     71 	  }
     72 
     73 	  if (mCodeGenOpts.UnrollLoops) {
     74 		  PMBuilder.DisableUnrollLoops = 0;
     75 	  } else {
     76 		  PMBuilder.DisableUnrollLoops = 1;
     77 	  }
     78 
     79 	  PMBuilder.DisableSimplifyLibCalls = false;
     80 	  PMBuilder.populateModulePassManager(*mpPerModulePasses);
     81   }
     82   return;
     83 }
     84 
     85 bool Backend::CreateCodeGenPasses() {
     86   if ((mOT != Compiler::OT_Assembly) && (mOT != Compiler::OT_Object))
     87     return true;
     88 
     89   // Now we add passes for code emitting
     90   if (mpCodeGenPasses) {
     91     return true;
     92   } else {
     93     mpCodeGenPasses = new llvm::FunctionPassManager(mpModule);
     94     mpCodeGenPasses->add(new llvm::TargetData(mpModule));
     95   }
     96 
     97   // Create the TargetMachine for generating code.
     98   std::string Triple = mpModule->getTargetTriple();
     99 
    100   std::string Error;
    101   const llvm::Target* TargetInfo =
    102       llvm::TargetRegistry::lookupTarget(Triple, Error);
    103   if (TargetInfo == NULL) {
    104     mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error;
    105     return false;
    106   }
    107 
    108   llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim;
    109 
    110   // Use hardware FPU.
    111   //
    112   // FIXME: Need to detect the CPU capability and decide whether to use softfp.
    113   // To use softfp, change following 2 lines to
    114   //
    115   //  llvm::FloatABIType = llvm::FloatABI::Soft;
    116   //  llvm::UseSoftFloat = true;
    117   llvm::FloatABIType = llvm::FloatABI::Hard;
    118   llvm::UseSoftFloat = false;
    119 
    120   // BCC needs all unknown symbols resolved at compilation time. So we don't
    121   // need any relocation model.
    122   llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
    123 
    124 
    125   // This is set for the linker (specify how large of the virtual addresses we
    126   // can access for all unknown symbols.)
    127   if (mpModule->getPointerSize() == llvm::Module::Pointer32)
    128     llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
    129   else
    130     // The target may have pointer size greater than 32 (e.g. x86_64
    131     // architecture) may need large data address model
    132     llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
    133 
    134   // Setup feature string
    135   std::string FeaturesStr;
    136   if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
    137     llvm::SubtargetFeatures Features;
    138 
    139     for (std::vector<std::string>::const_iterator
    140              I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
    141          I != E;
    142          I++)
    143       Features.AddFeature(*I);
    144 
    145     FeaturesStr = Features.getString();
    146   }
    147   llvm::TargetMachine *TM =
    148       TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr);
    149 
    150   // Register scheduler
    151   llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
    152 
    153   // Register allocation policy:
    154   //  createFastRegisterAllocator: fast but bad quality
    155   //  createLinearScanRegisterAllocator: not so fast but good quality
    156   llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
    157                                      llvm::createFastRegisterAllocator :
    158                                      llvm::createLinearScanRegisterAllocator);
    159 
    160   llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
    161   if (mCodeGenOpts.OptimizationLevel == 0)
    162     OptLevel = llvm::CodeGenOpt::None;
    163   else if (mCodeGenOpts.OptimizationLevel == 3)
    164     OptLevel = llvm::CodeGenOpt::Aggressive;
    165 
    166   llvm::TargetMachine::CodeGenFileType CGFT =
    167       llvm::TargetMachine::CGFT_AssemblyFile;
    168   if (mOT == Compiler::OT_Object)
    169     CGFT = llvm::TargetMachine::CGFT_ObjectFile;
    170   if (TM->addPassesToEmitFile(*mpCodeGenPasses, FormattedOutStream,
    171                               CGFT, OptLevel)) {
    172     mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target);
    173     return false;
    174   }
    175 
    176   return true;
    177 }
    178 
    179 Backend::Backend(const clang::CodeGenOptions &CodeGenOpts,
    180                  const clang::TargetOptions &TargetOpts,
    181                  clang::Diagnostic *Diags,
    182                  llvm::raw_ostream *OS,
    183                  Compiler::OutputType OT)
    184     : ASTConsumer(),
    185       mCodeGenOpts(CodeGenOpts),
    186       mTargetOpts(TargetOpts),
    187       mLLVMContext(llvm::getGlobalContext()),
    188       mDiags(*Diags),
    189       mpModule(NULL),
    190       mpOS(OS),
    191       mOT(OT),
    192       mpGen(NULL),
    193       mpPerFunctionPasses(NULL),
    194       mpPerModulePasses(NULL),
    195       mpCodeGenPasses(NULL) {
    196   FormattedOutStream.setStream(*mpOS,
    197                                llvm::formatted_raw_ostream::PRESERVE_STREAM);
    198   mpGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext);
    199   return;
    200 }
    201 
    202 void Backend::Initialize(clang::ASTContext &Ctx) {
    203   mpGen->Initialize(Ctx);
    204   mpModule = mpGen->GetModule();
    205   return;
    206 }
    207 
    208 void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
    209   mpGen->HandleTopLevelDecl(D);
    210   return;
    211 }
    212 
    213 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
    214   mpGen->HandleTranslationUnit(Ctx);
    215 
    216   // Here, we complete a translation unit (whole translation unit is now in LLVM
    217   // IR). Now, interact with LLVM backend to generate actual machine code (asm
    218   // or machine code, whatever.)
    219 
    220   // Silently ignore if we weren't initialized for some reason.
    221   if (!mpModule)
    222     return;
    223 
    224   llvm::Module *M = mpGen->ReleaseModule();
    225   if (!M) {
    226     // The module has been released by IR gen on failures, do not double free.
    227     mpModule = NULL;
    228     return;
    229   }
    230 
    231   assert(mpModule == M &&
    232               "Unexpected module change during LLVM IR generation");
    233 
    234   // Handle illigal CallSite
    235   for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    236        I != E;
    237        ++I) {
    238     for (llvm::inst_iterator i = llvm::inst_begin(*I), e = llvm::inst_end(*I);
    239          i != e;
    240          ++i) {
    241       if (llvm::CallInst* CallInst = llvm::dyn_cast<llvm::CallInst>(&*i)) {
    242         if (CallInst->isInlineAsm()) {
    243           // TODO: Should we reflect source location information to diagnostic
    244           //       class and show to users?
    245           llvm::errs() << "Inline assembly is illigal. Please don't use it." << "\n";
    246           exit(1);
    247         }
    248       }
    249     }
    250   }
    251 
    252   // Create and run per-function passes
    253   CreateFunctionPasses();
    254   if (mpPerFunctionPasses) {
    255     mpPerFunctionPasses->doInitialization();
    256 
    257     for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    258          I != E;
    259          I++)
    260       if (!I->isDeclaration())
    261         mpPerFunctionPasses->run(*I);
    262 
    263     mpPerFunctionPasses->doFinalization();
    264   }
    265 
    266   // Create and run module passes
    267   CreateModulePasses();
    268   if (mpPerModulePasses)
    269     mpPerModulePasses->run(*mpModule);
    270 
    271   switch (mOT) {
    272     case Compiler::OT_Assembly:
    273     case Compiler::OT_Object: {
    274       if (!CreateCodeGenPasses())
    275         return;
    276 
    277       mpCodeGenPasses->doInitialization();
    278 
    279       for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    280           I != E;
    281           I++)
    282         if (!I->isDeclaration())
    283           mpCodeGenPasses->run(*I);
    284 
    285       mpCodeGenPasses->doFinalization();
    286       break;
    287     }
    288     case Compiler::OT_LLVMAssembly: {
    289       llvm::PassManager *LLEmitPM = new llvm::PassManager();
    290       LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
    291       LLEmitPM->run(*mpModule);
    292       break;
    293     }
    294     case Compiler::OT_Bitcode: {
    295       llvm::PassManager *BCEmitPM = new llvm::PassManager();
    296       BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream));
    297       BCEmitPM->run(*mpModule);
    298       break;
    299     }
    300     case Compiler::OT_Nothing: {
    301       return;
    302     }
    303     default: {
    304       assert(false && "Unknown output type");
    305     }
    306   }
    307 
    308   FormattedOutStream.flush();
    309   return;
    310 }
    311 
    312 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
    313   mpGen->HandleTagDeclDefinition(D);
    314   return;
    315 }
    316 
    317 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
    318   mpGen->CompleteTentativeDefinition(D);
    319   return;
    320 }
    321 
    322 Backend::~Backend() {
    323   delete mpModule;
    324   delete mpGen;
    325   delete mpPerFunctionPasses;
    326   delete mpPerModulePasses;
    327   delete mpCodeGenPasses;
    328   return;
    329 }
    330 
    331 }
    332