Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2015, 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 "bcinfo/BitcodeWrapper.h"
     18 
     19 #include "llvm/Support/raw_ostream.h"
     20 
     21 #include "BitWriter_2_9/ReaderWriter_2_9.h"
     22 #include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
     23 #include "BitWriter_3_2/ReaderWriter_3_2.h"
     24 
     25 #include "slang_assert.h"
     26 #include "slang_bitcode_gen.h"
     27 #include "slang_version.h"
     28 #include "llvm/Bitcode/ReaderWriter.h"
     29 
     30 namespace slang {
     31 
     32 void writeBitcode(llvm::raw_ostream &Out,
     33                   const llvm::Module &M,
     34                   uint32_t TargetAPI,
     35                   uint32_t OptimizationLevel,
     36                   bool GenerateDebugInfo) {
     37   std::string BitcodeStr;
     38   llvm::raw_string_ostream Bitcode(BitcodeStr);
     39 
     40   // The older bitcode writers will produce invalid bitcode if the -g
     41   // flag is set using WriteBitcodeToFile. As such we use the ToT writer
     42   // when -g is set. However, this will produce a bitcode file linked to
     43   // this version of LLVM as the debug info format can change between
     44   // versions.
     45   // If bcc receives a bitcode file with a format of debug info
     46   // which is either ahead or behind the version it is expecting it will
     47   // fail the verification stage. Failing this stage results in the bitcode
     48   // loader returning null and the compiler will terminate abruptly. Bitcode
     49   // files with debug info are as such only capable of targeting devices with
     50   // LLVM libraries with the same debug info version as the version of slang
     51   // which was used to compile the file. This is due to the fact that LLVM
     52   // offers no backwards or forwards compatibility guarantee for its debug
     53   // bitcode. At the moment the only practical guarantee which can be made
     54   // is that the debug bitcode emitted by any slang will work with the bcc
     55   // version which was newest at the time when llvm-rs-cc was built.
     56   if (GenerateDebugInfo) {
     57     llvm::WriteBitcodeToFile(&M, Bitcode);
     58   } else {
     59     // Create the bitcode.
     60     switch (TargetAPI) {
     61     case SLANG_HC_TARGET_API:
     62     case SLANG_HC_MR1_TARGET_API:
     63     case SLANG_HC_MR2_TARGET_API: {
     64       // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
     65       llvm_2_9::WriteBitcodeToFile(&M, Bitcode);
     66       break;
     67     }
     68     case SLANG_ICS_TARGET_API:
     69     case SLANG_ICS_MR1_TARGET_API: {
     70       // ICS targets must use the LLVM 2.9_func BitcodeWriter
     71       llvm_2_9_func::WriteBitcodeToFile(&M, Bitcode);
     72       break;
     73     }
     74     default: {
     75       if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
     76           (TargetAPI < SLANG_MINIMUM_TARGET_API ||
     77            TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
     78         slangAssert(false && "Invalid target API value");
     79       }
     80       // Switch to the 3.2 BitcodeWriter by default, and don't use
     81       // LLVM's included BitcodeWriter at all (for now).
     82       llvm_3_2::WriteBitcodeToFile(&M, Bitcode);
     83       break;
     84     }
     85     }
     86   }
     87 
     88   const uint32_t CompilerVersion = SlangVersion::CURRENT;
     89 
     90   // Create the bitcode wrapper.
     91   bcinfo::AndroidBitcodeWrapper Wrapper;
     92   size_t ActualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
     93         &Wrapper, Bitcode.str().length(), TargetAPI,
     94         CompilerVersion, OptimizationLevel);
     95 
     96   slangAssert(ActualWrapperLen > 0);
     97 
     98   // Write out the file.
     99   Out.write(reinterpret_cast<char*>(&Wrapper), ActualWrapperLen);
    100   Out << Bitcode.str();
    101 }
    102 
    103 }  // namespace slang
    104