blob: 6f6e9dbb86e89e9a3b8ae3c90873f1cf5f10bf9c [file] [log] [blame]
Stephen Hines86a0b792012-11-06 20:04:47 -08001/*
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>
Stephen Hines0116d8b2012-12-12 20:48:15 -080021#include <vector>
Stephen Hines86a0b792012-11-06 20:04:47 -080022
Stephen Hinesb730e232013-01-09 15:31:36 -080023#include <llvm/IR/DerivedTypes.h>
24#include <llvm/IR/Function.h>
25#include <llvm/IR/Instructions.h>
26#include <llvm/IR/IRBuilder.h>
27#include <llvm/IR/Module.h>
Stephen Hines86a0b792012-11-06 20:04:47 -080028#include <llvm/Pass.h>
29#include <llvm/Support/raw_ostream.h>
Stephen Hinesb730e232013-01-09 15:31:36 -080030#include <llvm/IR/Type.h>
Stephen Hines86a0b792012-11-06 20:04:47 -080031
32#include "bcc/Config/Config.h"
33#include "bcc/Renderscript/RSInfo.h"
34#include "bcc/Support/Log.h"
35
36using namespace bcc;
37
38namespace {
39
40/* RSForEachExpandPass - This pass operates on functions that are able to be
41 * called via rsForEach() or "foreach_<NAME>". We create an inner loop for the
42 * ForEach-able function to be invoked over the appropriate data cells of the
43 * input/output allocations (adjusting other relevant parameters as we go). We
44 * support doing this for any ForEach-able compute kernels. The new function
45 * name is the original function name followed by ".expand". Note that we
46 * still generate code for the original function.
47 */
48class RSEmbedInfoPass : public llvm::ModulePass {
49private:
50 static char ID;
51
52 llvm::Module *M;
53 llvm::LLVMContext *C;
54
55 const RSInfo *mInfo;
56
57public:
58 RSEmbedInfoPass(const RSInfo *info)
59 : ModulePass(ID),
60 mInfo(info) {
61 }
62
63 virtual bool runOnModule(llvm::Module &M) {
64 this->M = &M;
65 C = &M.getContext();
66
67 std::string str;
68 llvm::raw_string_ostream s(str);
69
70 // We use a simple text format here that the compatibility library can
71 // easily parse. Each section starts out with its name followed by a count.
72 // The count denotes the number of lines to parse for that particular
73 // category. Variables and Functions merely put the appropriate identifier
74 // on the line, while ForEach kernels have the encoded int signature,
75 // followed by a hyphen followed by the identifier (function to look up).
76 // Object Slots are just listed as one integer per line.
77 const RSInfo::ExportVarNameListTy &export_vars = mInfo->getExportVarNames();
78 s << "exportVarCount: " << (unsigned int) export_vars.size() << "\n";
79 for (RSInfo::ExportVarNameListTy::const_iterator
80 export_var_iter = export_vars.begin(),
81 export_var_end = export_vars.end();
82 export_var_iter != export_var_end; export_var_iter++) {
83 s << *export_var_iter << "\n";
84 }
85
86 const RSInfo::ExportFuncNameListTy &export_funcs =
87 mInfo->getExportFuncNames();
88 s << "exportFuncCount: " << (unsigned int) export_funcs.size() << "\n";
89 for (RSInfo::ExportFuncNameListTy::const_iterator
90 export_func_iter = export_funcs.begin(),
91 export_func_end = export_funcs.end();
92 export_func_iter != export_func_end; export_func_iter++) {
93 s << *export_func_iter << "\n";
94 }
95
96 const RSInfo::ExportForeachFuncListTy &export_foreach_funcs =
97 mInfo->getExportForeachFuncs();
98 s << "exportForEachCount: "
99 << (unsigned int) export_foreach_funcs.size() << "\n";
100 for (RSInfo::ExportForeachFuncListTy::const_iterator
101 foreach_func_iter = export_foreach_funcs.begin(),
102 foreach_func_end = export_foreach_funcs.end();
103 foreach_func_iter != foreach_func_end; foreach_func_iter++) {
104 std::string name(foreach_func_iter->first);
105 s << foreach_func_iter->second << " - "
106 << foreach_func_iter->first << "\n";
107 }
108
Stephen Hines0116d8b2012-12-12 20:48:15 -0800109 std::vector<unsigned int> object_slot_numbers;
110 unsigned int i = 0;
Stephen Hines86a0b792012-11-06 20:04:47 -0800111 const RSInfo::ObjectSlotListTy &object_slots = mInfo->getObjectSlots();
Stephen Hines86a0b792012-11-06 20:04:47 -0800112 for (RSInfo::ObjectSlotListTy::const_iterator
113 slots_iter = object_slots.begin(),
114 slots_end = object_slots.end();
115 slots_iter != slots_end; slots_iter++) {
Stephen Hines0116d8b2012-12-12 20:48:15 -0800116 if (*slots_iter) {
117 object_slot_numbers.push_back(i);
118 }
119 i++;
120 }
121 s << "objectSlotCount: " << (unsigned int) object_slot_numbers.size()
122 << "\n";
123 for (i = 0; i < object_slot_numbers.size(); i++) {
124 s << object_slot_numbers[i] << "\n";
Stephen Hines86a0b792012-11-06 20:04:47 -0800125 }
126
127 s.flush();
128
129 // Embed this as the global variable .rs.info so that it will be
130 // accessible from the shared object later.
131 llvm::Constant *Init = llvm::ConstantDataArray::getString(*C, str);
132 llvm::GlobalVariable *InfoGV =
133 new llvm::GlobalVariable(M, Init->getType(), true,
134 llvm::GlobalValue::ExternalLinkage, Init,
135 ".rs.info");
136 (void) InfoGV;
137
138 return true;
139 }
140
141 virtual const char *getPassName() const {
142 return "Embed Renderscript Info";
143 }
144
145}; // end RSEmbedInfoPass
146
147} // end anonymous namespace
148
149char RSEmbedInfoPass::ID = 0;
150
151namespace bcc {
152
153llvm::ModulePass *
154createRSEmbedInfoPass(const RSInfo *info) {
155 return new RSEmbedInfoPass(info);
156}
157
158} // end namespace bcc