RSCompiler.cpp revision 25eb586bb055ae07c7e82a2b1bdbd6936641580c
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/Renderscript/RSCompiler.h" 18 19#include <llvm/IR/Module.h> 20#include <llvm/PassManager.h> 21#include <llvm/Transforms/IPO.h> 22 23#include "bcc/Assert.h" 24#include "bcc/Renderscript/RSExecutable.h" 25#include "bcc/Renderscript/RSScript.h" 26#include "bcc/Renderscript/RSTransforms.h" 27#include "bcc/Source.h" 28#include "bcc/Support/Log.h" 29#include "bcinfo/MetadataExtractor.h" 30 31using namespace bcc; 32 33bool RSCompiler::addInternalizeSymbolsPass(Script &pScript, llvm::PassManager &pPM) { 34 // Add a pass to internalize the symbols that don't need to have global 35 // visibility. 36 RSScript &script = static_cast<RSScript &>(pScript); 37 llvm::Module &module = script.getSource().getModule(); 38 bcinfo::MetadataExtractor me(&module); 39 if (!me.extract()) { 40 bccAssert(false && "Could not extract metadata for module!"); 41 return false; 42 } 43 44 // The vector contains the symbols that should not be internalized. 45 std::vector<const char *> export_symbols; 46 47 // Special RS functions should always be global symbols. 48 const char **special_functions = RSExecutable::SpecialFunctionNames; 49 while (*special_functions != NULL) { 50 export_symbols.push_back(*special_functions); 51 special_functions++; 52 } 53 54 // Visibility of symbols appeared in rs_export_var and rs_export_func should 55 // also be preserved. 56 size_t exportVarCount = me.getExportVarCount(); 57 size_t exportFuncCount = me.getExportFuncCount(); 58 size_t exportForEachCount = me.getExportForEachSignatureCount(); 59 const char **exportVarNameList = me.getExportVarNameList(); 60 const char **exportFuncNameList = me.getExportFuncNameList(); 61 const char **exportForEachNameList = me.getExportForEachNameList(); 62 size_t i; 63 64 for (i = 0; i < exportVarCount; ++i) { 65 export_symbols.push_back(exportVarNameList[i]); 66 } 67 68 for (i = 0; i < exportFuncCount; ++i) { 69 export_symbols.push_back(exportFuncNameList[i]); 70 } 71 72 // Expanded foreach functions should not be internalized, too. 73 // expanded_foreach_funcs keeps the .expand version of the kernel names 74 // around until createInternalizePass() is finished making its own 75 // copy of the visible symbols. 76 std::vector<std::string> expanded_foreach_funcs; 77 for (i = 0; i < exportForEachCount; ++i) { 78 expanded_foreach_funcs.push_back( 79 std::string(exportForEachNameList[i]) + ".expand"); 80 export_symbols.push_back(expanded_foreach_funcs[i].c_str()); 81 } 82 pPM.add(llvm::createInternalizePass(export_symbols)); 83 84 return true; 85} 86 87bool RSCompiler::addExpandForEachPass(Script &pScript, llvm::PassManager &pPM) { 88 // Script passed to RSCompiler must be a RSScript. 89 RSScript &script = static_cast<RSScript &>(pScript); 90 91 // Expand ForEach on CPU path to reduce launch overhead. 92 bool pEnableStepOpt = true; 93 pPM.add(createRSForEachExpandPass(pEnableStepOpt)); 94 if (script.getEmbedInfo()) 95 pPM.add(createRSEmbedInfoPass()); 96 97 return true; 98} 99 100bool RSCompiler::beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM) { 101 if (!addExpandForEachPass(pScript, pPM)) 102 return false; 103 104 if (!addInternalizeSymbolsPass(pScript, pPM)) 105 return false; 106 107 return true; 108} 109