Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010-2012, 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/IR/LLVMContext.h"
     45 #include "llvm/IR/Module.h"
     46 #include "llvm/IR/Metadata.h"
     47 
     48 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
     49 
     50 #include "llvm/IR/DataLayout.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 #include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
     60 #include "BitWriter_3_2/ReaderWriter_3_2.h"
     61 
     62 namespace slang {
     63 
     64 void Backend::CreateFunctionPasses() {
     65   if (!mPerFunctionPasses) {
     66     mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
     67     mPerFunctionPasses->add(new llvm::DataLayout(mpModule));
     68 
     69     llvm::PassManagerBuilder PMBuilder;
     70     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     71     PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
     72   }
     73   return;
     74 }
     75 
     76 void Backend::CreateModulePasses() {
     77   if (!mPerModulePasses) {
     78     mPerModulePasses = new llvm::PassManager();
     79     mPerModulePasses->add(new llvm::DataLayout(mpModule));
     80 
     81     llvm::PassManagerBuilder PMBuilder;
     82     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
     83     PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
     84     PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
     85     if (mCodeGenOpts.UnitAtATime) {
     86       PMBuilder.DisableUnitAtATime = 0;
     87     } else {
     88       PMBuilder.DisableUnitAtATime = 1;
     89     }
     90 
     91     if (mCodeGenOpts.UnrollLoops) {
     92       PMBuilder.DisableUnrollLoops = 0;
     93     } else {
     94       PMBuilder.DisableUnrollLoops = 1;
     95     }
     96 
     97     PMBuilder.DisableSimplifyLibCalls = false;
     98     PMBuilder.populateModulePassManager(*mPerModulePasses);
     99   }
    100   return;
    101 }
    102 
    103 bool Backend::CreateCodeGenPasses() {
    104   if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
    105     return true;
    106 
    107   // Now we add passes for code emitting
    108   if (mCodeGenPasses) {
    109     return true;
    110   } else {
    111     mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
    112     mCodeGenPasses->add(new llvm::DataLayout(mpModule));
    113   }
    114 
    115   // Create the TargetMachine for generating code.
    116   std::string Triple = mpModule->getTargetTriple();
    117 
    118   std::string Error;
    119   const llvm::Target* TargetInfo =
    120       llvm::TargetRegistry::lookupTarget(Triple, Error);
    121   if (TargetInfo == NULL) {
    122     mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
    123     return false;
    124   }
    125 
    126   // Target Machine Options
    127   llvm::TargetOptions Options;
    128 
    129   Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
    130 
    131   // Use hardware FPU.
    132   //
    133   // FIXME: Need to detect the CPU capability and decide whether to use softfp.
    134   // To use softfp, change following 2 lines to
    135   //
    136   // Options.FloatABIType = llvm::FloatABI::Soft;
    137   // Options.UseSoftFloat = true;
    138   Options.FloatABIType = llvm::FloatABI::Hard;
    139   Options.UseSoftFloat = false;
    140 
    141   // BCC needs all unknown symbols resolved at compilation time. So we don't
    142   // need any relocation model.
    143   llvm::Reloc::Model RM = llvm::Reloc::Static;
    144 
    145   // This is set for the linker (specify how large of the virtual addresses we
    146   // can access for all unknown symbols.)
    147   llvm::CodeModel::Model CM;
    148   if (mpModule->getPointerSize() == llvm::Module::Pointer32) {
    149     CM = llvm::CodeModel::Small;
    150   } else {
    151     // The target may have pointer size greater than 32 (e.g. x86_64
    152     // architecture) may need large data address model
    153     CM = llvm::CodeModel::Medium;
    154   }
    155 
    156   // Setup feature string
    157   std::string FeaturesStr;
    158   if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
    159     llvm::SubtargetFeatures Features;
    160 
    161     for (std::vector<std::string>::const_iterator
    162              I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
    163          I != E;
    164          I++)
    165       Features.AddFeature(*I);
    166 
    167     FeaturesStr = Features.getString();
    168   }
    169 
    170   llvm::TargetMachine *TM =
    171     TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
    172                                     Options, RM, CM);
    173 
    174   // Register scheduler
    175   llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
    176 
    177   // Register allocation policy:
    178   //  createFastRegisterAllocator: fast but bad quality
    179   //  createGreedyRegisterAllocator: not so fast but good quality
    180   llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
    181                                      llvm::createFastRegisterAllocator :
    182                                      llvm::createGreedyRegisterAllocator);
    183 
    184   llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
    185   if (mCodeGenOpts.OptimizationLevel == 0) {
    186     OptLevel = llvm::CodeGenOpt::None;
    187   } else if (mCodeGenOpts.OptimizationLevel == 3) {
    188     OptLevel = llvm::CodeGenOpt::Aggressive;
    189   }
    190 
    191   llvm::TargetMachine::CodeGenFileType CGFT =
    192       llvm::TargetMachine::CGFT_AssemblyFile;
    193   if (mOT == Slang::OT_Object) {
    194     CGFT = llvm::TargetMachine::CGFT_ObjectFile;
    195   }
    196   if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream,
    197                               CGFT, OptLevel)) {
    198     mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
    199     return false;
    200   }
    201 
    202   return true;
    203 }
    204 
    205 Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
    206                  const clang::CodeGenOptions &CodeGenOpts,
    207                  const clang::TargetOptions &TargetOpts,
    208                  PragmaList *Pragmas,
    209                  llvm::raw_ostream *OS,
    210                  Slang::OutputType OT)
    211     : ASTConsumer(),
    212       mTargetOpts(TargetOpts),
    213       mpModule(NULL),
    214       mpOS(OS),
    215       mOT(OT),
    216       mGen(NULL),
    217       mPerFunctionPasses(NULL),
    218       mPerModulePasses(NULL),
    219       mCodeGenPasses(NULL),
    220       mLLVMContext(llvm::getGlobalContext()),
    221       mDiagEngine(*DiagEngine),
    222       mCodeGenOpts(CodeGenOpts),
    223       mPragmas(Pragmas) {
    224   FormattedOutStream.setStream(*mpOS,
    225                                llvm::formatted_raw_ostream::PRESERVE_STREAM);
    226   mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts,
    227                            mTargetOpts, mLLVMContext);
    228   return;
    229 }
    230 
    231 void Backend::Initialize(clang::ASTContext &Ctx) {
    232   mGen->Initialize(Ctx);
    233 
    234   mpModule = mGen->GetModule();
    235 
    236   return;
    237 }
    238 
    239 // Encase the Bitcode in a wrapper containing RS version information.
    240 void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
    241   bcinfo::AndroidBitcodeWrapper wrapper;
    242   size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
    243       &wrapper, Bitcode.str().length(), getTargetAPI(),
    244       SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
    245 
    246   slangAssert(actualWrapperLen > 0);
    247 
    248   // Write out the bitcode wrapper.
    249   FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
    250 
    251   // Write out the actual encoded bitcode.
    252   FormattedOutStream << Bitcode.str();
    253   return;
    254 }
    255 
    256 bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
    257   return mGen->HandleTopLevelDecl(D);
    258 }
    259 
    260 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
    261   HandleTranslationUnitPre(Ctx);
    262 
    263   mGen->HandleTranslationUnit(Ctx);
    264 
    265   // Here, we complete a translation unit (whole translation unit is now in LLVM
    266   // IR). Now, interact with LLVM backend to generate actual machine code (asm
    267   // or machine code, whatever.)
    268 
    269   // Silently ignore if we weren't initialized for some reason.
    270   if (!mpModule)
    271     return;
    272 
    273   llvm::Module *M = mGen->ReleaseModule();
    274   if (!M) {
    275     // The module has been released by IR gen on failures, do not double free.
    276     mpModule = NULL;
    277     return;
    278   }
    279 
    280   slangAssert(mpModule == M &&
    281               "Unexpected module change during LLVM IR generation");
    282 
    283   // Insert #pragma information into metadata section of module
    284   if (!mPragmas->empty()) {
    285     llvm::NamedMDNode *PragmaMetadata =
    286         mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
    287     for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
    288          I != E;
    289          I++) {
    290       llvm::SmallVector<llvm::Value*, 2> Pragma;
    291       // Name goes first
    292       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
    293       // And then value
    294       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
    295 
    296       // Create MDNode and insert into PragmaMetadata
    297       PragmaMetadata->addOperand(
    298           llvm::MDNode::get(mLLVMContext, Pragma));
    299     }
    300   }
    301 
    302   HandleTranslationUnitPost(mpModule);
    303 
    304   // Create passes for optimization and code emission
    305 
    306   // Create and run per-function passes
    307   CreateFunctionPasses();
    308   if (mPerFunctionPasses) {
    309     mPerFunctionPasses->doInitialization();
    310 
    311     for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    312          I != E;
    313          I++)
    314       if (!I->isDeclaration())
    315         mPerFunctionPasses->run(*I);
    316 
    317     mPerFunctionPasses->doFinalization();
    318   }
    319 
    320   // Create and run module passes
    321   CreateModulePasses();
    322   if (mPerModulePasses)
    323     mPerModulePasses->run(*mpModule);
    324 
    325   switch (mOT) {
    326     case Slang::OT_Assembly:
    327     case Slang::OT_Object: {
    328       if (!CreateCodeGenPasses())
    329         return;
    330 
    331       mCodeGenPasses->doInitialization();
    332 
    333       for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    334           I != E;
    335           I++)
    336         if (!I->isDeclaration())
    337           mCodeGenPasses->run(*I);
    338 
    339       mCodeGenPasses->doFinalization();
    340       break;
    341     }
    342     case Slang::OT_LLVMAssembly: {
    343       llvm::PassManager *LLEmitPM = new llvm::PassManager();
    344       LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
    345       LLEmitPM->run(*mpModule);
    346       break;
    347     }
    348     case Slang::OT_Bitcode: {
    349       llvm::PassManager *BCEmitPM = new llvm::PassManager();
    350       std::string BCStr;
    351       llvm::raw_string_ostream Bitcode(BCStr);
    352       unsigned int TargetAPI = getTargetAPI();
    353       switch (TargetAPI) {
    354         case SLANG_HC_TARGET_API:
    355         case SLANG_HC_MR1_TARGET_API:
    356         case SLANG_HC_MR2_TARGET_API: {
    357           // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
    358           BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
    359           break;
    360         }
    361         case SLANG_ICS_TARGET_API:
    362         case SLANG_ICS_MR1_TARGET_API: {
    363           // ICS targets must use the LLVM 2.9_func BitcodeWriter
    364           BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
    365           break;
    366         }
    367         default: {
    368           if (TargetAPI < SLANG_MINIMUM_TARGET_API ||
    369               TargetAPI > SLANG_MAXIMUM_TARGET_API) {
    370             slangAssert(false && "Invalid target API value");
    371           }
    372           // Switch to the 3.2 BitcodeWriter by default, and don't use
    373           // LLVM's included BitcodeWriter at all (for now).
    374           BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
    375           //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
    376           break;
    377         }
    378       }
    379 
    380       BCEmitPM->run(*mpModule);
    381       WrapBitcode(Bitcode);
    382       break;
    383     }
    384     case Slang::OT_Nothing: {
    385       return;
    386     }
    387     default: {
    388       slangAssert(false && "Unknown output type");
    389     }
    390   }
    391 
    392   FormattedOutStream.flush();
    393 
    394   return;
    395 }
    396 
    397 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
    398   mGen->HandleTagDeclDefinition(D);
    399   return;
    400 }
    401 
    402 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
    403   mGen->CompleteTentativeDefinition(D);
    404   return;
    405 }
    406 
    407 Backend::~Backend() {
    408   delete mpModule;
    409   delete mGen;
    410   delete mPerFunctionPasses;
    411   delete mPerModulePasses;
    412   delete mCodeGenPasses;
    413   return;
    414 }
    415 
    416 }  // namespace slang
    417