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