Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "slang_backend.h"
     18 
     19 #include <string>
     20 #include <vector>
     21 
     22 #include "bcinfo/BitcodeWrapper.h"
     23 
     24 #include "clang/AST/ASTContext.h"
     25 #include "clang/AST/Decl.h"
     26 #include "clang/AST/DeclGroup.h"
     27 
     28 #include "clang/Basic/Diagnostic.h"
     29 #include "clang/Basic/TargetInfo.h"
     30 #include "clang/Basic/TargetOptions.h"
     31 
     32 #include "clang/CodeGen/ModuleBuilder.h"
     33 
     34 #include "clang/Frontend/CodeGenOptions.h"
     35 #include "clang/Frontend/FrontendDiagnostic.h"
     36 
     37 #include "llvm/Assembly/PrintModulePass.h"
     38 
     39 #include "llvm/Bitcode/ReaderWriter.h"
     40 
     41 #include "llvm/CodeGen/RegAllocRegistry.h"
     42 #include "llvm/CodeGen/SchedulerRegistry.h"
     43 
     44 #include "llvm/LLVMContext.h"
     45 #include "llvm/Module.h"
     46 #include "llvm/Metadata.h"
     47 
     48 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
     49 
     50 #include "llvm/Target/TargetData.h"
     51 #include "llvm/Target/TargetMachine.h"
     52 #include "llvm/Target/TargetOptions.h"
     53 #include "llvm/Support/TargetRegistry.h"
     54 
     55 #include "llvm/MC/SubtargetFeature.h"
     56 
     57 #include "slang_assert.h"
     58 #include "BitWriter_2_9/ReaderWriter_2_9.h"
     59 
     60 namespace slang {
     61 
     62 void Backend::CreateFunctionPasses() {
     63   if (!mPerFunctionPasses) {
     64     mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
     65     mPerFunctionPasses->add(new llvm::TargetData(mpModule));
     66 
     67     llvm::PassManagerBuilder PMBuilder;
     68     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     69     PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
     70   }
     71   return;
     72 }
     73 
     74 void Backend::CreateModulePasses() {
     75   if (!mPerModulePasses) {
     76     mPerModulePasses = new llvm::PassManager();
     77     mPerModulePasses->add(new llvm::TargetData(mpModule));
     78 
     79     llvm::PassManagerBuilder PMBuilder;
     80     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     81     PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
     82     PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
     83     if (mCodeGenOpts.UnitAtATime) {
     84       PMBuilder.DisableUnitAtATime = 0;
     85     } else {
     86       PMBuilder.DisableUnitAtATime = 1;
     87     }
     88 
     89     if (mCodeGenOpts.UnrollLoops) {
     90       PMBuilder.DisableUnrollLoops = 0;
     91     } else {
     92       PMBuilder.DisableUnrollLoops = 1;
     93     }
     94 
     95     PMBuilder.DisableSimplifyLibCalls = false;
     96     PMBuilder.populateModulePassManager(*mPerModulePasses);
     97   }
     98   return;
     99 }
    100 
    101 bool Backend::CreateCodeGenPasses() {
    102   if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
    103     return true;
    104 
    105   // Now we add passes for code emitting
    106   if (mCodeGenPasses) {
    107     return true;
    108   } else {
    109     mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
    110     mCodeGenPasses->add(new llvm::TargetData(mpModule));
    111   }
    112 
    113   // Create the TargetMachine for generating code.
    114   std::string Triple = mpModule->getTargetTriple();
    115 
    116   std::string Error;
    117   const llvm::Target* TargetInfo =
    118       llvm::TargetRegistry::lookupTarget(Triple, Error);
    119   if (TargetInfo == NULL) {
    120     mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
    121     return false;
    122   }
    123 
    124   llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim;
    125 
    126   // Use hardware FPU.
    127   //
    128   // FIXME: Need to detect the CPU capability and decide whether to use softfp.
    129   // To use softfp, change following 2 lines to
    130   //
    131   //  llvm::FloatABIType = llvm::FloatABI::Soft;
    132   //  llvm::UseSoftFloat = true;
    133   llvm::FloatABIType = llvm::FloatABI::Hard;
    134   llvm::UseSoftFloat = false;
    135 
    136   // BCC needs all unknown symbols resolved at compilation time. So we don't
    137   // need any relocation model.
    138   llvm::Reloc::Model RM = llvm::Reloc::Static;
    139 
    140   // This is set for the linker (specify how large of the virtual addresses we
    141   // can access for all unknown symbols.)
    142   llvm::CodeModel::Model CM;
    143   if (mpModule->getPointerSize() == llvm::Module::Pointer32) {
    144     CM = llvm::CodeModel::Small;
    145   } else {
    146     // The target may have pointer size greater than 32 (e.g. x86_64
    147     // architecture) may need large data address model
    148     CM = llvm::CodeModel::Medium;
    149   }
    150 
    151   // Setup feature string
    152   std::string FeaturesStr;
    153   if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
    154     llvm::SubtargetFeatures Features;
    155 
    156     for (std::vector<std::string>::const_iterator
    157              I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
    158          I != E;
    159          I++)
    160       Features.AddFeature(*I);
    161 
    162     FeaturesStr = Features.getString();
    163   }
    164 
    165   llvm::TargetMachine *TM =
    166     TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
    167                                     RM, CM);
    168 
    169   // Register scheduler
    170   llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
    171 
    172   // Register allocation policy:
    173   //  createFastRegisterAllocator: fast but bad quality
    174   //  createLinearScanRegisterAllocator: not so fast but good quality
    175   llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
    176                                      llvm::createFastRegisterAllocator :
    177                                      llvm::createLinearScanRegisterAllocator);
    178 
    179   llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
    180   if (mCodeGenOpts.OptimizationLevel == 0) {
    181     OptLevel = llvm::CodeGenOpt::None;
    182   } else if (mCodeGenOpts.OptimizationLevel == 3) {
    183     OptLevel = llvm::CodeGenOpt::Aggressive;
    184   }
    185 
    186   llvm::TargetMachine::CodeGenFileType CGFT =
    187       llvm::TargetMachine::CGFT_AssemblyFile;
    188   if (mOT == Slang::OT_Object) {
    189     CGFT = llvm::TargetMachine::CGFT_ObjectFile;
    190   }
    191   if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream,
    192                               CGFT, OptLevel)) {
    193     mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
    194     return false;
    195   }
    196 
    197   return true;
    198 }
    199 
    200 Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
    201                  const clang::CodeGenOptions &CodeGenOpts,
    202                  const clang::TargetOptions &TargetOpts,
    203                  PragmaList *Pragmas,
    204                  llvm::raw_ostream *OS,
    205                  Slang::OutputType OT)
    206     : ASTConsumer(),
    207       mCodeGenOpts(CodeGenOpts),
    208       mTargetOpts(TargetOpts),
    209       mpModule(NULL),
    210       mpOS(OS),
    211       mOT(OT),
    212       mGen(NULL),
    213       mPerFunctionPasses(NULL),
    214       mPerModulePasses(NULL),
    215       mCodeGenPasses(NULL),
    216       mLLVMContext(llvm::getGlobalContext()),
    217       mDiagEngine(*DiagEngine),
    218       mPragmas(Pragmas) {
    219   FormattedOutStream.setStream(*mpOS,
    220                                llvm::formatted_raw_ostream::PRESERVE_STREAM);
    221   mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
    222   return;
    223 }
    224 
    225 void Backend::Initialize(clang::ASTContext &Ctx) {
    226   mGen->Initialize(Ctx);
    227 
    228   mpModule = mGen->GetModule();
    229 
    230   return;
    231 }
    232 
    233 // Encase the Bitcode in a wrapper containing RS version information.
    234 void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
    235   struct bcinfo::BCWrapperHeader header;
    236   header.Magic = 0x0B17C0DE;
    237   header.Version = 0;
    238   header.BitcodeOffset = sizeof(header);
    239   header.BitcodeSize = Bitcode.str().length();
    240   header.HeaderVersion = 0;
    241   header.TargetAPI = getTargetAPI();
    242 
    243   // Write out the bitcode wrapper.
    244   FormattedOutStream.write((const char*) &header, sizeof(header));
    245 
    246   // Write out the actual encoded bitcode.
    247   FormattedOutStream << Bitcode.str();
    248   return;
    249 }
    250 
    251 void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
    252   mGen->HandleTopLevelDecl(D);
    253   return;
    254 }
    255 
    256 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
    257   HandleTranslationUnitPre(Ctx);
    258 
    259   mGen->HandleTranslationUnit(Ctx);
    260 
    261   // Here, we complete a translation unit (whole translation unit is now in LLVM
    262   // IR). Now, interact with LLVM backend to generate actual machine code (asm
    263   // or machine code, whatever.)
    264 
    265   // Silently ignore if we weren't initialized for some reason.
    266   if (!mpModule)
    267     return;
    268 
    269   llvm::Module *M = mGen->ReleaseModule();
    270   if (!M) {
    271     // The module has been released by IR gen on failures, do not double free.
    272     mpModule = NULL;
    273     return;
    274   }
    275 
    276   slangAssert(mpModule == M &&
    277               "Unexpected module change during LLVM IR generation");
    278 
    279   // Insert #pragma information into metadata section of module
    280   if (!mPragmas->empty()) {
    281     llvm::NamedMDNode *PragmaMetadata =
    282         mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
    283     for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
    284          I != E;
    285          I++) {
    286       llvm::SmallVector<llvm::Value*, 2> Pragma;
    287       // Name goes first
    288       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
    289       // And then value
    290       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
    291 
    292       // Create MDNode and insert into PragmaMetadata
    293       PragmaMetadata->addOperand(
    294           llvm::MDNode::get(mLLVMContext, Pragma));
    295     }
    296   }
    297 
    298   HandleTranslationUnitPost(mpModule);
    299 
    300   // Create passes for optimization and code emission
    301 
    302   // Create and run per-function passes
    303   CreateFunctionPasses();
    304   if (mPerFunctionPasses) {
    305     mPerFunctionPasses->doInitialization();
    306 
    307     for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    308          I != E;
    309          I++)
    310       if (!I->isDeclaration())
    311         mPerFunctionPasses->run(*I);
    312 
    313     mPerFunctionPasses->doFinalization();
    314   }
    315 
    316   // Create and run module passes
    317   CreateModulePasses();
    318   if (mPerModulePasses)
    319     mPerModulePasses->run(*mpModule);
    320 
    321   switch (mOT) {
    322     case Slang::OT_Assembly:
    323     case Slang::OT_Object: {
    324       if (!CreateCodeGenPasses())
    325         return;
    326 
    327       mCodeGenPasses->doInitialization();
    328 
    329       for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    330           I != E;
    331           I++)
    332         if (!I->isDeclaration())
    333           mCodeGenPasses->run(*I);
    334 
    335       mCodeGenPasses->doFinalization();
    336       break;
    337     }
    338     case Slang::OT_LLVMAssembly: {
    339       llvm::PassManager *LLEmitPM = new llvm::PassManager();
    340       LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
    341       LLEmitPM->run(*mpModule);
    342       break;
    343     }
    344     case Slang::OT_Bitcode: {
    345       llvm::PassManager *BCEmitPM = new llvm::PassManager();
    346       std::string BCStr;
    347       llvm::raw_string_ostream Bitcode(BCStr);
    348       if (getTargetAPI() < SLANG_ICS_TARGET_API) {
    349         // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
    350         BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
    351       } else {
    352         BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
    353       }
    354 
    355       BCEmitPM->run(*mpModule);
    356       WrapBitcode(Bitcode);
    357       break;
    358     }
    359     case Slang::OT_Nothing: {
    360       return;
    361     }
    362     default: {
    363       slangAssert(false && "Unknown output type");
    364     }
    365   }
    366 
    367   FormattedOutStream.flush();
    368 
    369   return;
    370 }
    371 
    372 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
    373   mGen->HandleTagDeclDefinition(D);
    374   return;
    375 }
    376 
    377 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
    378   mGen->CompleteTentativeDefinition(D);
    379   return;
    380 }
    381 
    382 Backend::~Backend() {
    383   delete mpModule;
    384   delete mGen;
    385   delete mPerFunctionPasses;
    386   delete mPerModulePasses;
    387   delete mCodeGenPasses;
    388   return;
    389 }
    390 
    391 }  // namespace slang
    392