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 1786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include "bcc/Assert.h" 18fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "bcc/Config/Config.h" 1986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include "bcc/Renderscript/RSTransforms.h" 2057fd9f882f3359be4201c42b02aebf785d311df2David Gross#include "bcc/Renderscript/RSUtils.h" 21fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "bcc/Support/Log.h" 22fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "bcinfo/MetadataExtractor.h" 23fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "rsDefines.h" 2486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 2586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <cstdlib> 260116d8b4247829adfb64b9cb7992eb783a54abd5Stephen Hines#include <vector> 2786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 28b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/DerivedTypes.h> 29b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Function.h> 30b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Instructions.h> 31b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/IRBuilder.h> 32b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h> 3386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <llvm/Pass.h> 3486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines#include <llvm/Support/raw_ostream.h> 35b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Type.h> 3686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 3786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesusing namespace bcc; 3886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 3986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesnamespace { 4086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 412d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines/* RSEmbedInfoPass - This pass operates on the entire module and embeds a 422d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * string constaining relevant metadata directly as a global variable. 432d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * This information does not need to be consistent across Android releases, 442d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * because the standalone compiler + compatibility driver or system driver 452d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * will be using the same format (i.e. bcc_compat + libRSSupport.so or 462d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines * bcc + libRSCpuRef are always paired together for installation). 4786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines */ 4886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesclass RSEmbedInfoPass : public llvm::ModulePass { 4986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesprivate: 5086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines static char ID; 5186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 5286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines llvm::Module *M; 5386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines llvm::LLVMContext *C; 5486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 5586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinespublic: 561253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines RSEmbedInfoPass() 5786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines : ModulePass(ID), 58900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes M(nullptr) { 5986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 6086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 61c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { 62c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines AU.setPreservesAll(); 63c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines } 64c754d49ee856be620e041348a9f2b3d5610a5a26Stephen Hines 651253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines static std::string getRSInfoString(const llvm::Module *module) { 6686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines std::string str; 6786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines llvm::raw_string_ostream s(str); 681253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines bcinfo::MetadataExtractor me(module); 691253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines if (!me.extract()) { 701253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines bccAssert(false && "Could not extract RS metadata for module!"); 711253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines return std::string(""); 721253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines } 731253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines 741253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines size_t exportVarCount = me.getExportVarCount(); 751253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines size_t exportFuncCount = me.getExportFuncCount(); 761253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines size_t exportForEachCount = me.getExportForEachSignatureCount(); 774e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala size_t exportReduceCount = me.getExportReduceCount(); 781253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines size_t objectSlotCount = me.getObjectSlotCount(); 79a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar size_t pragmaCount = me.getPragmaCount(); 801253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines const char **exportVarNameList = me.getExportVarNameList(); 811253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines const char **exportFuncNameList = me.getExportFuncNameList(); 821253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines const char **exportForEachNameList = me.getExportForEachNameList(); 831253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines const uint32_t *exportForEachSignatureList = 841253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines me.getExportForEachSignatureList(); 85a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce *exportReduceList = 86a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross me.getExportReduceList(); 871253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines const uint32_t *objectSlotList = me.getObjectSlotList(); 88a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar const char **pragmaKeyList = me.getPragmaKeyList(); 89a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar const char **pragmaValueList = me.getPragmaValueList(); 909fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar bool isThreadable = me.isThreadable(); 9151ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar const char *buildChecksum = me.getBuildChecksum(); 9251ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar 931253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines size_t i; 9486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 9579e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross // We use a simple text format here that the compatibility library 9679e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross // can easily parse. Each section starts out with its name 9779e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross // followed by a count. The count denotes the number of lines to 98a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // parse for that particular category. Variables and Functions 99a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // merely put the appropriate identifier on the line. ForEach 100a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // kernels have the encoded int signature, followed by a hyphen 101a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // followed by the identifier (function to look up). General 102a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // reduce kernels have the encoded int signature, followed by a 103a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // hyphen followed by the accumulator data size, followed by a 104a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // hyphen followed by the identifier (reduction name); and then 105a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // for each possible constituent function, a hyphen followed by 106a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // the identifier (function name) -- in the case where the 107a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // function is omitted, "." is used in place of the identifier. 108a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross // Object Slots are just listed as one integer per line. 10979e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross 1101253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << "exportVarCount: " << exportVarCount << "\n"; 1111253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines for (i = 0; i < exportVarCount; ++i) { 1121253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << exportVarNameList[i] << "\n"; 11386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 11486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 1151253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << "exportFuncCount: " << exportFuncCount << "\n"; 1161253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines for (i = 0; i < exportFuncCount; ++i) { 1171253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << exportFuncNameList[i] << "\n"; 11886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 11986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 1201253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << "exportForEachCount: " << exportForEachCount << "\n"; 1211253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines for (i = 0; i < exportForEachCount; ++i) { 1221253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << exportForEachSignatureList[i] << " - " 1231253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines << exportForEachNameList[i] << "\n"; 12486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 12586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 1264e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala s << "exportReduceCount: " << exportReduceCount << "\n"; 127a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross auto reduceFnName = [](const char *Name) { return Name ? Name : "."; }; 1284e7a50685ae18a24087f6f2a51c604e71fab69e2Matt Wala for (i = 0; i < exportReduceCount; ++i) { 129a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross const bcinfo::MetadataExtractor::Reduce &reduce = exportReduceList[i]; 130a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross s << reduce.mSignature << " - " 131a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduce.mAccumulatorDataSize << " - " 132a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduce.mReduceName << " - " 133a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduceFnName(reduce.mInitializerName) << " - " 134a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduceFnName(reduce.mAccumulatorName) << " - " 135a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << ((reduce.mCombinerName != nullptr) 136a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross ? reduce.mCombinerName 137a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross : nameReduceCombinerFromAccumulator(reduce.mAccumulatorName)) << " - " 138a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduceFnName(reduce.mOutConverterName) << " - " 139a48ea364652efcf947dd33c8a6ba893e9c00dd6aDavid Gross << reduceFnName(reduce.mHalterName) 14079e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross << "\n"; 14179e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross } 14279e1a05f704ada1bb12749fe3f8b9b69309be9e5David Gross 1431253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << "objectSlotCount: " << objectSlotCount << "\n"; 1441253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines for (i = 0; i < objectSlotCount; ++i) { 1451253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines s << objectSlotList[i] << "\n"; 14686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 14786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 148a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar s << "pragmaCount: " << pragmaCount << "\n"; 149a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar for (i = 0; i < pragmaCount; ++i) { 150a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar s << pragmaKeyList[i] << " - " 151a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar << pragmaValueList[i] << "\n"; 152a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar } 1539fe081b8bae8a95d903f8fa8dc0a7590ae706606Pirama Arumuga Nainar s << "isThreadable: " << ((isThreadable) ? "yes" : "no") << "\n"; 154a99ef646b808e99cf870a8663170a1162851a42fPirama Arumuga Nainar 155e1c7d298e3e38ffff294ce57c37ab43827a67ee5Stephen Hines if (buildChecksum != nullptr && buildChecksum[0]) { 15651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar s << "buildChecksum: " << buildChecksum << "\n"; 15751ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar } 15851ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar 15986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines s.flush(); 1602d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines return str; 1612d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines } 1622d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines 1632d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines virtual bool runOnModule(llvm::Module &M) { 1642d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines this->M = &M; 1652d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines C = &M.getContext(); 16686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 16786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines // Embed this as the global variable .rs.info so that it will be 16886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines // accessible from the shared object later. 1692d201e547f1d32140ff8ead1818c169f441cf5fbStephen Hines llvm::Constant *Init = llvm::ConstantDataArray::getString(*C, 1701253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines getRSInfoString(&M)); 17186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines llvm::GlobalVariable *InfoGV = 17286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines new llvm::GlobalVariable(M, Init->getType(), true, 17386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines llvm::GlobalValue::ExternalLinkage, Init, 174fb81ec1a875d13d9750006313b9123903336101dStephen Hines kRsInfo); 17586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines (void) InfoGV; 17686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 17786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines return true; 17886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 17986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 18086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines virtual const char *getPassName() const { 18186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines return "Embed Renderscript Info"; 18286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines } 18386a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 18486a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines}; // end RSEmbedInfoPass 18586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 18686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines} // end anonymous namespace 18786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 18886a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hineschar RSEmbedInfoPass::ID = 0; 18986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 19086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesnamespace bcc { 19186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 19286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hinesllvm::ModulePass * 1931253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen HinescreateRSEmbedInfoPass() { 1941253c195dd7911ad91bd66790f03e4c2f8888ad2Stephen Hines return new RSEmbedInfoPass(); 19586a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines} 19686a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines 19786a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines} // end namespace bcc 198