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