1 /* 2 * Copyright 2017, 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 #ifndef RS2SPIRV_CONTEXT_H 18 #define RS2SPIRV_CONTEXT_H 19 20 #include "RSAllocationUtils.h" 21 #include "bcinfo/MetadataExtractor.h" 22 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/ADT/StringRef.h" 25 26 #include <limits> 27 #include <stdint.h> 28 #include <vector> 29 30 // Declare a friend relationship in a class with a test. Used rather that 31 // FRIEND_TEST to avoid globally importing gtest/gtest.h into the main 32 // RSoV header files. 33 #ifdef __HOST__ 34 #define RSOV_FRIEND_TEST(test_set_name, individual_test) \ 35 friend class test_set_name##_##individual_test##_Test 36 #else 37 #define RSOV_FRIEND_TEST(test_set_name, individual_test) 38 #endif // __HOST__ 39 40 namespace bcinfo { 41 class MetadataExtractor; 42 } 43 44 namespace llvm { 45 class Module; 46 } 47 48 namespace rs2spirv { 49 50 // A singleton that keeps state during the compilation from RS LLVM bitcode to 51 // SPIR-V, which provides quick lookup of metadata and shares information 52 // between the passes. 53 class Context { 54 RSOV_FRIEND_TEST(ContextTest, testInitialize); 55 56 public: 57 static Context &getInstance(); 58 59 Context(); 60 61 // Initialize the internal data struture such as the slot number lookup table, 62 // etc. 63 bool Initialize(std::unique_ptr<bcinfo::MetadataExtractor> ME); 64 65 // Returns the total number of exported variables getNumExportVar()66 uint32_t getNumExportVar() const { return mExportVarIndices.size(); } 67 68 // Adds the mapping from the slot number of an exported variable to the index 69 // of its field in the global buffer addExportVarIndex(uint32_t slot,uint32_t index)70 void addExportVarIndex(uint32_t slot, uint32_t index) { 71 mExportVarIndices[slot] = index; 72 } 73 74 // Adds the mapping from the name of an exported variable to the index of its 75 // field in the global buffer addExportVarIndex(const char * varName,uint32_t index)76 void addExportVarIndex(const char *varName, uint32_t index) { 77 const uint32_t slot = getSlotForExportVar(varName); 78 if (slot == std::numeric_limits<uint32_t>::max()) { 79 assert(0 && "Invalid name for an exported variable"); 80 return; 81 } 82 addExportVarIndex(slot, index); 83 } 84 85 // Given the slot number of an exported variable, returns the index of its 86 // field in the global buffer getExportVarIndex(uint32_t slot)87 uint32_t getExportVarIndex(uint32_t slot) const { 88 return mExportVarIndices[slot]; 89 } 90 91 // Returns the total number of foreach kernels getNumForEachKernel()92 uint32_t getNumForEachKernel() const { return mForEachNameToSlot.size(); } 93 94 // Checks if a name refers to a foreach kernel function isForEachKernel(llvm::StringRef name)95 bool isForEachKernel(llvm::StringRef name) const { 96 return mForEachNameToSlot.count(name) != 0; 97 } 98 getMetadata()99 const bcinfo::MetadataExtractor &getMetadata() const { return *mMetadata; } 100 getGlobalAllocs()101 llvm::SmallVectorImpl<RSAllocationInfo> &getGlobalAllocs() { 102 return mGlobalAllocs; 103 } 104 105 private: getSlotForExportVar(const char * varName)106 uint32_t getSlotForExportVar(const char *varName) { 107 const llvm::StringRef strVarName(varName); 108 auto it = mVarNameToSlot.find(strVarName); 109 if (it == mVarNameToSlot.end()) { 110 return std::numeric_limits<uint32_t>::max(); 111 } 112 return it->second; 113 } 114 115 bool mInitialized; 116 // RenderScript metadata embedded in the input LLVM Moduel 117 std::unique_ptr<bcinfo::MetadataExtractor> mMetadata; 118 // A map from exported variable names to their slot numbers 119 llvm::StringMap<uint32_t> mVarNameToSlot; 120 // A map from exported foreach kernel names to their slot numbers 121 llvm::StringMap<uint32_t> mForEachNameToSlot; 122 // These are the indices for each exported variable in the global buffer 123 std::vector<uint32_t> mExportVarIndices; 124 // For Global Allocations; carries global variable -> metadata offset 125 // mapping from an LLVM pass to a SPIRIT pass 126 llvm::SmallVector<RSAllocationInfo, 8> mGlobalAllocs; 127 }; 128 129 } // namespace rs2spirv 130 131 #endif // RS2SPIRV_CONTEXT_H 132