Add RSGlobalInfoPass information to RS driver. Bug: 20306487 This change enables vendor drivers to configure support for including additional information about global variables in the emitted CPU code. This information includes the number of total global variables, the names of these variables, the addresses of these variables and the sizes of these variables. The driver can also select whether the information includes constant (immutable) globals or not. The reference driver defaults to embedding information about each of the existing, non-constant global variables. Change-Id: I1e55fc3f08e518f04eeee3e4f9dc7b6ea3b80d7c
diff --git a/cpu_ref/rsCpuCore.cpp b/cpu_ref/rsCpuCore.cpp index e2d3bf1..3ce9d9d 100644 --- a/cpu_ref/rsCpuCore.cpp +++ b/cpu_ref/rsCpuCore.cpp
@@ -115,6 +115,8 @@ mLinkRuntimeCallback = nullptr; mSelectRTCallback = nullptr; mSetupCompilerCallback = nullptr; + mEmbedGlobalInfo = true; + mEmbedGlobalInfoSkipConstant = true; }
diff --git a/cpu_ref/rsCpuCore.h b/cpu_ref/rsCpuCore.h index afe8ef5..843fa54 100644 --- a/cpu_ref/rsCpuCore.h +++ b/cpu_ref/rsCpuCore.h
@@ -135,6 +135,28 @@ } virtual bool getInForEach() { return mInForEach; } + // Set to true if we should embed global variable information in the code. + virtual void setEmbedGlobalInfo(bool v) { + mEmbedGlobalInfo = v; + } + + // Returns true if we should embed global variable information in the code. + virtual bool getEmbedGlobalInfo() const { + return mEmbedGlobalInfo; + } + + // Set to true if we should skip constant (immutable) global variables when + // potentially embedding information about globals. + virtual void setEmbedGlobalInfoSkipConstant(bool v) { + mEmbedGlobalInfoSkipConstant = v; + } + + // Returns true if we should skip constant (immutable) global variables when + // potentially embedding information about globals. + virtual bool getEmbedGlobalInfoSkipConstant() const { + return mEmbedGlobalInfoSkipConstant; + } + protected: Context *mRSC; uint32_t version_major; @@ -164,6 +186,16 @@ RSSelectRTCallback mSelectRTCallback; RSSetupCompilerCallback mSetupCompilerCallback; String8 mBccPluginName; + + // Specifies whether we should embed global variable information in the + // code via special RS variables that can be examined later by the driver. + // Defaults to true. + bool mEmbedGlobalInfo; + + // Specifies whether we should skip constant (immutable) global variables + // when potentially embedding information about globals. + // Defaults to true. + bool mEmbedGlobalInfoSkipConstant; };
diff --git a/cpu_ref/rsCpuExecutable.cpp b/cpu_ref/rsCpuExecutable.cpp index 1553da2..584aa84 100644 --- a/cpu_ref/rsCpuExecutable.cpp +++ b/cpu_ref/rsCpuExecutable.cpp
@@ -303,6 +303,11 @@ uint32_t checksum = 0; const char *rsInfo = (const char *) dlsym(sharedObj, ".rs.info"); + int numEntries = 0; + const int *rsGlobalEntries = (const int *) dlsym(sharedObj, ".rs.global_entries"); + const char **rsGlobalNames = (const char **) dlsym(sharedObj, ".rs.global_names"); + const void **rsGlobalAddresses = (const void **) dlsym(sharedObj, ".rs.global_addresses"); + const size_t *rsGlobalSizes = (const size_t *) dlsym(sharedObj, ".rs.global_sizes"); if (strgets(line, MAXLINE, &rsInfo) == nullptr) { return nullptr; @@ -537,11 +542,25 @@ #endif // RS_COMPATIBILITY_LIB + // Read in information about mutable global variables provided by bcc's + // RSGlobalInfoPass + if (rsGlobalEntries) { + numEntries = *rsGlobalEntries; + if (numEntries > 0) { + rsAssert(rsGlobalNames); + rsAssert(rsGlobalAddresses); + rsAssert(rsGlobalSizes); + } + } else { + ALOGD("Missing .rs.global_entries from shared object"); + } + return new ScriptExecutable( RSContext, fieldAddress, fieldIsObject, fieldName, varCount, invokeFunctions, funcCount, forEachFunctions, forEachSignatures, forEachCount, pragmaKeys, pragmaValues, pragmaCount, + rsGlobalNames, rsGlobalAddresses, rsGlobalSizes, numEntries, isThreadable, checksum); error: @@ -582,5 +601,14 @@ return nullptr; } +bool ScriptExecutable::dumpGlobalInfo() const { + ALOGE("Globals: %p %p %p", mGlobalAddresses, mGlobalSizes, mGlobalNames); + for (int i = 0; i < mGlobalEntries; i++) { + ALOGE("Global[%d]: %p %zu %s", i, mGlobalAddresses[i], mGlobalSizes[i], + mGlobalNames[i]); + } + return true; +} + } // namespace renderscript } // namespace android
diff --git a/cpu_ref/rsCpuExecutable.h b/cpu_ref/rsCpuExecutable.h index 785f53d..6c81a47 100644 --- a/cpu_ref/rsCpuExecutable.h +++ b/cpu_ref/rsCpuExecutable.h
@@ -64,6 +64,8 @@ size_t forEachCount, const char** pragmaKeys, const char** pragmaValues, size_t pragmaCount, + const char **globalNames, const void **globalAddresses, + const size_t *globalSizes, size_t globalEntries, bool isThreadable, uint32_t buildChecksum) : mFieldAddress(fieldAddress), mFieldIsObject(fieldIsObject), mFieldName(fieldName), mExportedVarCount(varCount), @@ -71,7 +73,9 @@ mForEachFunctions(forEachFunctions), mForEachSignatures(forEachSignatures), mForEachCount(forEachCount), mPragmaKeys(pragmaKeys), mPragmaValues(pragmaValues), - mPragmaCount(pragmaCount), mIsThreadable(isThreadable), + mPragmaCount(pragmaCount), mGlobalNames(globalNames), + mGlobalAddresses(globalAddresses), mGlobalSizes(globalSizes), + mGlobalEntries(globalEntries), mIsThreadable(isThreadable), mBuildChecksum(buildChecksum), mRS(RSContext) { } @@ -132,10 +136,35 @@ const char ** getPragmaKeys() const { return mPragmaKeys; } const char ** getPragmaValues() const { return mPragmaValues; } + const char* getGlobalName(int i) const { + if (i < mGlobalEntries) { + return mGlobalNames[i]; + } else { + return nullptr; + } + } + const void* getGlobalAddress(int i) const { + if (i < mGlobalEntries) { + return mGlobalAddresses[i]; + } else { + return nullptr; + } + } + size_t getGlobalSize(int i) const { + if (i < mGlobalEntries) { + return mGlobalSizes[i]; + } else { + return 0; + } + } + int getGlobalEntries() const { return mGlobalEntries; } + bool getThreadable() const { return mIsThreadable; } uint32_t getBuildChecksum() const { return mBuildChecksum; } + bool dumpGlobalInfo() const; + private: void** mFieldAddress; bool* mFieldIsObject; @@ -153,6 +182,11 @@ const char ** mPragmaValues; size_t mPragmaCount; + const char ** mGlobalNames; + const void ** mGlobalAddresses; + const size_t * mGlobalSizes; + int mGlobalEntries; + bool mIsThreadable; uint32_t mBuildChecksum;
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp index 3f64534..7e024bc 100644 --- a/cpu_ref/rsCpuScript.cpp +++ b/cpu_ref/rsCpuScript.cpp
@@ -55,6 +55,9 @@ #endif namespace { + +static const bool kDebugGlobalVariables = false; + #ifndef RS_COMPATIBILITY_LIB static bool is_force_recompile() { @@ -83,11 +86,18 @@ const std::string& bcFileName, const char* cacheDir, const char* resName, const char* core_lib, bool useRSDebugContext, - const char* bccPluginName) { + const char* bccPluginName, bool emitGlobalInfo, + bool emitGlobalInfoSkipConstant) { rsAssert(cacheDir && resName && core_lib); args->push_back(android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH); args->push_back("-unroll-runtime"); args->push_back("-scalarize-load-store"); + if (emitGlobalInfo) { + args->push_back("-rs-global-info"); + if (emitGlobalInfoSkipConstant) { + args->push_back("-rs-global-info-skip-constant"); + } + } args->push_back("-o"); args->push_back(resName); args->push_back("-output_path"); @@ -276,6 +286,10 @@ mIsThreadable = mScriptExec->getThreadable(); //ALOGE("Script isThreadable? %d", mIsThreadable); + if (kDebugGlobalVariables) { + mScriptExec->dumpGlobalInfo(); + } + return true; } @@ -326,8 +340,11 @@ bcFileName.append(".bc"); std::vector<const char*> compileArguments; + bool emitGlobalInfo = mCtx->getEmbedGlobalInfo(); + bool emitGlobalInfoSkipConstant = mCtx->getEmbedGlobalInfoSkipConstant(); setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib, - useRSDebugContext, bccPluginName); + useRSDebugContext, bccPluginName, emitGlobalInfo, + emitGlobalInfoSkipConstant); mChecksumNeeded = isChecksumNeeded(); if (mChecksumNeeded) { @@ -888,6 +905,22 @@ return nullptr; } +int RsdCpuScriptImpl::getGlobalEntries() const { + return mScriptExec->getGlobalEntries(); +} + +const char * RsdCpuScriptImpl::getGlobalName(int i) const { + return mScriptExec->getGlobalName(i); +} + +const void * RsdCpuScriptImpl::getGlobalAddress(int i) const { + return mScriptExec->getGlobalAddress(i); +} + +size_t RsdCpuScriptImpl::getGlobalSize(int i) const { + return mScriptExec->getGlobalSize(i); +} + void RsdCpuScriptImpl::preLaunch(uint32_t slot, const Allocation ** ains, uint32_t inLen, Allocation * aout, const void * usr, uint32_t usrLen,
diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h index 22f973b..5ee3749 100644 --- a/cpu_ref/rsCpuScript.h +++ b/cpu_ref/rsCpuScript.h
@@ -107,6 +107,11 @@ virtual Allocation * getAllocationForPointer(const void *ptr) const; bool storeRSInfoFromSO(); + int getGlobalEntries() const override; + const char * getGlobalName(int i) const override; + const void * getGlobalAddress(int i) const override; + size_t getGlobalSize(int i) const override; + protected: RsdCpuReferenceImpl *mCtx; const Script *mScript;
diff --git a/cpu_ref/rsd_cpu.h b/cpu_ref/rsd_cpu.h index c53e880..8452828 100644 --- a/cpu_ref/rsd_cpu.h +++ b/cpu_ref/rsd_cpu.h
@@ -87,6 +87,17 @@ virtual void setGlobalObj(uint32_t slot, ObjectBase *obj) = 0; virtual Allocation * getAllocationForPointer(const void *ptr) const = 0; + + // Returns number of global variables in this Script (may be 0 if + // compiler is not configured to emit this information). + virtual int getGlobalEntries() const = 0; + // Returns the name of the global variable at index i. + virtual const char * getGlobalName(int i) const = 0; + // Returns the CPU address of the global variable at index i. + virtual const void * getGlobalAddress(int i) const = 0; + // Returns the size (in bytes) of the global variable at index i. + virtual size_t getGlobalSize(int i) const = 0; + virtual ~CpuScript() {} }; typedef CpuScript * (* script_lookup_t)(Context *, const Script *s);