diff options
author | Stephen Hines <srhines@google.com> | 2014-06-10 23:53:00 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-07-09 00:59:39 -0700 |
commit | 9ae18b2bbee0b08afd400542e863dd665ff76059 (patch) | |
tree | 979861baa5023caa4f4a2335dd307526634f0581 | |
parent | afa84a9112db3b135f88d736b4c8249a049eb40a (diff) | |
download | android_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.td | 3 | ||||
-rw-r--r-- | llvm-rs-cc.cpp | 130 | ||||
-rw-r--r-- | rs_cc_options.cpp | 6 | ||||
-rw-r--r-- | rs_cc_options.h | 20 | ||||
-rw-r--r-- | slang.cpp | 40 | ||||
-rw-r--r-- | slang.h | 18 | ||||
-rw-r--r-- | slang_rs.cpp | 45 | ||||
-rw-r--r-- | slang_rs.h | 3 | ||||
-rw-r--r-- | slang_rs_context.cpp | 3 | ||||
-rw-r--r-- | slang_rs_context.h | 5 | ||||
-rw-r--r-- | slang_rs_export_type.cpp | 18 | ||||
-rw-r--r-- | slang_rs_object_ref_count.cpp | 8 | ||||
-rw-r--r-- | slang_rs_reflect_utils.cpp | 60 | ||||
-rw-r--r-- | slang_rs_reflect_utils.h | 6 | ||||
-rw-r--r-- | slang_rs_reflection.cpp | 4 | ||||
-rw-r--r-- | tests/P_v64/stderr.txt.expect | 0 | ||||
-rw-r--r-- | tests/P_v64/stdout.txt.expect | 0 | ||||
-rw-r--r-- | tests/P_v64/v64.rs | 23 |
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; } }; @@ -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 @@ -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; @@ -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); +}*/ |