Switch RSForEachExpandPass to use MetadataExtractor.

Change-Id: I442054e7aa2329b369f578052bd41c7a973cc822
diff --git a/include/bcc/Renderscript/RSTransforms.h b/include/bcc/Renderscript/RSTransforms.h
index 758a8ba..9ca6eea 100644
--- a/include/bcc/Renderscript/RSTransforms.h
+++ b/include/bcc/Renderscript/RSTransforms.h
@@ -17,8 +17,6 @@
 #ifndef BCC_RS_TRANSFORMS_H
 #define BCC_RS_TRANSFORMS_H
 
-#include "bcc/Renderscript/RSInfo.h"
-
 namespace llvm {
   class ModulePass;
 }
@@ -26,8 +24,7 @@
 namespace bcc {
 
 llvm::ModulePass *
-createRSForEachExpandPass(const RSInfo::ExportForeachFuncListTy &pForeachFuncs,
-                          bool pEnableStepOpt);
+createRSForEachExpandPass(bool pEnableStepOpt);
 
 llvm::ModulePass * createRSEmbedInfoPass();
 
diff --git a/lib/Renderscript/RSCompiler.cpp b/lib/Renderscript/RSCompiler.cpp
index 354338f..5947372 100644
--- a/lib/Renderscript/RSCompiler.cpp
+++ b/lib/Renderscript/RSCompiler.cpp
@@ -20,12 +20,13 @@
 #include <llvm/PassManager.h>
 #include <llvm/Transforms/IPO.h>
 
+#include "bcc/Assert.h"
 #include "bcc/Renderscript/RSExecutable.h"
-#include "bcc/Renderscript/RSInfo.h"
 #include "bcc/Renderscript/RSScript.h"
 #include "bcc/Renderscript/RSTransforms.h"
 #include "bcc/Source.h"
 #include "bcc/Support/Log.h"
+#include "bcinfo/MetadataExtractor.h"
 
 using namespace bcc;
 
@@ -33,7 +34,12 @@
   // Add a pass to internalize the symbols that don't need to have global
   // visibility.
   RSScript &script = static_cast<RSScript &>(pScript);
-  const RSInfo *info = script.getInfo();
+  llvm::Module &module = script.getSource().getModule();
+  bcinfo::MetadataExtractor me(&module);
+  if (!me.extract()) {
+    bccAssert(false && "Could not extract metadata for module!");
+    return false;
+  }
 
   // The vector contains the symbols that should not be internalized.
   std::vector<const char *> export_symbols;
@@ -47,41 +53,32 @@
 
   // Visibility of symbols appeared in rs_export_var and rs_export_func should
   // also be preserved.
-  const RSInfo::ExportVarNameListTy &export_vars = info->getExportVarNames();
-  const RSInfo::ExportFuncNameListTy &export_funcs = info->getExportFuncNames();
+  size_t exportVarCount = me.getExportVarCount();
+  size_t exportFuncCount = me.getExportFuncCount();
+  size_t exportForEachCount = me.getExportForEachSignatureCount();
+  const char **exportVarNameList = me.getExportVarNameList();
+  const char **exportFuncNameList = me.getExportFuncNameList();
+  const char **exportForEachNameList = me.getExportForEachNameList();
+  size_t i;
 
-  for (RSInfo::ExportVarNameListTy::const_iterator
-           export_var_iter = export_vars.begin(),
-           export_var_end = export_vars.end();
-       export_var_iter != export_var_end; export_var_iter++) {
-    export_symbols.push_back(*export_var_iter);
+  for (i = 0; i < exportVarCount; ++i) {
+    export_symbols.push_back(exportVarNameList[i]);
   }
 
-  for (RSInfo::ExportFuncNameListTy::const_iterator
-           export_func_iter = export_funcs.begin(),
-           export_func_end = export_funcs.end();
-       export_func_iter != export_func_end; export_func_iter++) {
-    export_symbols.push_back(*export_func_iter);
+  for (i = 0; i < exportFuncCount; ++i) {
+    export_symbols.push_back(exportFuncNameList[i]);
   }
 
   // Expanded foreach functions should not be internalized, too.
-  const RSInfo::ExportForeachFuncListTy &export_foreach_func =
-      info->getExportForeachFuncs();
+  // expanded_foreach_funcs keeps the .expand version of the kernel names
+  // around until createInternalizePass() is finished making its own
+  // copy of the visible symbols.
   std::vector<std::string> expanded_foreach_funcs;
-  for (RSInfo::ExportForeachFuncListTy::const_iterator
-           foreach_func_iter = export_foreach_func.begin(),
-           foreach_func_end = export_foreach_func.end();
-       foreach_func_iter != foreach_func_end; foreach_func_iter++) {
-    std::string name(foreach_func_iter->first);
-    expanded_foreach_funcs.push_back(name.append(".expand"));
-  }
-
-  // Need to wait until ForEachExpandList is fully populated to fill in
-  // exported symbols.
-  for (size_t i = 0; i < expanded_foreach_funcs.size(); i++) {
+  for (i = 0; i < exportForEachCount; ++i) {
+    expanded_foreach_funcs.push_back(
+        std::string(exportForEachNameList[i]) + ".expand");
     export_symbols.push_back(expanded_foreach_funcs[i].c_str());
   }
-
   pPM.add(llvm::createInternalizePass(export_symbols));
 
   return true;
@@ -90,19 +87,10 @@
 bool RSCompiler::addExpandForEachPass(Script &pScript, llvm::PassManager &pPM) {
   // Script passed to RSCompiler must be a RSScript.
   RSScript &script = static_cast<RSScript &>(pScript);
-  const RSInfo *info = script.getInfo();
-  llvm::Module &module = script.getSource().getModule();
-
-  if (info == NULL) {
-    ALOGE("Missing RSInfo in RSScript to run the pass for foreach expansion on "
-          "%s!", module.getModuleIdentifier().c_str());
-    return false;
-  }
 
   // Expand ForEach on CPU path to reduce launch overhead.
   bool pEnableStepOpt = true;
-  pPM.add(createRSForEachExpandPass(info->getExportForeachFuncs(),
-                                    pEnableStepOpt));
+  pPM.add(createRSForEachExpandPass(pEnableStepOpt));
   if (script.getEmbedInfo())
     pPM.add(createRSEmbedInfoPass());
 
diff --git a/lib/Renderscript/RSForEachExpand.cpp b/lib/Renderscript/RSForEachExpand.cpp
index a2a3ea7..8ccd1ac 100644
--- a/lib/Renderscript/RSForEachExpand.cpp
+++ b/lib/Renderscript/RSForEachExpand.cpp
@@ -33,7 +33,6 @@
 #include <llvm/Transforms/Utils/BasicBlockUtils.h>
 
 #include "bcc/Config/Config.h"
-#include "bcc/Renderscript/RSInfo.h"
 #include "bcc/Support/Log.h"
 
 #include "bcinfo/MetadataExtractor.h"
@@ -59,7 +58,9 @@
   llvm::Module *M;
   llvm::LLVMContext *C;
 
-  const RSInfo::ExportForeachFuncListTy &mFuncs;
+  uint32_t mExportForEachCount;
+  const char **mExportForEachNameList;
+  const uint32_t *mExportForEachSignatureList;
 
   // Turns on optimization of allocation stride values.
   bool mEnableStepOpt;
@@ -281,10 +282,8 @@
   }
 
 public:
-  RSForEachExpandPass(const RSInfo::ExportForeachFuncListTy &pForeachFuncs,
-                      bool pEnableStepOpt)
-      : ModulePass(ID), M(NULL), C(NULL), mFuncs(pForeachFuncs),
-        mEnableStepOpt(pEnableStepOpt) {
+  RSForEachExpandPass(bool pEnableStepOpt)
+      : ModulePass(ID), M(NULL), C(NULL), mEnableStepOpt(pEnableStepOpt) {
   }
 
   /* Performs the actual optimization on a selected function. On success, the
@@ -614,11 +613,9 @@
     // Old style kernel function can expose pointers to elements within
     // allocations.
     // TODO: Extend analysis to allow simple cases of old-style kernels.
-    for (RSInfo::ExportForeachFuncListTy::const_iterator
-             func_iter = mFuncs.begin(), func_end = mFuncs.end();
-         func_iter != func_end; func_iter++) {
-      const char *Name = func_iter->first;
-      uint32_t Signature = func_iter->second;
+    for (size_t i = 0; i < mExportForEachCount; ++i) {
+      const char *Name = mExportForEachNameList[i];
+      uint32_t Signature = mExportForEachSignatureList[i];
       if (M.getFunction(Name) &&
           !bcinfo::MetadataExtractor::hasForEachSignatureKernel(Signature)) {
         return true;
@@ -685,14 +682,20 @@
     bool Changed = false;
     this->M = &M;
     C = &M.getContext();
+    bcinfo::MetadataExtractor me(&M);
+    if (!me.extract()) {
+      ALOGE("Could not extract metadata from module!");
+      return false;
+    }
+    mExportForEachCount = me.getExportForEachSignatureCount();
+    mExportForEachNameList = me.getExportForEachNameList();
+    mExportForEachSignatureList = me.getExportForEachSignatureList();
 
     bool AllocsExposed = allocPointersExposed(M);
 
-    for (RSInfo::ExportForeachFuncListTy::const_iterator
-             func_iter = mFuncs.begin(), func_end = mFuncs.end();
-         func_iter != func_end; func_iter++) {
-      const char *name = func_iter->first;
-      uint32_t signature = func_iter->second;
+    for (size_t i = 0; i < mExportForEachCount; ++i) {
+      const char *name = mExportForEachNameList[i];
+      uint32_t signature = mExportForEachSignatureList[i];
       llvm::Function *kernel = M.getFunction(name);
       if (kernel) {
         if (bcinfo::MetadataExtractor::hasForEachSignatureKernel(signature)) {
@@ -729,9 +732,8 @@
 namespace bcc {
 
 llvm::ModulePass *
-createRSForEachExpandPass(const RSInfo::ExportForeachFuncListTy &pForeachFuncs,
-                          bool pEnableStepOpt){
-  return new RSForEachExpandPass(pForeachFuncs, pEnableStepOpt);
+createRSForEachExpandPass(bool pEnableStepOpt){
+  return new RSForEachExpandPass(pEnableStepOpt);
 }
 
 } // end namespace bcc