Add LinkRuntimeCallback() and supporting functions to RS compiler.

Change-Id: I7745406a94ba74896ee98752a3de106d2672159d
diff --git a/include/bcc/Renderscript/RSCompilerDriver.h b/include/bcc/Renderscript/RSCompilerDriver.h
index 2b34ae5..14e8856 100644
--- a/include/bcc/Renderscript/RSCompilerDriver.h
+++ b/include/bcc/Renderscript/RSCompilerDriver.h
@@ -77,7 +77,8 @@
   RSExecutable *build(BCCContext &pContext,
                       const char *pCacheDir, const char *pResName,
                       const char *pBitcode, size_t pBitcodeSize,
-                      const char *pRuntimePath);
+                      const char *pRuntimePath,
+                      RSLinkRuntimeCallback pLinkRuntimeCallback = NULL);
   RSExecutable *build(RSScript &pScript, const char *pOut,
                       const char *pRuntimePath);
 };
diff --git a/include/bcc/Renderscript/RSScript.h b/include/bcc/Renderscript/RSScript.h
index 7a6e07d..b6c19ef 100644
--- a/include/bcc/Renderscript/RSScript.h
+++ b/include/bcc/Renderscript/RSScript.h
@@ -20,11 +20,18 @@
 #include "bcc/Script.h"
 #include "bcc/Support/Sha1Util.h"
 
+namespace llvm {
+  class Module;
+}  // end namespace llvm
+
 namespace bcc {
 
 class RSInfo;
+class RSScript;
 class Source;
 
+typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
+
 class RSScript : public Script {
 public:
   // This is one-one mapping with the llvm::CodeGenOpt::Level in
@@ -44,6 +51,8 @@
 
   OptimizationLevel mOptimizationLevel;
 
+  RSLinkRuntimeCallback mLinkRuntimeCallback;
+
   bool mEmbedInfo;
 
 private:
@@ -80,6 +89,10 @@
     return mOptimizationLevel;
   }
 
+  void setLinkRuntimeCallback(RSLinkRuntimeCallback fn){
+    mLinkRuntimeCallback = fn;
+  }
+
   void setEmbedInfo(bool pEnable) {
     mEmbedInfo = pEnable;
   }
diff --git a/include/bcc/Source.h b/include/bcc/Source.h
index 74d477a..4aa76c1 100644
--- a/include/bcc/Source.h
+++ b/include/bcc/Source.h
@@ -66,6 +66,8 @@
   inline const BCCContext &getContext() const
   { return mContext; }
 
+  void setModule(llvm::Module *pModule);
+
   inline llvm::Module &getModule()
   { return *mModule;  }
   inline const llvm::Module &getModule() const
diff --git a/lib/Core/Source.cpp b/lib/Core/Source.cpp
index 6fa7882..e0e6886 100644
--- a/lib/Core/Source.cpp
+++ b/lib/Core/Source.cpp
@@ -53,6 +53,11 @@
 
 namespace bcc {
 
+void Source::setModule(llvm::Module *pModule) {
+  if (!mNoDelete && (mModule != pModule)) delete mModule;
+  mModule = pModule;
+}
+
 Source *Source::CreateFromBuffer(BCCContext &pContext,
                                  const char *pName,
                                  const char *pBitcode,
diff --git a/lib/Renderscript/RSCompilerDriver.cpp b/lib/Renderscript/RSCompilerDriver.cpp
index 7963408..474b884 100644
--- a/lib/Renderscript/RSCompilerDriver.cpp
+++ b/lib/Renderscript/RSCompilerDriver.cpp
@@ -331,7 +331,8 @@
                                       const char *pResName,
                                       const char *pBitcode,
                                       size_t pBitcodeSize,
-                                      const char *pRuntimePath) {
+                                      const char *pRuntimePath,
+                                      RSLinkRuntimeCallback pLinkRuntimeCallback) {
   android::StopWatch build_time("bcc: RSCompilerDriver::build time");
   //===--------------------------------------------------------------------===//
   // Check parameters.
@@ -398,6 +399,8 @@
     return NULL;
   }
 
+  script->setLinkRuntimeCallback(pLinkRuntimeCallback);
+
   // Read information from bitcode wrapper.
   bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
   script->setCompilerVersion(wrapper.getCompilerVersion());
diff --git a/lib/Renderscript/RSScript.cpp b/lib/Renderscript/RSScript.cpp
index 53c8946..d4db9fa 100644
--- a/lib/Renderscript/RSScript.cpp
+++ b/lib/Renderscript/RSScript.cpp
@@ -47,6 +47,11 @@
     return false;
   }
 
+  if (NULL != pScript.mLinkRuntimeCallback) {
+    pScript.mLinkRuntimeCallback(&pScript,
+        &pScript.getSource().getModule(), &libclcore_source->getModule());
+  }
+
   if (!pScript.getSource().merge(*libclcore_source,
                                  /* pPreserveSource */false)) {
     ALOGE("Failed to link Renderscript library '%s'!", core_lib);
@@ -59,7 +64,8 @@
 
 RSScript::RSScript(Source &pSource)
   : Script(pSource), mInfo(NULL), mCompilerVersion(0),
-    mOptimizationLevel(kOptLvl3) { }
+    mOptimizationLevel(kOptLvl3), mLinkRuntimeCallback(NULL),
+    mEmbedInfo(false) { }
 
 bool RSScript::doReset() {
   mInfo = NULL;
diff --git a/lib/Renderscript/runtime/rs_structs.h b/lib/Renderscript/runtime/rs_structs.h
index a61ebea..4ee066e 100644
--- a/lib/Renderscript/runtime/rs_structs.h
+++ b/lib/Renderscript/runtime/rs_structs.h
@@ -1,5 +1,5 @@
-#ifndef _RS_CORE_H_
-#define _RS_CORE_H_
+#ifndef _RS_STRUCTS_H_
+#define _RS_STRUCTS_H_
 
 /*****************************************************************************
  * CAUTION