am 704c0b2a: am 16b9a4f1: Merge "llvm-rs-as: Wrap bitcode with the RS bitcode wrapper."
* commit '704c0b2acecbe7a5cafaf1f53e96c5c1ff24a273':
llvm-rs-as: Wrap bitcode with the RS bitcode wrapper.
diff --git a/Android.mk b/Android.mk
index 55f35e7..4fdd5a5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -81,6 +81,7 @@
LOCAL_SRC_FILES := \
slang.cpp \
+ slang_bitcode_gen.cpp \
slang_backend.cpp \
slang_pragma_recorder.cpp \
slang_diagnostic_buffer.cpp
diff --git a/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll b/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll
new file mode 100644
index 0000000..77e32c0
--- /dev/null
+++ b/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll
@@ -0,0 +1,51 @@
+; This test assembles this file to bitcode with all supported target
+; API versions, then checks that the bitcode file was generated and
+; has the right magic number.
+
+; RUN: %llvm-rs-as -target-api 11 %s -o %t11
+; RUN: xxd -ps -l 4 %t11 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 12 %s -o %t12
+; RUN: xxd -ps -l 4 %t12 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 13 %s -o %t13
+; RUN: xxd -ps -l 4 %t13 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 14 %s -o %t14
+; RUN: xxd -ps -l 4 %t14 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 15 %s -o %t15
+; RUN: xxd -ps -l 4 %t15 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 16 %s -o %t16
+; RUN: xxd -ps -l 4 %t16 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 17 %s -o %t17
+; RUN: xxd -ps -l 4 %t17 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 18 %s -o %t18
+; RUN: xxd -ps -l 4 %t18 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 19 %s -o %t19
+; RUN: xxd -ps -l 4 %t19 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 20 %s -o %t20
+; RUN: xxd -ps -l 4 %t20 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 21 %s -o %t21
+; RUN: xxd -ps -l 4 %t21 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 22 %s -o %t22
+; RUN: xxd -ps -l 4 %t22 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 23 %s -o %t23
+; RUN: xxd -ps -l 4 %t23 | FileCheck %s
+
+; RUN: %llvm-rs-as -target-api 0 %s -o %t0
+; RUN: xxd -ps -l 4 %t0 | FileCheck %s
+
+; Check for the magic number.
+
+; CHECK: dec0170b
+
+; ModuleID = 'kernel.bc'
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"clang version 3.6 "}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"foo"}
diff --git a/lit-tests/lit.cfg b/lit-tests/lit.cfg
index 23337a1..88ad6e6 100644
--- a/lit-tests/lit.cfg
+++ b/lit-tests/lit.cfg
@@ -6,7 +6,7 @@
config.name = 'slang_lit_tests'
# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.rs']
+config.suffixes = ['.rs', '.ll']
# testFormat: The test format to use to interpret tests.
import lit.formats
@@ -45,6 +45,7 @@
return os.path.abspath(tool)
config.slang = inferTool('llvm-rs-cc', 'SLANG', os.path.join(config.base_path, 'out', 'host', 'linux-x86', 'bin')).replace('\\', '/')
+config.llvm_rs_as = inferTool('llvm-rs-as', 'LLVM_RS_AS', os.path.join(config.base_path, 'out', 'host', 'linux-x86', 'bin')).replace('\\', '/')
config.filecheck = inferTool('FileCheck', 'FILECHECK', config.environment['PATH'])
config.rs_filecheck_wrapper = inferTool('rs-filecheck-wrapper.sh', 'RS_FILECHECK_WRAPPER', os.path.join(config.base_path, 'frameworks', 'compile', 'slang', 'lit-tests'))
@@ -59,10 +60,12 @@
if not lit_config.quiet:
lit_config.note('using slang: %r' % config.slang)
+ lit_config.note('using llvm-rs-as: %r' % config.llvm_rs_as)
lit_config.note('using FileCheck: %r' % config.filecheck)
lit_config.note('using rs-filecheck-wrapper.sh: %r' % config.rs_filecheck_wrapper)
lit_config.note('using output directory: %r' % config.test_exec_root)
# Tools configuration substitutions
config.substitutions.append( ('%Slang', ' ' + config.slang + ' ' + config.slang_includes + ' ' + config.slang_options ) )
+config.substitutions.append( ('%llvm-rs-as', config.llvm_rs_as) )
config.substitutions.append( ('%rs-filecheck-wrapper', ' ' + config.rs_filecheck_wrapper + ' ' + config.test_exec_root + ' ' + config.filecheck + ' ') )
diff --git a/llvm-rs-as.cpp b/llvm-rs-as.cpp
index 1f81b14..c63a1ac 100644
--- a/llvm-rs-as.cpp
+++ b/llvm-rs-as.cpp
@@ -29,9 +29,8 @@
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "BitWriter_3_2/ReaderWriter_3_2.h"
-#include "BitWriter_2_9/ReaderWriter_2_9.h"
-#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
+#include "slang_bitcode_gen.h"
+#include "slang_version.h"
#include <memory>
using namespace llvm;
@@ -49,6 +48,11 @@
static cl::opt<bool>
DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false));
+static cl::opt<uint32_t>
+TargetAPI("target-api", cl::desc("Specify RenderScript target API version "
+ "(0 = development API) (default is 0)"),
+ cl::init(0));
+
static cl::opt<bool>
DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
@@ -56,20 +60,8 @@
DisableVerify("disable-verify", cl::Hidden,
cl::desc("Do not run verifier on input LLVM (dangerous!)"));
-enum BCVersion {
- BC29, BC29Func, BC32, BCHEAD
-};
-cl::opt<BCVersion> BitcodeVersion("bitcode-version",
- cl::desc("Set the bitcode version to be written:"),
- cl::values(
- clEnumValN(BC29, "BC29", "Version 2.9"),
- clEnumVal(BC29Func, "Version 2.9 func"),
- clEnumVal(BC32, "Version 3.2"),
- clEnumVal(BCHEAD, "Most current version"),
- clEnumValEnd), cl::init(BC32));
-
-static void WriteOutputFile(const Module *M) {
+static void WriteOutputFile(const Module *M, uint32_t ModuleTargetAPI) {
// Infer the output filename if needed.
if (OutputFilename.empty()) {
if (InputFilename == "-") {
@@ -97,24 +89,15 @@
}
if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) {
- switch(BitcodeVersion) {
- case BC29:
- llvm_2_9::WriteBitcodeToFile(M, Out->os());
- break;
- case BC29Func:
- llvm_2_9_func::WriteBitcodeToFile(M, Out->os());
- break;
- case BC32:
- llvm_3_2::WriteBitcodeToFile(M, Out->os());
- break;
- case BCHEAD:
- llvm::WriteBitcodeToFile(M, Out->os());
- break;
+ slang::writeBitcode(Out->os(), *M,
+ /* TargetAPI = */ ModuleTargetAPI,
+ /* OptimizationLevel = */ 3);
+
+ if (!Out->os().has_error()) {
+ // Declare success.
+ Out->keep();
}
}
-
- // Declare success.
- Out->keep();
}
int main(int argc, char **argv) {
@@ -125,6 +108,18 @@
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
+ // Check target API.
+ uint32_t ActualTargetAPI = (TargetAPI == 0) ? RS_DEVELOPMENT_API : TargetAPI;
+
+ if (ActualTargetAPI != RS_DEVELOPMENT_API &&
+ (ActualTargetAPI < SLANG_MINIMUM_TARGET_API ||
+ ActualTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
+ errs() << "target API level '" << ActualTargetAPI << "' is out of range "
+ << "('" << SLANG_MINIMUM_TARGET_API << "' - '"
+ << SLANG_MAXIMUM_TARGET_API << "')\n";
+ return 1;
+ }
+
// Parse the file now...
SMDiagnostic Err;
std::unique_ptr<Module> M(parseAssemblyFile(InputFilename, Err, Context));
@@ -147,7 +142,7 @@
if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get();
if (!DisableOutput)
- WriteOutputFile(M.get());
+ WriteOutputFile(M.get(), ActualTargetAPI);
return 0;
}
diff --git a/slang_backend.cpp b/slang_backend.cpp
index ff41367..79cd783 100644
--- a/slang_backend.cpp
+++ b/slang_backend.cpp
@@ -19,8 +19,6 @@
#include <string>
#include <vector>
-#include "bcinfo/BitcodeWrapper.h"
-
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
@@ -64,6 +62,7 @@
#include "slang_assert.h"
#include "slang.h"
+#include "slang_bitcode_gen.h"
#include "slang_rs_context.h"
#include "slang_rs_export_foreach.h"
#include "slang_rs_export_func.h"
@@ -72,9 +71,6 @@
#include "slang_rs_metadata.h"
#include "strip_unknown_attributes.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"
namespace slang {
@@ -234,22 +230,6 @@
mpModule = mGen->GetModule();
}
-// Encase the Bitcode in a wrapper containing RS version information.
-void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
- bcinfo::AndroidBitcodeWrapper wrapper;
- size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
- &wrapper, Bitcode.str().length(), getTargetAPI(),
- SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
-
- slangAssert(actualWrapperLen > 0);
-
- // Write out the bitcode wrapper.
- mBufferOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
-
- // Write out the actual encoded bitcode.
- mBufferOutStream << Bitcode.str();
-}
-
void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
HandleTranslationUnitPre(Ctx);
@@ -339,40 +319,8 @@
break;
}
case Slang::OT_Bitcode: {
- llvm::legacy::PassManager *BCEmitPM = new llvm::legacy::PassManager();
- std::string BCStr;
- llvm::raw_string_ostream Bitcode(BCStr);
- unsigned int TargetAPI = getTargetAPI();
- 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
- BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
- break;
- }
- case SLANG_ICS_TARGET_API:
- case SLANG_ICS_MR1_TARGET_API: {
- // ICS targets must use the LLVM 2.9_func BitcodeWriter
- BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(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).
- BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
- //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
- break;
- }
- }
-
- BCEmitPM->run(*mpModule);
- WrapBitcode(Bitcode);
+ writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
+ mCodeGenOpts.OptimizationLevel);
break;
}
case Slang::OT_Nothing: {
diff --git a/slang_backend.h b/slang_backend.h
index e3dbdef..c3eb3bc 100644
--- a/slang_backend.h
+++ b/slang_backend.h
@@ -81,8 +81,6 @@
void CreateModulePasses();
bool CreateCodeGenPasses();
- void WrapBitcode(llvm::raw_string_ostream &Bitcode);
-
RSContext *mContext;
clang::SourceManager &mSourceMgr;
diff --git a/slang_bitcode_gen.cpp b/slang_bitcode_gen.cpp
new file mode 100644
index 0000000..83d96bf
--- /dev/null
+++ b/slang_bitcode_gen.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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"
+
+namespace slang {
+
+void writeBitcode(llvm::raw_ostream &Out,
+ const llvm::Module &M,
+ uint32_t TargetAPI,
+ uint32_t OptimizationLevel) {
+ std::string BitcodeStr;
+ llvm::raw_string_ostream Bitcode(BitcodeStr);
+
+ // 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
diff --git a/slang_bitcode_gen.h b/slang_bitcode_gen.h
new file mode 100644
index 0000000..cc0e9f6
--- /dev/null
+++ b/slang_bitcode_gen.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_ // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_
+
+#include <cstdint>
+
+namespace llvm {
+ class raw_ostream;
+ class Module;
+}
+
+namespace slang {
+
+// Write out the LLVM bitcode for a module, encased in a wrapper
+// containing RS version information.
+void writeBitcode(llvm::raw_ostream &Out,
+ const llvm::Module &M,
+ uint32_t TargetAPI,
+ uint32_t OptimizationLevel);
+
+} // end namespace slang
+
+#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_ NOLINT