Switch libbcc to start using MetadataExtractor.
BUG=6051742
This reduces code duplication, and makes us a client of our own helper library.
It also helps to fix a potential issue that can come up with older bitcode
containing only ForEach signatures and not names (something that was fixed in
MetadataExtractor, but not libbcc). We no longer look at metadata nodes at all
from libbcc.
Change-Id: I5cdacec82e4cd164f1aec5aa28a5e82feb9cfc15
diff --git a/Android.mk b/Android.mk
index 079e73a..e3948c8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -148,7 +148,7 @@
libLLVMCore \
libLLVMSupport
-LOCAL_SHARED_LIBRARIES := libdl libcutils libutils libstlport
+LOCAL_SHARED_LIBRARIES := libbcinfo libdl libcutils libutils libstlport
# Modules that need get installed if and only if the target libbcc.so is
# installed.
@@ -245,6 +245,8 @@
libcutils \
libutils
+LOCAL_SHARED_LIBRARIES := libbcinfo
+
LOCAL_LDLIBS := -ldl -lpthread
# Generate build stamp (Build time + Build git revision + Build Semi SHA1)
diff --git a/bcinfo/MetadataExtractor.cpp b/bcinfo/MetadataExtractor.cpp
index 5927f22..91458e4 100644
--- a/bcinfo/MetadataExtractor.cpp
+++ b/bcinfo/MetadataExtractor.cpp
@@ -61,8 +61,19 @@
MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
- : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mExportVarCount(0),
+ : mModule(NULL), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
+ mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
+ mExportVarNameList(NULL), mExportFuncNameList(NULL),
+ mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
+ mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
+ mObjectSlotCount(0), mObjectSlotList(NULL), mOptimizationLevel(3) {
+}
+
+
+MetadataExtractor::MetadataExtractor(const llvm::Module *module)
+ : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0),
mExportFuncCount(0), mExportForEachSignatureCount(0),
+ mExportVarNameList(NULL), mExportFuncNameList(NULL),
mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
mObjectSlotCount(0), mObjectSlotList(NULL), mOptimizationLevel(3) {
@@ -70,6 +81,24 @@
MetadataExtractor::~MetadataExtractor() {
+ if (mExportVarNameList) {
+ for (size_t i = 0; i < mExportVarCount; i++) {
+ delete [] mExportVarNameList[i];
+ mExportVarNameList[i] = NULL;
+ }
+ }
+ delete [] mExportVarNameList;
+ mExportVarNameList = NULL;
+
+ if (mExportFuncNameList) {
+ for (size_t i = 0; i < mExportFuncCount; i++) {
+ delete [] mExportFuncNameList[i];
+ mExportFuncNameList[i] = NULL;
+ }
+ }
+ delete [] mExportFuncNameList;
+ mExportFuncNameList = NULL;
+
if (mExportForEachNameList) {
for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
delete [] mExportForEachNameList[i];
@@ -168,23 +197,78 @@
return;
}
- mPragmaKeyList = new const char*[mPragmaCount];
- mPragmaValueList = new const char*[mPragmaCount];
+ const char **TmpKeyList = new const char*[mPragmaCount];
+ const char **TmpValueList = new const char*[mPragmaCount];
for (size_t i = 0; i < mPragmaCount; i++) {
llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
if (Pragma != NULL && Pragma->getNumOperands() == 2) {
llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
- mPragmaKeyList[i] = createStringFromValue(PragmaKeyMDS);
+ TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
- mPragmaValueList[i] = createStringFromValue(PragmaValueMDS);
+ TmpValueList[i] = createStringFromValue(PragmaValueMDS);
}
}
+ mPragmaKeyList = TmpKeyList;
+ mPragmaValueList = TmpValueList;
+
return;
}
+bool MetadataExtractor::populateVarNameMetadata(
+ const llvm::NamedMDNode *VarNameMetadata) {
+ if (!VarNameMetadata) {
+ return true;
+ }
+
+ mExportVarCount = VarNameMetadata->getNumOperands();
+ if (!mExportVarCount) {
+ return true;
+ }
+
+ const char **TmpNameList = new const char *[mExportVarCount];
+
+ for (size_t i = 0; i < mExportVarCount; i++) {
+ llvm::MDNode *Name = VarNameMetadata->getOperand(i);
+ if (Name != NULL && Name->getNumOperands() > 1) {
+ TmpNameList[i] = createStringFromValue(Name->getOperand(0));
+ }
+ }
+
+ mExportVarNameList = TmpNameList;
+
+ return true;
+}
+
+
+bool MetadataExtractor::populateFuncNameMetadata(
+ const llvm::NamedMDNode *FuncNameMetadata) {
+ if (!FuncNameMetadata) {
+ return true;
+ }
+
+ mExportFuncCount = FuncNameMetadata->getNumOperands();
+ if (!mExportFuncCount) {
+ return true;
+ }
+
+ const char **TmpNameList = new const char*[mExportFuncCount];
+
+ for (size_t i = 0; i < mExportFuncCount; i++) {
+ llvm::MDNode *Name = FuncNameMetadata->getOperand(i);
+ if (Name != NULL && Name->getNumOperands() == 1) {
+ TmpNameList[i] = createStringFromValue(Name->getOperand(0));
+ }
+ }
+
+ mExportFuncNameList = TmpNameList;
+
+ return true;
+}
+
+
bool MetadataExtractor::populateForEachMetadata(
const llvm::NamedMDNode *Names,
const llvm::NamedMDNode *Signatures) {
@@ -199,6 +283,7 @@
uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
TmpSigList[0] = 0x1f;
+
mExportForEachNameList = (const char**)TmpNameList;
mExportForEachSignatureList = TmpSigList;
return true;
@@ -210,6 +295,7 @@
}
uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
+ const char **TmpNameList = new const char*[mExportForEachSignatureCount];
for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
llvm::MDNode *SigNode = Signatures->getOperand(i);
@@ -228,65 +314,68 @@
}
}
- mExportForEachSignatureList = TmpSigList;
-
-
- mExportForEachNameList = new const char*[mExportForEachSignatureCount];
-
for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
llvm::MDNode *Name = Names->getOperand(i);
if (Name != NULL && Name->getNumOperands() == 1) {
- mExportForEachNameList[i] = createStringFromValue(Name->getOperand(0));
+ TmpNameList[i] = createStringFromValue(Name->getOperand(0));
}
}
+ mExportForEachNameList = TmpNameList;
+ mExportForEachSignatureList = TmpSigList;
+
return true;
}
-
bool MetadataExtractor::extract() {
- if (!mBitcode || !mBitcodeSize) {
- ALOGE("Invalid/empty bitcode");
+ if (!(mBitcode && mBitcodeSize) && !mModule) {
+ ALOGE("Invalid/empty bitcode/module");
return false;
}
- llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
- llvm::OwningPtr<llvm::MemoryBuffer> MEM(
- llvm::MemoryBuffer::getMemBuffer(
- llvm::StringRef(mBitcode, mBitcodeSize)));
- std::string error;
+ llvm::OwningPtr<llvm::LLVMContext> mContext;
- // Module ownership is handled by the context, so we don't need to free it.
- llvm::Module *module = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
- if (!module) {
- ALOGE("Could not parse bitcode file");
- ALOGE("%s", error.c_str());
- return false;
+ if (!mModule) {
+ mContext.reset(new llvm::LLVMContext());
+ llvm::OwningPtr<llvm::MemoryBuffer> MEM(
+ llvm::MemoryBuffer::getMemBuffer(
+ llvm::StringRef(mBitcode, mBitcodeSize)));
+ std::string error;
+
+ // Module ownership is handled by the context, so we don't need to free it.
+ mModule = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
+ if (!mModule) {
+ ALOGE("Could not parse bitcode file");
+ ALOGE("%s", error.c_str());
+ return false;
+ }
}
const llvm::NamedMDNode *ExportVarMetadata =
- module->getNamedMetadata(ExportVarMetadataName);
+ mModule->getNamedMetadata(ExportVarMetadataName);
const llvm::NamedMDNode *ExportFuncMetadata =
- module->getNamedMetadata(ExportFuncMetadataName);
+ mModule->getNamedMetadata(ExportFuncMetadataName);
const llvm::NamedMDNode *ExportForEachNameMetadata =
- module->getNamedMetadata(ExportForEachNameMetadataName);
+ mModule->getNamedMetadata(ExportForEachNameMetadataName);
const llvm::NamedMDNode *ExportForEachMetadata =
- module->getNamedMetadata(ExportForEachMetadataName);
+ mModule->getNamedMetadata(ExportForEachMetadataName);
const llvm::NamedMDNode *PragmaMetadata =
- module->getNamedMetadata(PragmaMetadataName);
+ mModule->getNamedMetadata(PragmaMetadataName);
const llvm::NamedMDNode *ObjectSlotMetadata =
- module->getNamedMetadata(ObjectSlotMetadataName);
+ mModule->getNamedMetadata(ObjectSlotMetadataName);
const llvm::NamedMDNode *OptimizationLevelMetadata =
- module->getNamedMetadata(OptimizationLevelMetadataName);
+ mModule->getNamedMetadata(OptimizationLevelMetadataName);
- if (ExportVarMetadata) {
- mExportVarCount = ExportVarMetadata->getNumOperands();
+ if (!populateVarNameMetadata(ExportVarMetadata)) {
+ ALOGE("Could not populate export variable metadata");
+ return false;
}
- if (ExportFuncMetadata) {
- mExportFuncCount = ExportFuncMetadata->getNumOperands();
+ if (!populateFuncNameMetadata(ExportFuncMetadata)) {
+ ALOGE("Could not populate export function metadata");
+ return false;
}
if (!populateForEachMetadata(ExportForEachNameMetadata,
diff --git a/bcinfo/tools/main.cpp b/bcinfo/tools/main.cpp
index daeea7d..6ecded0 100644
--- a/bcinfo/tools/main.cpp
+++ b/bcinfo/tools/main.cpp
@@ -82,7 +82,18 @@
}
printf("exportVarCount: %u\n", ME->getExportVarCount());
+ const char **varNameList = ME->getExportVarNameList();
+ for (size_t i = 0; i < ME->getExportVarCount(); i++) {
+ printf("var[%u]: %s\n", i, varNameList[i]);
+ }
+ printf("\n");
+
printf("exportFuncCount: %u\n", ME->getExportFuncCount());
+ const char **funcNameList = ME->getExportFuncNameList();
+ for (size_t i = 0; i < ME->getExportFuncCount(); i++) {
+ printf("func[%u]: %s\n", i, funcNameList[i]);
+ }
+ printf("\n");
printf("exportForEachSignatureCount: %u\n",
ME->getExportForEachSignatureCount());
@@ -92,6 +103,7 @@
printf("exportForEachSignatureList[%u]: %s - %u\n", i, nameList[i],
sigList[i]);
}
+ printf("\n");
printf("pragmaCount: %u\n", ME->getPragmaCount());
const char **keyList = ME->getPragmaKeyList();
@@ -99,12 +111,14 @@
for (size_t i = 0; i < ME->getPragmaCount(); i++) {
printf("pragma[%u]: %s - %s\n", i, keyList[i], valueList[i]);
}
+ printf("\n");
printf("objectSlotCount: %u\n", ME->getObjectSlotCount());
const uint32_t *slotList = ME->getObjectSlotList();
for (size_t i = 0; i < ME->getObjectSlotCount(); i++) {
printf("objectSlotList[%u]: %u\n", i, slotList[i]);
}
+ printf("\n");
printf("optimizationLevel: %u\n", ME->getOptimizationLevel());
diff --git a/include/bcinfo/MetadataExtractor.h b/include/bcinfo/MetadataExtractor.h
index c2b7921..29ca961 100644
--- a/include/bcinfo/MetadataExtractor.h
+++ b/include/bcinfo/MetadataExtractor.h
@@ -21,6 +21,7 @@
#include <stdint.h>
namespace llvm {
+ class Module;
class NamedMDNode;
}
@@ -28,12 +29,15 @@
class MetadataExtractor {
private:
+ const llvm::Module *mModule;
const char *mBitcode;
size_t mBitcodeSize;
size_t mExportVarCount;
size_t mExportFuncCount;
size_t mExportForEachSignatureCount;
+ const char **mExportVarNameList;
+ const char **mExportFuncNameList;
const char **mExportForEachNameList;
const uint32_t *mExportForEachSignatureList;
@@ -47,6 +51,8 @@
uint32_t mOptimizationLevel;
// Helper functions for extraction
+ bool populateVarNameMetadata(const llvm::NamedMDNode *VarNameMetadata);
+ bool populateFuncNameMetadata(const llvm::NamedMDNode *FuncNameMetadata);
bool populateForEachMetadata(const llvm::NamedMDNode *Names,
const llvm::NamedMDNode *Signatures);
bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
@@ -61,6 +67,13 @@
*/
MetadataExtractor(const char *bitcode, size_t bitcodeSize);
+ /**
+ * Reads metadata from \p module.
+ *
+ * \param module - input module.
+ */
+ MetadataExtractor(const llvm::Module *module);
+
~MetadataExtractor();
/**
@@ -78,6 +91,13 @@
}
/**
+ * \return array of exported variable names.
+ */
+ const char **getExportVarNameList() const {
+ return mExportVarNameList;
+ }
+
+ /**
* \return number of exported global functions (slots) in this script/module.
*/
size_t getExportFuncCount() const {
@@ -85,6 +105,13 @@
}
/**
+ * \return array of exported function names.
+ */
+ const char **getExportFuncNameList() const {
+ return mExportFuncNameList;
+ }
+
+ /**
* \return number of exported ForEach functions in this script/module.
*/
size_t getExportForEachSignatureCount() const {
@@ -92,14 +119,14 @@
}
/**
- * \return array of ForEach function signatures.
+ * \return array of exported ForEach function signatures.
*/
const uint32_t *getExportForEachSignatureList() const {
return mExportForEachSignatureList;
}
/**
- * \return array of ForEach function names.
+ * \return array of exported ForEach function names.
*/
const char **getExportForEachNameList() const {
return mExportForEachNameList;
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index cc66435..2e2a4fa 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -72,6 +72,7 @@
LOCAL_C_INCLUDES := $(libbcc_C_INCLUDES)
LOCAL_SRC_FILES := $(libbcc_executionengine_SRC_FILES)
+LOCAL_SHARED_LIBRARIES := libbcinfo
include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
@@ -95,6 +96,7 @@
LOCAL_C_INCLUDES := $(libbcc_C_INCLUDES)
LOCAL_SRC_FILES := $(libbcc_executionengine_SRC_FILES)
+LOCAL_SHARED_LIBRARIES := libbcinfo
include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index ebdfb0f..e7bdd52 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -17,6 +17,7 @@
#include "Compiler.h"
#include "Config.h"
+#include <bcinfo/MetadataExtractor.h>
#if USE_OLD_JIT
#include "OldJIT/ContextManager.h"
@@ -66,7 +67,6 @@
#include "llvm/GlobalValue.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Type.h"
@@ -119,37 +119,6 @@
std::vector<std::string> Compiler::Features;
-// Name of metadata node where pragma info resides (should be synced with
-// slang.cpp)
-const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
-
-// Name of metadata node where exported variable names reside (should be
-// synced with slang_rs_metadata.h)
-const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
-
-// Name of metadata node where exported function names reside (should be
-// synced with slang_rs_metadata.h)
-const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
-
-// Name of metadata node where exported ForEach name information resides
-// (should be synced with slang_rs_metadata.h)
-const llvm::StringRef Compiler::ExportForEachNameMetadataName =
- "#rs_export_foreach_name";
-
-// Name of metadata node where exported ForEach signature information resides
-// (should be synced with slang_rs_metadata.h)
-const llvm::StringRef Compiler::ExportForEachMetadataName =
- "#rs_export_foreach";
-
-// Name of metadata node where RS object slot info resides (should be
-// synced with slang_rs_metadata.h)
-const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
-
-// Name of metadata node where RS optimization level resides (should be
-// synced with slang_rs_metadata.h)
-const llvm::StringRef OptimizationLevelMetadataName = "#optimization_level";
-
-
//////////////////////////////////////////////////////////////////////////////
// Compiler
@@ -314,27 +283,24 @@
if (mModule == NULL) // No module was loaded
return 0;
- llvm::NamedMDNode const *PragmaMetadata;
- llvm::NamedMDNode const *ExportVarMetadata;
- llvm::NamedMDNode const *ExportFuncMetadata;
- llvm::NamedMDNode const *ExportForEachNameMetadata;
- llvm::NamedMDNode const *ExportForEachMetadata;
- llvm::NamedMDNode const *ObjectSlotMetadata;
+ bcinfo::MetadataExtractor ME(mModule);
+ ME.extract();
+ size_t VarCount = ME.getExportVarCount();
+ size_t FuncCount = ME.getExportFuncCount();
+ size_t ForEachSigCount = ME.getExportForEachSignatureCount();
+ size_t ObjectSlotCount = ME.getObjectSlotCount();
+ size_t PragmaCount = ME.getPragmaCount();
+
+ std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
+ std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
+ std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
std::vector<std::string> ForEachNameList;
- std::vector<std::string> ForEachExpandList;
- std::vector<uint32_t> forEachSigList;
+ std::vector<uint32_t> ForEachSigList;
+ std::vector<const char*> ExportSymbols;
- llvm::NamedMDNode const *OptimizationLevelMetadata =
- mModule->getNamedMetadata(OptimizationLevelMetadataName);
-
- // Default to maximum optimization in the absence of named metadata node
- int OptimizationLevel = 3;
- if (OptimizationLevelMetadata) {
- llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
- OptimizationLevelMetadata->getOperand(0)->getOperand(0));
- OptimizationLevel = OL->getZExtValue();
- }
+ // Defaults to maximum optimization level from MetadataExtractor.
+ int OptimizationLevel = ME.getOptimizationLevel();
if (OptimizationLevel == 0) {
CodeGenOptLevel = llvm::CodeGenOpt::None;
@@ -388,59 +354,62 @@
// Get target data from Module
TD = new llvm::TargetData(mModule);
- // Load named metadata
- ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
- ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
- ExportForEachNameMetadata =
- mModule->getNamedMetadata(ExportForEachNameMetadataName);
- ExportForEachMetadata =
- mModule->getNamedMetadata(ExportForEachMetadataName);
- PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
- ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
-
- if (ExportForEachNameMetadata) {
- for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
- i != e;
- i++) {
- llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
- if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
- llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
- if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportForEachName =
- static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
- ForEachNameList.push_back(ExportForEachName.str());
- std::string ExpandName = ExportForEachName.str() + ".expand";
- ForEachExpandList.push_back(ExpandName);
- }
- }
+ // Read pragma information from MetadataExtractor
+ if (PragmaCount) {
+ ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
+ const char **PragmaKeys = ME.getPragmaKeyList();
+ const char **PragmaValues = ME.getPragmaValueList();
+ for (size_t i = 0; i < PragmaCount; i++) {
+ PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
}
}
- if (ExportForEachMetadata) {
- for (int i = 0, e = ExportForEachMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *SigNode = ExportForEachMetadata->getOperand(i);
- if (SigNode != NULL && SigNode->getNumOperands() == 1) {
- llvm::Value *SigVal = SigNode->getOperand(0);
- if (SigVal->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef SigString =
- static_cast<llvm::MDString*>(SigVal)->getString();
- uint32_t Signature = 0;
- if (SigString.getAsInteger(10, Signature)) {
- ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
- goto on_bcc_compile_error;
- }
- forEachSigList.push_back(Signature);
- }
- }
+ if (VarCount) {
+ const char **VarNames = ME.getExportVarNameList();
+ for (size_t i = 0; i < VarCount; i++) {
+ VarNameList.push_back(VarNames[i]);
+ ExportSymbols.push_back(VarNames[i]);
}
}
- runInternalPasses(ForEachNameList, forEachSigList);
+ if (FuncCount) {
+ const char **FuncNames = ME.getExportFuncNameList();
+ for (size_t i = 0; i < FuncCount; i++) {
+ FuncNameList.push_back(FuncNames[i]);
+ ExportSymbols.push_back(FuncNames[i]);
+ }
+ }
+
+ if (ForEachSigCount) {
+ const char **ForEachNames = ME.getExportForEachNameList();
+ const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
+ for (size_t i = 0; i < ForEachSigCount; i++) {
+ std::string Name(ForEachNames[i]);
+ ForEachNameList.push_back(Name);
+ ForEachExpandList.push_back(Name + ".expand");
+ ForEachSigList.push_back(ForEachSigs[i]);
+ }
+
+ // Need to wait until ForEachExpandList is fully populated to fill in
+ // exported symbols.
+ for (size_t i = 0; i < ForEachSigCount; i++) {
+ ExportSymbols.push_back(ForEachExpandList[i].c_str());
+ }
+ }
+
+ if (ObjectSlotCount) {
+ ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
+ const uint32_t *ObjectSlots = ME.getObjectSlotList();
+ for (size_t i = 0; i < ObjectSlotCount; i++) {
+ objectSlotList.push_back(ObjectSlots[i]);
+ }
+ }
+
+ runInternalPasses(ForEachNameList, ForEachSigList);
// Perform link-time optimization if we have multiple modules
if (mHasLinked) {
- runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
- ForEachExpandList, CodeGenOptLevel);
+ runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
}
// Perform code generation
@@ -461,9 +430,9 @@
// Load the ELF Object
mRSExecutable =
- rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
- mEmittedELFExecutable.size(),
- &resolveSymbolAdapter, this);
+ rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
+ mEmittedELFExecutable.size(),
+ &resolveSymbolAdapter, this);
if (!mRSExecutable) {
setError("Fail to load emitted ELF relocatable file");
@@ -471,81 +440,31 @@
}
rsloaderUpdateSectionHeaders(mRSExecutable,
- (unsigned char*) mEmittedELFExecutable.begin());
+ (unsigned char*) mEmittedELFExecutable.begin());
- if (ExportVarMetadata) {
- ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
- std::vector<std::string> &varNameList = mpResult->mExportVarsName;
-
- for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
- if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
- llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
- if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportVarName =
- static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
-
- varList.push_back(
- rsloaderGetSymbolAddress(mRSExecutable,
- ExportVarName.str().c_str()));
- varNameList.push_back(ExportVarName.str());
-#if DEBUG_MCJIT_REFLECT
- ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
- varList.back());
-#endif
- continue;
- }
- }
-
- varList.push_back(NULL);
+ // Once the ELF object has been loaded, populate the various slots for RS
+ // with the appropriate relocated addresses.
+ if (VarCount) {
+ ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
+ for (size_t i = 0; i < VarCount; i++) {
+ VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
+ VarNameList[i].c_str()));
}
}
- if (ExportFuncMetadata) {
- ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
- std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
-
- for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
- if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
- llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
- if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportFuncName =
- static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
-
- funcList.push_back(
- rsloaderGetSymbolAddress(mRSExecutable,
- ExportFuncName.str().c_str()));
- funcNameList.push_back(ExportFuncName.str());
-#if DEBUG_MCJIT_RELECT
- ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
- funcList.back());
-#endif
- }
- }
+ if (FuncCount) {
+ ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
+ for (size_t i = 0; i < FuncCount; i++) {
+ FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
+ FuncNameList[i].c_str()));
}
}
- if (ExportForEachNameMetadata) {
- ScriptCompiled::ExportForEachList &forEachList = mpResult->mExportForEach;
- std::vector<std::string> &ForEachNameList = mpResult->mExportForEachName;
-
- for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
- i != e;
- i++) {
- llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
- if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
- llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
- if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportForEachName =
- static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
- std::string Name = ExportForEachName.str() + ".expand";
-
- forEachList.push_back(
- rsloaderGetSymbolAddress(mRSExecutable, Name.c_str()));
- ForEachNameList.push_back(Name);
- }
- }
+ if (ForEachSigCount) {
+ ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
+ for (size_t i = 0; i < ForEachSigCount; i++) {
+ ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
+ ForEachExpandList[i].c_str()));
}
}
@@ -569,64 +488,6 @@
#endif
#endif
- // Read pragma information from the metadata node of the module.
- if (PragmaMetadata) {
- ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
-
- for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
- if (Pragma != NULL &&
- Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
- llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
- llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
-
- if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
- (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
- llvm::StringRef PragmaName =
- static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
- llvm::StringRef PragmaValue =
- static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
-
- pragmaList.push_back(
- std::make_pair(std::string(PragmaName.data(),
- PragmaName.size()),
- std::string(PragmaValue.data(),
- PragmaValue.size())));
-#if DEBUG_BCC_REFLECT
- ALOGD("compile(): Pragma: %s -> %s\n",
- pragmaList.back().first.c_str(),
- pragmaList.back().second.c_str());
-#endif
- }
- }
- }
- }
-
- if (ObjectSlotMetadata) {
- ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
-
- for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
- if (ObjectSlot != NULL &&
- ObjectSlot->getNumOperands() == 1) {
- llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
- if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef Slot =
- static_cast<llvm::MDString*>(SlotMDS)->getString();
- uint32_t USlot = 0;
- if (Slot.getAsInteger(10, USlot)) {
- setError("Non-integer object slot value '" + Slot.str() + "'");
- goto on_bcc_compile_error;
- }
- objectSlotList.push_back(USlot);
-#if DEBUG_BCC_REFLECT
- ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
-#endif
- }
- }
- }
- }
-
on_bcc_compile_error:
// ALOGE("on_bcc_compiler_error");
if (TD) {
@@ -812,46 +673,11 @@
}
int Compiler::runLTO(llvm::TargetData *TD,
- llvm::NamedMDNode const *ExportVarMetadata,
- llvm::NamedMDNode const *ExportFuncMetadata,
- std::vector<std::string>& ForEachExpandList,
+ std::vector<const char*>& ExportSymbols,
llvm::CodeGenOpt::Level OptimizationLevel) {
- // Collect All Exported Symbols
- std::vector<const char*> ExportSymbols;
-
- // Note: This is a workaround for getting export variable and function name.
+ // Note: ExportSymbols is a workaround for getting all exported variable,
+ // function, and kernel names.
// We should refine it soon.
- if (ExportVarMetadata) {
- for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
- if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
- llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
- if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportVarName =
- static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
- ExportSymbols.push_back(ExportVarName.data());
- }
- }
- }
- }
-
- if (ExportFuncMetadata) {
- for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
- if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
- llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
- if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportFuncName =
- static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
- ExportSymbols.push_back(ExportFuncName.data());
- }
- }
- }
- }
-
- for (int i = 0, e = ForEachExpandList.size(); i != e; i++) {
- ExportSymbols.push_back(ForEachExpandList[i].c_str());
- }
// TODO(logan): Remove this after we have finished the
// bccMarkExternalSymbol API.
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index c70a920..eebe550 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -77,17 +77,9 @@
static void LLVMErrorHandler(void *UserData, const std::string &Message);
- static const llvm::StringRef PragmaMetadataName;
- static const llvm::StringRef ExportVarMetadataName;
- static const llvm::StringRef ExportFuncMetadataName;
- static const llvm::StringRef ExportForEachNameMetadataName;
- static const llvm::StringRef ExportForEachMetadataName;
- static const llvm::StringRef ObjectSlotMetadataName;
-
friend class CodeEmitter;
friend class CodeMemoryManager;
-
private:
ScriptCompiled *mpResult;
@@ -182,9 +174,7 @@
std::vector<uint32_t>& Signatures);
int runLTO(llvm::TargetData *TD,
- llvm::NamedMDNode const *ExportVarMetadata,
- llvm::NamedMDNode const *ExportFuncMetadata,
- std::vector<std::string>& ForEachExpandList,
+ std::vector<const char*>& ExportSymbols,
llvm::CodeGenOpt::Level OptimizationLevel);
bool hasError() const {