You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.8 KiB
104 lines
3.8 KiB
/*
|
|
* Copyright 2015, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "bcinfo/BitcodeWrapper.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include "BitWriter_2_9/ReaderWriter_2_9.h"
|
|
#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
|
|
#include "BitWriter_3_2/ReaderWriter_3_2.h"
|
|
|
|
#include "slang_assert.h"
|
|
#include "slang_bitcode_gen.h"
|
|
#include "slang_version.h"
|
|
#include "llvm/Bitcode/ReaderWriter.h"
|
|
|
|
namespace slang {
|
|
|
|
void writeBitcode(llvm::raw_ostream &Out,
|
|
const llvm::Module &M,
|
|
uint32_t TargetAPI,
|
|
uint32_t OptimizationLevel,
|
|
bool GenerateDebugInfo) {
|
|
std::string BitcodeStr;
|
|
llvm::raw_string_ostream Bitcode(BitcodeStr);
|
|
|
|
// The older bitcode writers will produce invalid bitcode if the -g
|
|
// flag is set using WriteBitcodeToFile. As such we use the ToT writer
|
|
// when -g is set. However, this will produce a bitcode file linked to
|
|
// this version of LLVM as the debug info format can change between
|
|
// versions.
|
|
// If bcc receives a bitcode file with a format of debug info
|
|
// which is either ahead or behind the version it is expecting it will
|
|
// fail the verification stage. Failing this stage results in the bitcode
|
|
// loader returning null and the compiler will terminate abruptly. Bitcode
|
|
// files with debug info are as such only capable of targeting devices with
|
|
// LLVM libraries with the same debug info version as the version of slang
|
|
// which was used to compile the file. This is due to the fact that LLVM
|
|
// offers no backwards or forwards compatibility guarantee for its debug
|
|
// bitcode. At the moment the only practical guarantee which can be made
|
|
// is that the debug bitcode emitted by any slang will work with the bcc
|
|
// version which was newest at the time when llvm-rs-cc was built.
|
|
if (GenerateDebugInfo) {
|
|
llvm::WriteBitcodeToFile(&M, Bitcode);
|
|
} else {
|
|
// Create the bitcode.
|
|
switch (TargetAPI) {
|
|
case SLANG_HC_TARGET_API:
|
|
case SLANG_HC_MR1_TARGET_API:
|
|
case SLANG_HC_MR2_TARGET_API: {
|
|
// Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
|
|
llvm_2_9::WriteBitcodeToFile(&M, Bitcode);
|
|
break;
|
|
}
|
|
case SLANG_ICS_TARGET_API:
|
|
case SLANG_ICS_MR1_TARGET_API: {
|
|
// ICS targets must use the LLVM 2.9_func BitcodeWriter
|
|
llvm_2_9_func::WriteBitcodeToFile(&M, Bitcode);
|
|
break;
|
|
}
|
|
default: {
|
|
if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
|
|
(TargetAPI < SLANG_MINIMUM_TARGET_API ||
|
|
TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
|
|
slangAssert(false && "Invalid target API value");
|
|
}
|
|
// Switch to the 3.2 BitcodeWriter by default, and don't use
|
|
// LLVM's included BitcodeWriter at all (for now).
|
|
llvm_3_2::WriteBitcodeToFile(&M, Bitcode);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const uint32_t CompilerVersion = SlangVersion::CURRENT;
|
|
|
|
// Create the bitcode wrapper.
|
|
bcinfo::AndroidBitcodeWrapper Wrapper;
|
|
size_t ActualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
|
|
&Wrapper, Bitcode.str().length(), TargetAPI,
|
|
CompilerVersion, OptimizationLevel);
|
|
|
|
slangAssert(ActualWrapperLen > 0);
|
|
|
|
// Write out the file.
|
|
Out.write(reinterpret_cast<char*>(&Wrapper), ActualWrapperLen);
|
|
Out << Bitcode.str();
|
|
}
|
|
|
|
} // namespace slang
|