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