blob: dc0eb8d9d0e234434f31037221032020354c3cdc [file] [log] [blame]
Matt Waladabd2462015-07-15 18:39:41 -07001/*
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"
Stephen McGroartyb130e152015-07-23 16:55:02 +010028#include "llvm/Bitcode/ReaderWriter.h"
Matt Waladabd2462015-07-15 18:39:41 -070029
30namespace slang {
31
32void writeBitcode(llvm::raw_ostream &Out,
33 const llvm::Module &M,
34 uint32_t TargetAPI,
Stephen McGroartyb130e152015-07-23 16:55:02 +010035 uint32_t OptimizationLevel,
36 bool GenerateDebugInfo) {
Matt Waladabd2462015-07-15 18:39:41 -070037 std::string BitcodeStr;
38 llvm::raw_string_ostream Bitcode(BitcodeStr);
39
Stephen McGroartyb130e152015-07-23 16:55:02 +010040 // 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;
Matt Waladabd2462015-07-15 18:39:41 -070067 }
Stephen McGroartyb130e152015-07-23 16:55:02 +010068 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 }
Matt Waladabd2462015-07-15 18:39:41 -070086 }
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