186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines/*
286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * Copyright 2012, The Android Open Source Project
386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines *
486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * you may not use this file except in compliance with the License.
686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * You may obtain a copy of the License at
786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines *
886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines *
1086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * Unless required by applicable law or agreed to in writing, software
1186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
1286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * See the License for the specific language governing permissions and
1486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines * limitations under the License.
1586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines */
1686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
17a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Assert.h"
18a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Log.h"
19a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "RSTransforms.h"
20a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "RSUtils.h"
21fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "rsDefines.h"
2286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
23a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "bcc/Config.h"
24a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "bcinfo/MetadataExtractor.h"
25a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet
26f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond#include <string>
2786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <cstdlib>
280116d8b4247829adfb64b9cb7992eb783a54abd5Stephen Hines#include <vector>
2986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
30b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/DerivedTypes.h>
31b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Function.h>
32f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond#include <llvm/IR/Metadata.h>
33b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Instructions.h>
34b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/IRBuilder.h>
35b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h>
3686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <llvm/Pass.h>
3786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <llvm/Support/raw_ostream.h>
38b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Type.h>
3986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
4086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesusing namespace bcc;
4186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
4286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesnamespace {
4386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
442d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines/* RSEmbedInfoPass - This pass operates on the entire module and embeds a
452d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * string constaining relevant metadata directly as a global variable.
462d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * This information does not need to be consistent across Android releases,
472d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * because the standalone compiler + compatibility driver or system driver
482d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * will be using the same format (i.e. bcc_compat + libRSSupport.so or
492d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * bcc + libRSCpuRef are always paired together for installation).
5086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines */
5186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesclass RSEmbedInfoPass : public llvm::ModulePass {
5286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesprivate:
5386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  static char ID;
5486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
5586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  llvm::Module *M;
5686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  llvm::LLVMContext *C;
5786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
5886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinespublic:
591253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines  RSEmbedInfoPass()
6086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines      : ModulePass(ID),
61900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes        M(nullptr) {
6286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  }
6386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
64c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
65c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines    AU.setPreservesAll();
66c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines  }
67c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines
681253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines  static std::string getRSInfoString(const llvm::Module *module) {
6986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    std::string str;
7086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    llvm::raw_string_ostream s(str);
711253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    bcinfo::MetadataExtractor me(module);
721253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    if (!me.extract()) {
731253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      bccAssert(false && "Could not extract RS metadata for module!");
741253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      return std::string("");
751253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    }
761253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines
771253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    size_t exportVarCount = me.getExportVarCount();
781253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    size_t exportFuncCount = me.getExportFuncCount();
791253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    size_t exportForEachCount = me.getExportForEachSignatureCount();
804e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala    size_t exportReduceCount = me.getExportReduceCount();
811253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    size_t objectSlotCount = me.getObjectSlotCount();
82a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    size_t pragmaCount = me.getPragmaCount();
831253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    const char **exportVarNameList = me.getExportVarNameList();
841253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    const char **exportFuncNameList = me.getExportFuncNameList();
851253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    const char **exportForEachNameList = me.getExportForEachNameList();
861253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    const uint32_t *exportForEachSignatureList =
871253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines        me.getExportForEachSignatureList();
88a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    const bcinfo::MetadataExtractor::Reduce *exportReduceList =
89a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        me.getExportReduceList();
901253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    const uint32_t *objectSlotList = me.getObjectSlotList();
91a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    const char **pragmaKeyList = me.getPragmaKeyList();
92a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    const char **pragmaValueList = me.getPragmaValueList();
939fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar    bool isThreadable = me.isThreadable();
9451ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    const char *buildChecksum = me.getBuildChecksum();
9551ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar
961253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    size_t i;
9786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
9879e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross    // We use a simple text format here that the compatibility library
9979e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross    // can easily parse. Each section starts out with its name
10079e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross    // followed by a count.  The count denotes the number of lines to
101a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // parse for that particular category. Variables and Functions
102a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // merely put the appropriate identifier on the line. ForEach
103a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // kernels have the encoded int signature, followed by a hyphen
104a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // followed by the identifier (function to look up). General
105a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // reduce kernels have the encoded int signature, followed by a
106a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // hyphen followed by the accumulator data size, followed by a
107a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // hyphen followed by the identifier (reduction name); and then
108a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // for each possible constituent function, a hyphen followed by
109a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // the identifier (function name) -- in the case where the
110a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // function is omitted, "." is used in place of the identifier.
111a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    // Object Slots are just listed as one integer per line.
11279e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross
1131253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    s << "exportVarCount: " << exportVarCount << "\n";
1141253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    for (i = 0; i < exportVarCount; ++i) {
1151253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      s << exportVarNameList[i] << "\n";
11686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    }
11786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
1181253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    s << "exportFuncCount: " << exportFuncCount << "\n";
1191253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    for (i = 0; i < exportFuncCount; ++i) {
1201253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      s << exportFuncNameList[i] << "\n";
12186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    }
12286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
1231253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    s << "exportForEachCount: " << exportForEachCount << "\n";
1241253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    for (i = 0; i < exportForEachCount; ++i) {
1251253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      s << exportForEachSignatureList[i] << " - "
1261253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines        << exportForEachNameList[i] << "\n";
12786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    }
12886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
1294e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala    s << "exportReduceCount: " << exportReduceCount << "\n";
130a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross    auto reduceFnName = [](const char *Name) { return Name ? Name : "."; };
1314e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala    for (i = 0; i < exportReduceCount; ++i) {
132a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross      const bcinfo::MetadataExtractor::Reduce &reduce = exportReduceList[i];
133a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross      s << reduce.mSignature << " - "
134a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduce.mAccumulatorDataSize << " - "
135a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduce.mReduceName << " - "
136a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduceFnName(reduce.mInitializerName) << " - "
137a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduceFnName(reduce.mAccumulatorName) << " - "
138a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << ((reduce.mCombinerName != nullptr)
139a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross            ? reduce.mCombinerName
140a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross            : nameReduceCombinerFromAccumulator(reduce.mAccumulatorName)) << " - "
141a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduceFnName(reduce.mOutConverterName) << " - "
142a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross        << reduceFnName(reduce.mHalterName)
14379e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross        << "\n";
14479e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross    }
14579e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross
1461253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    s << "objectSlotCount: " << objectSlotCount << "\n";
1471253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines    for (i = 0; i < objectSlotCount; ++i) {
1481253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines      s << objectSlotList[i] << "\n";
14986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    }
15086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
151a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    s << "pragmaCount: " << pragmaCount << "\n";
152a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    for (i = 0; i < pragmaCount; ++i) {
153a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar      s << pragmaKeyList[i] << " - "
154a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar        << pragmaValueList[i] << "\n";
155a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar    }
1569fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar    s << "isThreadable: " << ((isThreadable) ? "yes" : "no") << "\n";
157a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar
158e1c7d298e3e38ffff294ce57c37ab43827a67ee5Stephen Hines    if (buildChecksum != nullptr && buildChecksum[0]) {
15951ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar      s << "buildChecksum: " << buildChecksum << "\n";
16051ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    }
16151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar
162f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond    {
163f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      // As per `exportReduceCount`'s linewise fields, we use the literal `"."`
164f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      // to signify the empty field. This makes it easy to parse when it's
165f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      // missing.
166f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      llvm::StringRef slangVersion(".");
167f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      if (auto nmd = module->getNamedMetadata("slang.llvm.version")) {
168f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond        if (auto md = nmd->getOperand(0)) {
169f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond          if (const auto ver =
170f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond                  llvm::dyn_cast<llvm::MDString>(md->getOperand(0))) {
171f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            slangVersion = ver->getString();
172f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond          }
173f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond        }
174f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      }
175f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      s << "versionInfo: 2\n";
176f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      s << "bcc - " << LLVM_VERSION_STRING << "\n";
177f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      s << "slang - " << slangVersion << "\n";
178f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      if (slangVersion != LLVM_VERSION_STRING && me.hasDebugInfo()) {
179f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond        ALOGW(
180f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            "The debug info in module '%s' has a different version than "
181f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            "expected (%s, expecting %s). The debugging experience may be "
182f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            "unreliable.",
183f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            module->getModuleIdentifier().c_str(), slangVersion.str().c_str(),
184f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond            LLVM_VERSION_STRING);
185f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond      }
186f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond    }
187f4c3483f3abc4cadd20672ce49acfe0c88a1c1daLuke Drummond
18886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    s.flush();
1892d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines    return str;
1902d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines  }
1912d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines
1922d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines  virtual bool runOnModule(llvm::Module &M) {
1932d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines    this->M = &M;
1942d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines    C = &M.getContext();
19586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
19686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    // Embed this as the global variable .rs.info so that it will be
19786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    // accessible from the shared object later.
1982d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines    llvm::Constant *Init = llvm::ConstantDataArray::getString(*C,
1991253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines                                                              getRSInfoString(&M));
20086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    llvm::GlobalVariable *InfoGV =
20186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines        new llvm::GlobalVariable(M, Init->getType(), true,
20286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines                                 llvm::GlobalValue::ExternalLinkage, Init,
203fb81ec1a875d13d9750006313b9123903336101dStephen Hines                                 kRsInfo);
20486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    (void) InfoGV;
20586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
20686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    return true;
20786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  }
20886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
20986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  virtual const char *getPassName() const {
21086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines    return "Embed Renderscript Info";
21186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  }
21286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
21386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines};  // end RSEmbedInfoPass
21486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
21586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines}  // end anonymous namespace
21686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
21786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hineschar RSEmbedInfoPass::ID = 0;
21886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
21986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesnamespace bcc {
22086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
22186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesllvm::ModulePass *
2221253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen HinescreateRSEmbedInfoPass() {
2231253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines  return new RSEmbedInfoPass();
22486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines}
22586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
22686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines}  // end namespace bcc
227