1eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni/* 2eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * Copyright 2017, The Android Open Source Project 3eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * 4eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * Licensed under the Apache License, Version 2.0 (the "License"); 5eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * you may not use this file except in compliance with the License. 6eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * You may obtain a copy of the License at 7eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * 8eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * http://www.apache.org/licenses/LICENSE-2.0 9eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * 10eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * Unless required by applicable law or agreed to in writing, software 11eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * distributed under the License is distributed on an "AS IS" BASIS, 12eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * See the License for the specific language governing permissions and 14eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni * limitations under the License. 15eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni */ 16eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 17eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#ifndef RS2SPIRV_CONTEXT_H 18eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#define RS2SPIRV_CONTEXT_H 19eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 20c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung#include "RSAllocationUtils.h" 21eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#include "bcinfo/MetadataExtractor.h" 22eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 23eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#include "llvm/ADT/StringMap.h" 24eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#include "llvm/ADT/StringRef.h" 25eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 26eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#include <limits> 27bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung#include <stdint.h> 28eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#include <vector> 29eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 30eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// Declare a friend relationship in a class with a test. Used rather that 31eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// FRIEND_TEST to avoid globally importing gtest/gtest.h into the main 32eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// RSoV header files. 33eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#ifdef __HOST__ 34bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung#define RSOV_FRIEND_TEST(test_set_name, individual_test) \ 35bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung friend class test_set_name##_##individual_test##_Test 36eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#else 37eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#define RSOV_FRIEND_TEST(test_set_name, individual_test) 38bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung#endif // __HOST__ 39eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 40eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ninamespace bcinfo { 41eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Niclass MetadataExtractor; 42eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni} 43eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 44eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ninamespace llvm { 45eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Niclass Module; 46eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni} 47eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 48eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ninamespace rs2spirv { 49eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 50eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// A singleton that keeps state during the compilation from RS LLVM bitcode to 51eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// SPIR-V, which provides quick lookup of metadata and shares information 52eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni// between the passes. 53eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Niclass Context { 54eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni RSOV_FRIEND_TEST(ContextTest, testInitialize); 55eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 56eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Nipublic: 57eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni static Context &getInstance(); 58eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 59eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni Context(); 60eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 61eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Initialize the internal data struture such as the slot number lookup table, 62eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // etc. 63bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung bool Initialize(std::unique_ptr<bcinfo::MetadataExtractor> ME); 64eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 65eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Returns the total number of exported variables 66bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung uint32_t getNumExportVar() const { return mExportVarIndices.size(); } 67eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 68eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Adds the mapping from the slot number of an exported variable to the index 69eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // of its field in the global buffer 70eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni void addExportVarIndex(uint32_t slot, uint32_t index) { 71eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni mExportVarIndices[slot] = index; 72eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 73eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 74eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Adds the mapping from the name of an exported variable to the index of its 75eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // field in the global buffer 76eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni void addExportVarIndex(const char *varName, uint32_t index) { 77eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni const uint32_t slot = getSlotForExportVar(varName); 78eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni if (slot == std::numeric_limits<uint32_t>::max()) { 79eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni assert(0 && "Invalid name for an exported variable"); 80eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni return; 81eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 82eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni addExportVarIndex(slot, index); 83eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 84eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 85eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Given the slot number of an exported variable, returns the index of its 86eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // field in the global buffer 87eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni uint32_t getExportVarIndex(uint32_t slot) const { 88eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni return mExportVarIndices[slot]; 89eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 90eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 91eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Returns the total number of foreach kernels 92bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung uint32_t getNumForEachKernel() const { return mForEachNameToSlot.size(); } 93eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 94eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // Checks if a name refers to a foreach kernel function 95eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni bool isForEachKernel(llvm::StringRef name) const { 96eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni return mForEachNameToSlot.count(name) != 0; 97eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 98eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 99bbf0b0eac5b1aa65ded878d80a0adc83e48527c8I-Jui (Ray) Sung const bcinfo::MetadataExtractor &getMetadata() const { return *mMetadata; } 100eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 101c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung llvm::SmallVectorImpl<RSAllocationInfo> &getGlobalAllocs() { 102c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung return mGlobalAllocs; 103c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung } 104c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung 105eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Niprivate: 106eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni uint32_t getSlotForExportVar(const char *varName) { 107eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni const llvm::StringRef strVarName(varName); 108eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni auto it = mVarNameToSlot.find(strVarName); 109eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni if (it == mVarNameToSlot.end()) { 110eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni return std::numeric_limits<uint32_t>::max(); 111eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 112eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni return it->second; 113eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni } 114eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 115eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni bool mInitialized; 116eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // RenderScript metadata embedded in the input LLVM Moduel 117eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni std::unique_ptr<bcinfo::MetadataExtractor> mMetadata; 118eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // A map from exported variable names to their slot numbers 119eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni llvm::StringMap<uint32_t> mVarNameToSlot; 120eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // A map from exported foreach kernel names to their slot numbers 121eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni llvm::StringMap<uint32_t> mForEachNameToSlot; 122eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni // These are the indices for each exported variable in the global buffer 123eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni std::vector<uint32_t> mExportVarIndices; 124c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung // For Global Allocations; carries global variable -> metadata offset 125c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung // mapping from an LLVM pass to a SPIRIT pass 126c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung llvm::SmallVector<RSAllocationInfo, 8> mGlobalAllocs; 127eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni}; 128eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 129eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni} // namespace rs2spirv 130eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni 131eb6548743c40f4129ca55a58ff2d5254f22e95e1Yang Ni#endif // RS2SPIRV_CONTEXT_H 132