aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-06-10 23:53:00 -0700
committerStephen Hines <srhines@google.com>2014-07-09 00:59:39 -0700
commit9ae18b2bbee0b08afd400542e863dd665ff76059 (patch)
tree979861baa5023caa4f4a2335dd307526634f0581
parentafa84a9112db3b135f88d736b4c8249a049eb40a (diff)
downloadandroid_frameworks_compile_slang-9ae18b2bbee0b08afd400542e863dd665ff76059.tar.gz
android_frameworks_compile_slang-9ae18b2bbee0b08afd400542e863dd665ff76059.tar.bz2
android_frameworks_compile_slang-9ae18b2bbee0b08afd400542e863dd665ff76059.zip
Add an option to emit 32-bit and 64-bit bitcode.
Bug: 16031597 Change-Id: Ifb3c4eca5e7ae16106260c2b5f5da6854c021a3a
-rw-r--r--RSCCOptions.td3
-rw-r--r--llvm-rs-cc.cpp130
-rw-r--r--rs_cc_options.cpp6
-rw-r--r--rs_cc_options.h20
-rw-r--r--slang.cpp40
-rw-r--r--slang.h18
-rw-r--r--slang_rs.cpp45
-rw-r--r--slang_rs.h3
-rw-r--r--slang_rs_context.cpp3
-rw-r--r--slang_rs_context.h5
-rw-r--r--slang_rs_export_type.cpp18
-rw-r--r--slang_rs_object_ref_count.cpp8
-rw-r--r--slang_rs_reflect_utils.cpp60
-rw-r--r--slang_rs_reflect_utils.h6
-rw-r--r--slang_rs_reflection.cpp4
-rw-r--r--tests/P_v64/stderr.txt.expect0
-rw-r--r--tests/P_v64/stdout.txt.expect0
-rw-r--r--tests/P_v64/v64.rs23
18 files changed, 262 insertions, 130 deletions
diff --git a/RSCCOptions.td b/RSCCOptions.td
index 1d5f536..554e971 100644
--- a/RSCCOptions.td
+++ b/RSCCOptions.td
@@ -137,5 +137,8 @@ def version : Flag<["-"], "version">,
HelpText<"Print the assembler version">;
def _version : Flag<["--"], "version">, Alias<version>;
+def emit_32_64 : Flag<["-"], "emit_32_64">,
+ HelpText<"Emit 32-bit and 64-bit bitcode in source files">;
+
// Compatible with old slang
def no_link : Flag<["-"], "no-link">; // currently no effect
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index 0e8589b..e7300d2 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -59,6 +59,7 @@ static void ExpandArgv(int argc, const char **argv,
std::set<std::string> &SavedStrings);
static const char *DetermineOutputFile(const std::string &OutputDir,
+ const std::string &PathSuffix,
const char *InputFile,
slang::Slang::OutputType OutputType,
std::set<std::string> &SavedStrings) {
@@ -72,6 +73,11 @@ static const char *DetermineOutputFile(const std::string &OutputDir,
(OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
OutputFile.append(1, OS_PATH_SEPARATOR);
+ if (!PathSuffix.empty()) {
+ OutputFile.append(PathSuffix);
+ OutputFile.append(1, OS_PATH_SEPARATOR);
+ }
+
if (OutputType == slang::Slang::OT_Dependency) {
// The build system wants the .d file name stem to be exactly the same as
// the source .rs file, instead of the .bc file.
@@ -111,6 +117,77 @@ static const char *DetermineOutputFile(const std::string &OutputDir,
return SaveStringInSet(SavedStrings, OutputFile);
}
+typedef std::list<std::pair<const char*, const char*> > NamePairList;
+
+/*
+ * Compile the Inputs.
+ *
+ * Returns 0 on success and nonzero on failure.
+ *
+ * IOFiles - list of (foo.rs, foo.bc) pairs of input/output files.
+ * IOFiles32 - list of input/output pairs for 32-bit compilation.
+ * Inputs - input filenames.
+ * Opts - options controlling compilation.
+ * DiagEngine - Clang diagnostic engine (for creating diagnostics).
+ * DiagClient - Slang diagnostic consumer (collects and displays diagnostics).
+ * SavedStrings - expanded strings copied from argv source input files.
+ *
+ * We populate IOFiles dynamically while working through the list of Inputs.
+ * On any 64-bit compilation, we pass back in the 32-bit pairs of files as
+ * IOFiles32. This allows the 64-bit compiler to later bundle up both the
+ * 32-bit and 64-bit bitcode outputs to be included in the final reflected
+ * source code that is emitted.
+ */
+static int compileFiles(NamePairList *IOFiles, NamePairList *IOFiles32,
+ const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts,
+ clang::DiagnosticsEngine *DiagEngine, slang::DiagnosticBuffer *DiagClient,
+ std::set<std::string> *SavedStrings) {
+ NamePairList DepFiles;
+ std::string PathSuffix = "";
+
+ // In our mixed 32/64-bit path, we need to suffix our files differently for
+ // both 32-bit and 64-bit versions.
+ if (Opts.mEmit3264) {
+ if (Opts.mBitWidth == 64) {
+ PathSuffix = "bc64";
+ } else {
+ PathSuffix = "bc32";
+ }
+ }
+
+ for (int i = 0, e = Inputs.size(); i != e; i++) {
+ const char *InputFile = Inputs[i];
+
+ const char *BCOutputFile = DetermineOutputFile(Opts.mBitcodeOutputDir,
+ PathSuffix, InputFile,
+ slang::Slang::OT_Bitcode,
+ *SavedStrings);
+ const char *OutputFile = BCOutputFile;
+
+ if (Opts.mEmitDependency) {
+ // The dependency file is always emitted without a PathSuffix.
+ // Collisions between 32-bit and 64-bit files don't make a difference,
+ // because they share the same sources/dependencies.
+ const char *DepOutputFile =
+ DetermineOutputFile(Opts.mDependencyOutputDir, "", InputFile,
+ slang::Slang::OT_Dependency, *SavedStrings);
+ if (Opts.mOutputType == slang::Slang::OT_Dependency) {
+ OutputFile = DepOutputFile;
+ }
+
+ DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
+ }
+
+ IOFiles->push_back(std::make_pair(InputFile, OutputFile));
+ }
+
+ llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
+ Compiler->init(Opts.mBitWidth, DiagEngine, DiagClient);
+ int CompileFailed = !Compiler->compile(*IOFiles, *IOFiles32, DepFiles, Opts);
+ Compiler->reset();
+ return CompileFailed;
+}
+
#define str(s) #s
#define wrap_str(s) str(s)
static void llvm_rs_cc_VersionPrinter() {
@@ -137,7 +214,7 @@ int main(int argc, const char **argv) {
llvm::SmallVector<const char*, 16> Inputs;
std::string Argv0;
- atexit(llvm::llvm_shutdown);
+ llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
ExpandArgv(argc, argv, ArgVector, SavedStrings);
@@ -184,52 +261,19 @@ int main(int argc, const char **argv) {
}
// Prepare input data for RS compiler.
- std::list<std::pair<const char*, const char*> > IOFiles;
- std::list<std::pair<const char*, const char*> > DepFiles;
+ NamePairList IOFiles64;
+ NamePairList IOFiles32;
- llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
-
- Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine,
- DiagClient);
-
- for (int i = 0, e = Inputs.size(); i != e; i++) {
- const char *InputFile = Inputs[i];
- const char *OutputFile =
- DetermineOutputFile(Opts.mBitcodeOutputDir, InputFile,
- Opts.mOutputType, SavedStrings);
+ int CompileFailed = compileFiles(&IOFiles32, &IOFiles32, Inputs, Opts,
+ &DiagEngine, DiagClient, &SavedStrings);
- if (Opts.mEmitDependency) {
- const char *BCOutputFile, *DepOutputFile;
-
- if (Opts.mOutputType == slang::Slang::OT_Bitcode)
- BCOutputFile = OutputFile;
- else
- BCOutputFile = DetermineOutputFile(Opts.mDependencyOutputDir,
- InputFile,
- slang::Slang::OT_Bitcode,
- SavedStrings);
-
- if (Opts.mOutputType == slang::Slang::OT_Dependency)
- DepOutputFile = OutputFile;
- else
- DepOutputFile = DetermineOutputFile(Opts.mDependencyOutputDir,
- InputFile,
- slang::Slang::OT_Dependency,
- SavedStrings);
-
- DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
- }
-
- IOFiles.push_back(std::make_pair(InputFile, OutputFile));
+ // Handle the 64-bit case too!
+ if (Opts.mEmit3264 && !CompileFailed) {
+ Opts.mBitWidth = 64;
+ CompileFailed = compileFiles(&IOFiles64, &IOFiles32, Inputs, Opts,
+ &DiagEngine, DiagClient, &SavedStrings);
}
- // Let's rock!
- int CompileFailed = !Compiler->compile(IOFiles,
- DepFiles,
- Opts);
-
- Compiler->reset();
-
return CompileFailed;
}
diff --git a/rs_cc_options.cpp b/rs_cc_options.cpp
index 474250c..987313b 100644
--- a/rs_cc_options.cpp
+++ b/rs_cc_options.cpp
@@ -206,6 +206,12 @@ void slang::ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector,
Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
Opts.mVerbose = Args->hasArg(OPT_verbose);
+ // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
+ Opts.mEmit3264 = Args->hasArg(OPT_emit_32_64);
+ if (Opts.mEmit3264) {
+ Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
+ }
+
size_t OptLevel =
clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine);
diff --git a/rs_cc_options.h b/rs_cc_options.h
index eff673a..8bdd7bc 100644
--- a/rs_cc_options.h
+++ b/rs_cc_options.h
@@ -51,15 +51,8 @@ class RSCCOptions {
// Allow user-defined functions prefixed with 'rs'.
bool mAllowRSPrefix;
- // The name of the target triple to compile for.
- std::string mTriple;
-
- // The name of the target CPU to generate code for.
- std::string mCPU;
-
- // The list of target specific features to enable or disable -- this should
- // be a list of strings starting with by '+' or '-'.
- std::vector<std::string> mFeatures;
+ // 32-bit or 64-bit target
+ uint32_t mBitWidth;
// The path for storing reflected Java source files
// (i.e. out/target/common/obj/APPS/.../src/renderscript/src).
@@ -102,12 +95,12 @@ class RSCCOptions {
// Display verbose information about the compilation on stdout.
bool mVerbose;
+ // Emit both 32-bit and 64-bit bitcode (embedded in the reflected sources).
+ bool mEmit3264;
+
RSCCOptions() {
mOutputType = slang::Slang::OT_Bitcode;
- // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
- mTriple = "armv7-none-linux-gnueabi";
- mCPU = "";
- mFeatures.push_back("+long64");
+ mBitWidth = 32;
mBitcodeStorage = slang::BCST_APK_RESOURCE;
mEmitDependency = 0;
mShowHelp = 0;
@@ -116,6 +109,7 @@ class RSCCOptions {
mDebugEmission = 0;
mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
mVerbose = false;
+ mEmit3264 = false;
}
};
diff --git a/slang.cpp b/slang.cpp
index dcb0aad..d982e4d 100644
--- a/slang.cpp
+++ b/slang.cpp
@@ -72,6 +72,9 @@
namespace {
+static const char *kRSTriple32 = "armv7-none-linux-gnueabi";
+static const char *kRSTriple64 = "aarch64-none-linux-gnueabi";
+
struct ForceSlangLinking {
ForceSlangLinking() {
// We must reference the functions in such a way that compilers will not
@@ -95,15 +98,6 @@ struct ForceSlangLinking {
namespace slang {
-#if defined(__arm__)
-# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
-#elif defined(__x86_64__)
-# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
-#else
-// let's use x86 as default target
-# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
-#endif
-
bool Slang::GlobalInitialized = false;
// Language option (define the language feature for compiler such as C99)
@@ -176,18 +170,17 @@ void Slang::LLVMErrorHandler(void *UserData, const std::string &Message,
exit(1);
}
-void Slang::createTarget(const std::string &Triple, const std::string &CPU,
- const std::vector<std::string> &Features) {
- if (!Triple.empty())
- mTargetOpts->Triple = Triple;
- else
- mTargetOpts->Triple = DEFAULT_TARGET_TRIPLE_STRING;
+void Slang::createTarget(uint32_t BitWidth) {
+ std::vector<std::string> features;
- if (!CPU.empty())
- mTargetOpts->CPU = CPU;
-
- if (!Features.empty())
- mTargetOpts->FeaturesAsWritten = Features;
+ if (BitWidth == 64) {
+ mTargetOpts->Triple = kRSTriple64;
+ } else {
+ mTargetOpts->Triple = kRSTriple32;
+ // Treat long as a 64-bit type for our 32-bit RS code.
+ features.push_back("+long64");
+ mTargetOpts->FeaturesAsWritten = features;
+ }
mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
mTargetOpts.getPtr()));
@@ -270,9 +263,7 @@ Slang::Slang() : mInitialized(false), mDiagClient(NULL), mOT(OT_Default) {
GlobalInitialization();
}
-void Slang::init(const std::string &Triple, const std::string &CPU,
- const std::vector<std::string> &Features,
- clang::DiagnosticsEngine *DiagEngine,
+void Slang::init(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
DiagnosticBuffer *DiagClient) {
if (mInitialized)
return;
@@ -283,7 +274,7 @@ void Slang::init(const std::string &Triple, const std::string &CPU,
initDiagnostic();
llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagEngine);
- createTarget(Triple, CPU, Features);
+ createTarget(BitWidth);
createFileManager();
createSourceManager();
@@ -486,7 +477,6 @@ void Slang::reset() {
}
Slang::~Slang() {
- llvm::llvm_shutdown();
}
} // namespace slang
diff --git a/slang.h b/slang.h
index a60c5c7..c733a52 100644
--- a/slang.h
+++ b/slang.h
@@ -94,8 +94,7 @@ class Slang : public clang::ModuleLoader {
// The target being compiled for
llvm::IntrusiveRefCntPtr<clang::TargetOptions> mTargetOpts;
llvm::OwningPtr<clang::TargetInfo> mTarget;
- void createTarget(std::string const &Triple, std::string const &CPU,
- std::vector<std::string> const &Features);
+ void createTarget(uint32_t BitWidth);
// File manager (for prepocessor doing the job such as header file search)
@@ -126,6 +125,7 @@ class Slang : public clang::ModuleLoader {
// File names
std::string mInputFileName;
std::string mOutputFileName;
+ std::string mOutput32FileName;
std::string mDepOutputFileName;
std::string mDepTargetBCFileName;
@@ -171,9 +171,7 @@ class Slang : public clang::ModuleLoader {
Slang();
- void init(const std::string &Triple, const std::string &CPU,
- const std::vector<std::string> &Features,
- clang::DiagnosticsEngine *DiagEngine,
+ void init(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
DiagnosticBuffer *DiagClient);
virtual clang::ModuleLoadResult loadModule(
@@ -197,10 +195,20 @@ class Slang : public clang::ModuleLoader {
bool setOutput(const char *OutputFile);
+ // For use with 64-bit compilation/reflection. This only sets the filename of
+ // the 32-bit bitcode file, and doesn't actually verify it already exists.
+ void setOutput32(const char *OutputFile) {
+ mOutput32FileName = OutputFile;
+ }
+
std::string const &getOutputFileName() const {
return mOutputFileName;
}
+ std::string const &getOutput32FileName() const {
+ return mOutput32FileName;
+ }
+
bool setDepOutput(const char *OutputFile);
void setDepTargetBC(const char *TargetBCFile) {
diff --git a/slang_rs.cpp b/slang_rs.cpp
index 3b6d4b7..bc46972 100644
--- a/slang_rs.cpp
+++ b/slang_rs.cpp
@@ -82,11 +82,13 @@ bool SlangRS::generateJavaBitcodeAccessor(const std::string &OutputPathBase,
RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
BCAccessorContext.rsFileName = getInputFileName().c_str();
- BCAccessorContext.bcFileName = getOutputFileName().c_str();
+ BCAccessorContext.bc32FileName = getOutput32FileName().c_str();
+ BCAccessorContext.bc64FileName = getOutputFileName().c_str();
BCAccessorContext.reflectPath = OutputPathBase.c_str();
BCAccessorContext.packageName = PackageName.c_str();
BCAccessorContext.licenseNote = LicenseNote;
BCAccessorContext.bcStorage = BCST_JAVA_CODE; // Must be BCST_JAVA_CODE
+ BCAccessorContext.verbose = false;
return RSSlangReflectUtils::GenerateJavaBitCodeAccessor(BCAccessorContext);
}
@@ -270,22 +272,31 @@ SlangRS::SlangRS()
}
bool SlangRS::compile(
- const std::list<std::pair<const char*, const char*> > &IOFiles,
+ const std::list<std::pair<const char*, const char*> > &IOFiles64,
+ const std::list<std::pair<const char*, const char*> > &IOFiles32,
const std::list<std::pair<const char*, const char*> > &DepFiles,
const RSCCOptions &Opts) {
- if (IOFiles.empty())
+ if (IOFiles32.empty())
return true;
- if (Opts.mEmitDependency && (DepFiles.size() != IOFiles.size())) {
+ if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) {
getDiagnostics().Report(mDiagErrorInvalidOutputDepParameter);
return false;
}
+ if (Opts.mEmit3264 && (IOFiles64.size() != IOFiles32.size())) {
+ slangAssert(false && "Should have equal number of 32/64-bit files");
+ return false;
+ }
+
std::string RealPackageName;
- const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile;
+ const char *InputFile, *Output64File, *Output32File, *BCOutputFile,
+ *DepOutputFile;
std::list<std::pair<const char*, const char*> >::const_iterator
- IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin();
+ IOFile64Iter = IOFiles64.begin(),
+ IOFile32Iter = IOFiles32.begin(),
+ DepFileIter = DepFiles.begin();
setIncludePaths(Opts.mIncludePaths);
setOutputType(Opts.mOutputType);
@@ -314,18 +325,21 @@ bool SlangRS::compile(
// a single pass over the input file.
bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency);
- for (unsigned i = 0, e = IOFiles.size(); i != e; i++) {
- InputFile = IOFileIter->first;
- OutputFile = IOFileIter->second;
+ for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) {
+ InputFile = IOFile64Iter->first;
+ Output64File = IOFile64Iter->second;
+ Output32File = IOFile32Iter->second;
reset();
if (!setInputSource(InputFile))
return false;
- if (!setOutput(OutputFile))
+ if (!setOutput(Output64File))
return false;
+ setOutput32(Output32File);
+
mIsFilterscript = isFilterscript(InputFile);
if (Slang::compile() > 0)
@@ -337,7 +351,13 @@ bool SlangRS::compile(
const std::string &RealPackageName =
mRSContext->getReflectJavaPackageName();
- if (Opts.mOutputType != Slang::OT_Dependency) {
+ bool doReflection = true;
+ if (Opts.mEmit3264 && (Opts.mBitWidth == 32)) {
+ // Skip reflection on the 32-bit path if we are going to emit it on the
+ // 64-bit path.
+ doReflection = false;
+ }
+ if (Opts.mOutputType != Slang::OT_Dependency && doReflection) {
if (Opts.mBitcodeStorage == BCST_CPP_CODE) {
RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase,
@@ -407,7 +427,8 @@ bool SlangRS::compile(
if (!checkODR(InputFile))
return false;
- IOFileIter++;
+ IOFile64Iter++;
+ IOFile32Iter++;
}
return true;
diff --git a/slang_rs.h b/slang_rs.h
index e878179..3a04444 100644
--- a/slang_rs.h
+++ b/slang_rs.h
@@ -107,7 +107,8 @@ class SlangRS : public Slang {
// with the same number of pairs given in @IOFiles.
//
// @Opts - Selection of options defined from invoking llvm-rs-cc
- bool compile(const std::list<std::pair<const char*, const char*> > &IOFiles,
+ bool compile(const std::list<std::pair<const char*, const char*> > &IOFiles64,
+ const std::list<std::pair<const char*, const char*> > &IOFiles32,
const std::list<std::pair<const char*, const char*> > &DepFiles,
const RSCCOptions &Opts);
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index 42075bc..e9bb008 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -58,7 +58,8 @@ RSContext::RSContext(clang::Preprocessor &PP,
mLicenseNote(NULL),
mRSPackageName("android.renderscript"),
version(0),
- mMangleCtx(Ctx.createMangleContext()) {
+ mMangleCtx(Ctx.createMangleContext()),
+ mIs64Bit(Target.getPointerWidth(0) == 64) {
// For #pragma rs export_type
PP.AddPragmaHandler(
diff --git a/slang_rs_context.h b/slang_rs_context.h
index 3373a8b..41f5979 100644
--- a/slang_rs_context.h
+++ b/slang_rs_context.h
@@ -87,6 +87,8 @@ class RSContext {
llvm::OwningPtr<clang::MangleContext> mMangleCtx;
+ bool mIs64Bit;
+
bool processExportVar(const clang::VarDecl *VD);
bool processExportFunc(const clang::FunctionDecl *FD);
bool processExportType(const llvm::StringRef &Name);
@@ -126,6 +128,9 @@ class RSContext {
inline bool getVerbose() const {
return mVerbose;
}
+ inline bool is64Bit() const {
+ return mIs64Bit;
+ }
inline void setLicenseNote(const std::string &S) {
mLicenseNote = new std::string(S);
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index 3c96a51..28a17c8 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -69,7 +69,8 @@ static RSReflectionType gReflectionTypes[] = {
{MatrixDataType, "MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false},
{MatrixDataType, "MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false},
- // TODO: For 64 bit, what will be the size of the objects??
+ // RS object types are 32 bits in 32-bit RS, but 256 bits in 64-bit RS.
+ // This is handled specially by the GetSizeInBits() method.
{ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false},
{ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false},
{ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false},
@@ -1021,6 +1022,10 @@ size_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) {
int type = EPT->getType();
slangAssert((type > DataTypeUnknown && type < DataTypeMax) &&
"RSExportPrimitiveType::GetSizeInBits : unknown data type");
+ // All RS object types are 256 bits in 64-bit RS.
+ if (EPT->isRSObjectType() && EPT->getRSContext()->is64Bit()) {
+ return 256;
+ }
return gReflectionTypes[type].size_in_bits;
}
@@ -1096,8 +1101,15 @@ llvm::Type *RSExportPrimitiveType::convertToLLVMType() const {
//
if (RSObjectLLVMType == NULL) {
std::vector<llvm::Type *> Elements;
- Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1));
- RSObjectLLVMType = llvm::StructType::get(C, Elements, true);
+ if (getRSContext()->is64Bit()) {
+ // 64-bit path
+ Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt64Ty(C), 4));
+ RSObjectLLVMType = llvm::StructType::get(C, Elements, true);
+ } else {
+ // 32-bit legacy path
+ Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1));
+ RSObjectLLVMType = llvm::StructType::get(C, Elements, true);
+ }
}
return RSObjectLLVMType;
}
diff --git a/slang_rs_object_ref_count.cpp b/slang_rs_object_ref_count.cpp
index 8f1e507..f0ac22d 100644
--- a/slang_rs_object_ref_count.cpp
+++ b/slang_rs_object_ref_count.cpp
@@ -1100,7 +1100,7 @@ void RSObjectRefCount::Scope::ReplaceRSObjectAssignment(
clang::QualType QT = AS->getType();
clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
- DataTypeRSFont)->getASTContext();
+ DataTypeRSAllocation)->getASTContext();
clang::SourceLocation Loc = AS->getExprLoc();
clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc();
@@ -1131,11 +1131,11 @@ void RSObjectRefCount::Scope::AppendRSObjectInit(
}
clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
- DataTypeRSFont)->getASTContext();
+ DataTypeRSAllocation)->getASTContext();
clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD(
- DataTypeRSFont)->getLocation();
+ DataTypeRSAllocation)->getLocation();
clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD(
- DataTypeRSFont)->getInnerLocStart();
+ DataTypeRSAllocation)->getInnerLocStart();
if (DT == DataTypeIsStruct) {
const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
diff --git a/slang_rs_reflect_utils.cpp b/slang_rs_reflect_utils.cpp
index c841d52..80b8452 100644
--- a/slang_rs_reflect_utils.cpp
+++ b/slang_rs_reflect_utils.cpp
@@ -116,21 +116,23 @@ std::string RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
static bool GenerateAccessorMethod(
const RSSlangReflectUtils::BitCodeAccessorContext &context,
- GeneratedFile &out) {
+ int bitwidth, GeneratedFile &out) {
// the prototype of the accessor method
- out.indent() << "// return byte array representation of the bitcode.\n";
- out.indent() << "public static byte[] getBitCode32()";
+ out.indent() << "// return byte array representation of the " << bitwidth
+ << "-bit bitcode.\n";
+ out.indent() << "public static byte[] getBitCode" << bitwidth << "()";
out.startBlock();
- out.indent() << "return getBitCode32Internal();\n";
+ out.indent() << "return getBitCode" << bitwidth << "Internal();\n";
out.endBlock(true);
return true;
}
// Java method size must not exceed 64k,
// so we have to split the bitcode into multiple segments.
-static bool GenerateSegmentMethod(const char *buff, int blen, int seg_num,
- GeneratedFile &out) {
- out.indent() << "private static byte[] getSegment32_" << seg_num << "()";
+static bool GenerateSegmentMethod(const char *buff, int blen, int bitwidth,
+ int seg_num, GeneratedFile &out) {
+ out.indent() << "private static byte[] getSegment" << bitwidth << "_"
+ << seg_num << "()";
out.startBlock();
out.indent() << "byte[] data = {";
out.increaseIndent();
@@ -157,17 +159,23 @@ static bool GenerateSegmentMethod(const char *buff, int blen, int seg_num,
return true;
}
-static bool GenerateJavaCodeAccessorMethod(
+static bool GenerateJavaCodeAccessorMethodForBitwidth(
const RSSlangReflectUtils::BitCodeAccessorContext &context,
- GeneratedFile &out) {
- FILE *pfin = fopen(context.bcFileName, "rb");
+ int bitwidth, GeneratedFile &out) {
+
+ std::string filename(context.bc32FileName);
+ if (bitwidth == 64) {
+ filename = context.bc64FileName;
+ }
+
+ FILE *pfin = fopen(filename.c_str(), "rb");
if (pfin == NULL) {
- fprintf(stderr, "Error: could not read file %s\n", context.bcFileName);
+ fprintf(stderr, "Error: could not read file %s\n", filename.c_str());
return false;
}
// start the accessor method
- GenerateAccessorMethod(context, out);
+ GenerateAccessorMethod(context, bitwidth, out);
// output the data
// make sure the generated function for a segment won't break the Javac
@@ -178,7 +186,7 @@ static bool GenerateJavaCodeAccessorMethod(
int seg_num = 0;
int total_length = 0;
while ((read_length = fread(buff, 1, SEG_SIZE, pfin)) > 0) {
- GenerateSegmentMethod(buff, read_length, seg_num, out);
+ GenerateSegmentMethod(buff, read_length, bitwidth, seg_num, out);
++seg_num;
total_length += read_length;
}
@@ -186,15 +194,16 @@ static bool GenerateJavaCodeAccessorMethod(
fclose(pfin);
// output the internal accessor method
- out.indent() << "private static int bitCodeLength = " << total_length
- << ";\n\n";
- out.indent() << "private static byte[] getBitCode32Internal()";
+ out.indent() << "private static int bitCode" << bitwidth << "Length = "
+ << total_length << ";\n\n";
+ out.indent() << "private static byte[] getBitCode" << bitwidth
+ << "Internal()";
out.startBlock();
- out.indent() << "byte[] bc = new byte[bitCodeLength];\n";
+ out.indent() << "byte[] bc = new byte[bitCode" << bitwidth << "Length];\n";
out.indent() << "int offset = 0;\n";
out.indent() << "byte[] seg;\n";
for (int i = 0; i < seg_num; ++i) {
- out.indent() << "seg = getSegment32_" << i << "();\n";
+ out.indent() << "seg = getSegment" << bitwidth << "_" << i << "();\n";
out.indent() << "System.arraycopy(seg, 0, bc, offset, seg.length);\n";
out.indent() << "offset += seg.length;\n";
}
@@ -204,6 +213,21 @@ static bool GenerateJavaCodeAccessorMethod(
return true;
}
+static bool GenerateJavaCodeAccessorMethod(
+ const RSSlangReflectUtils::BitCodeAccessorContext &context,
+ GeneratedFile &out) {
+ if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 32, out)) {
+ slangAssert(false && "Couldn't generate 32-bit embedded bitcode!");
+ return false;
+ }
+ if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 64, out)) {
+ slangAssert(false && "Couldn't generate 64-bit embedded bitcode!");
+ return false;
+ }
+
+ return true;
+}
+
static bool GenerateAccessorClass(
const RSSlangReflectUtils::BitCodeAccessorContext &context,
const char *clazz_name, GeneratedFile &out) {
diff --git a/slang_rs_reflect_utils.h b/slang_rs_reflect_utils.h
index 28c46b9..8667c64 100644
--- a/slang_rs_reflect_utils.h
+++ b/slang_rs_reflect_utils.h
@@ -29,7 +29,8 @@ class RSSlangReflectUtils {
public:
// Encode a binary bitcode file into a Java source file.
// rsFileName: the original .rs file name (with or without path).
- // bcFileName: where is the bit code file
+ // bc32FileName: path of the 32-bit bitcode file
+ // bc64FileName: path of the 64-bit bitcode file
// reflectPath: where to output the generated Java file, no package name in
// it.
// packageName: the package of the output Java file.
@@ -37,7 +38,8 @@ public:
// bcStorage: where to emit bitcode to (resource file or embedded).
struct BitCodeAccessorContext {
const char *rsFileName;
- const char *bcFileName;
+ const char *bc32FileName;
+ const char *bc64FileName;
const char *reflectPath;
const char *packageName;
const std::string *licenseNote;
diff --git a/slang_rs_reflection.cpp b/slang_rs_reflection.cpp
index dcf8422..9f5ccd0 100644
--- a/slang_rs_reflection.cpp
+++ b/slang_rs_reflection.cpp
@@ -366,9 +366,7 @@ void RSReflectionJava::genScriptClassConstructor() {
mOut.indent() << "super(rs,\n";
mOut.indent() << " " << RS_RESOURCE_NAME ",\n";
mOut.indent() << " " << className << ".getBitCode32(),\n";
- // TODO(srhines): Replace the extra BitCode32 with Bitcode64 here!
- // mOut.indent() << " " << className << ".getBitCode64());\n";
- mOut.indent() << " " << className << ".getBitCode32());\n";
+ mOut.indent() << " " << className << ".getBitCode64());\n";
} else {
// Call alternate constructor with required parameters.
// Look up the proper raw bitcode resource id via the context.
diff --git a/tests/P_v64/stderr.txt.expect b/tests/P_v64/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_v64/stderr.txt.expect
diff --git a/tests/P_v64/stdout.txt.expect b/tests/P_v64/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_v64/stdout.txt.expect
diff --git a/tests/P_v64/v64.rs b/tests/P_v64/v64.rs
new file mode 100644
index 0000000..cfa3b7e
--- /dev/null
+++ b/tests/P_v64/v64.rs
@@ -0,0 +1,23 @@
+// -emit_32_64
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL root(uint32_t ain) {
+ return 0;
+}
+
+void RS_KERNEL in_only(uint32_t ain) {
+}
+
+int RS_KERNEL out_only() {
+ return 0;
+}
+
+int RS_KERNEL everything(uint32_t ain, uint32_t x, uint32_t y) {
+ return 0;
+}
+
+/*int v;
+void test_invoke(rs_allocation a, int i) {
+ v = rsGetElementAt_int(a, i);
+}*/