RSEmbedInfo.cpp revision 0116d8b4247829adfb64b9cb7992eb783a54abd5
1/* 2 * Copyright 2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "bcc/Assert.h" 18#include "bcc/Renderscript/RSTransforms.h" 19 20#include <cstdlib> 21#include <vector> 22 23#include <llvm/DerivedTypes.h> 24#include <llvm/Function.h> 25#include <llvm/Instructions.h> 26#include <llvm/IRBuilder.h> 27#include <llvm/Module.h> 28#include <llvm/Pass.h> 29#include <llvm/Support/raw_ostream.h> 30#include <llvm/Target/TargetData.h> 31#include <llvm/Type.h> 32 33#include "bcc/Config/Config.h" 34#include "bcc/Renderscript/RSInfo.h" 35#include "bcc/Support/Log.h" 36 37using namespace bcc; 38 39namespace { 40 41/* RSForEachExpandPass - This pass operates on functions that are able to be 42 * called via rsForEach() or "foreach_<NAME>". We create an inner loop for the 43 * ForEach-able function to be invoked over the appropriate data cells of the 44 * input/output allocations (adjusting other relevant parameters as we go). We 45 * support doing this for any ForEach-able compute kernels. The new function 46 * name is the original function name followed by ".expand". Note that we 47 * still generate code for the original function. 48 */ 49class RSEmbedInfoPass : public llvm::ModulePass { 50private: 51 static char ID; 52 53 llvm::Module *M; 54 llvm::LLVMContext *C; 55 56 const RSInfo *mInfo; 57 58public: 59 RSEmbedInfoPass(const RSInfo *info) 60 : ModulePass(ID), 61 mInfo(info) { 62 } 63 64 virtual bool runOnModule(llvm::Module &M) { 65 this->M = &M; 66 C = &M.getContext(); 67 68 std::string str; 69 llvm::raw_string_ostream s(str); 70 71 // We use a simple text format here that the compatibility library can 72 // easily parse. Each section starts out with its name followed by a count. 73 // The count denotes the number of lines to parse for that particular 74 // category. Variables and Functions merely put the appropriate identifier 75 // on the line, while ForEach kernels have the encoded int signature, 76 // followed by a hyphen followed by the identifier (function to look up). 77 // Object Slots are just listed as one integer per line. 78 const RSInfo::ExportVarNameListTy &export_vars = mInfo->getExportVarNames(); 79 s << "exportVarCount: " << (unsigned int) export_vars.size() << "\n"; 80 for (RSInfo::ExportVarNameListTy::const_iterator 81 export_var_iter = export_vars.begin(), 82 export_var_end = export_vars.end(); 83 export_var_iter != export_var_end; export_var_iter++) { 84 s << *export_var_iter << "\n"; 85 } 86 87 const RSInfo::ExportFuncNameListTy &export_funcs = 88 mInfo->getExportFuncNames(); 89 s << "exportFuncCount: " << (unsigned int) export_funcs.size() << "\n"; 90 for (RSInfo::ExportFuncNameListTy::const_iterator 91 export_func_iter = export_funcs.begin(), 92 export_func_end = export_funcs.end(); 93 export_func_iter != export_func_end; export_func_iter++) { 94 s << *export_func_iter << "\n"; 95 } 96 97 const RSInfo::ExportForeachFuncListTy &export_foreach_funcs = 98 mInfo->getExportForeachFuncs(); 99 s << "exportForEachCount: " 100 << (unsigned int) export_foreach_funcs.size() << "\n"; 101 for (RSInfo::ExportForeachFuncListTy::const_iterator 102 foreach_func_iter = export_foreach_funcs.begin(), 103 foreach_func_end = export_foreach_funcs.end(); 104 foreach_func_iter != foreach_func_end; foreach_func_iter++) { 105 std::string name(foreach_func_iter->first); 106 s << foreach_func_iter->second << " - " 107 << foreach_func_iter->first << "\n"; 108 } 109 110 std::vector<unsigned int> object_slot_numbers; 111 unsigned int i = 0; 112 const RSInfo::ObjectSlotListTy &object_slots = mInfo->getObjectSlots(); 113 for (RSInfo::ObjectSlotListTy::const_iterator 114 slots_iter = object_slots.begin(), 115 slots_end = object_slots.end(); 116 slots_iter != slots_end; slots_iter++) { 117 if (*slots_iter) { 118 object_slot_numbers.push_back(i); 119 } 120 i++; 121 } 122 s << "objectSlotCount: " << (unsigned int) object_slot_numbers.size() 123 << "\n"; 124 for (i = 0; i < object_slot_numbers.size(); i++) { 125 s << object_slot_numbers[i] << "\n"; 126 } 127 128 s.flush(); 129 130 // Embed this as the global variable .rs.info so that it will be 131 // accessible from the shared object later. 132 llvm::Constant *Init = llvm::ConstantDataArray::getString(*C, str); 133 llvm::GlobalVariable *InfoGV = 134 new llvm::GlobalVariable(M, Init->getType(), true, 135 llvm::GlobalValue::ExternalLinkage, Init, 136 ".rs.info"); 137 (void) InfoGV; 138 139 return true; 140 } 141 142 virtual const char *getPassName() const { 143 return "Embed Renderscript Info"; 144 } 145 146}; // end RSEmbedInfoPass 147 148} // end anonymous namespace 149 150char RSEmbedInfoPass::ID = 0; 151 152namespace bcc { 153 154llvm::ModulePass * 155createRSEmbedInfoPass(const RSInfo *info) { 156 return new RSEmbedInfoPass(info); 157} 158 159} // end namespace bcc 160