blob: 9bf8b7c95ba979f8caff1ce4f7da109ca3a00c79 [file] [log] [blame]
Kévin Petitbbbda972020-03-03 19:16:31 +00001// Copyright 2020 The Clspv Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "PushConstant.h"
16
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/Function.h"
19#include "llvm/IR/IRBuilder.h"
20#include "llvm/IR/Metadata.h"
21#include "llvm/IR/Module.h"
22#include "llvm/IR/Type.h"
23#include "llvm/Support/ErrorHandling.h"
24
25#include "Constants.h"
26
27using namespace llvm;
28
29namespace clspv {
30
31const char *GetPushConstantName(PushConstant pc) {
32 switch (pc) {
33 case PushConstant::Dimensions:
34 return "dimensions";
35 case PushConstant::GlobalOffset:
36 return "global_offset";
37 }
38 llvm_unreachable("Unknown PushConstant in GetPushConstantName");
39 return "";
40}
41
42Type *GetPushConstantType(Module &M, PushConstant pc) {
43 auto &C = M.getContext();
44 switch (pc) {
45 case PushConstant::Dimensions:
46 return IntegerType::get(C, 32);
47 case PushConstant::GlobalOffset:
48 return VectorType::get(IntegerType::get(C, 32), 3);
49 }
50 llvm_unreachable("Unknown PushConstant in GetPushConstantType");
51 return nullptr;
52}
53
54Value *GetPushConstantPointer(BasicBlock *BB, PushConstant pc) {
55 auto M = BB->getParent()->getParent();
56
57 // Get variable
58 auto GV = M->getGlobalVariable(clspv::PushConstantsVariableName());
59 assert(GV && "Push constants requested but none are declared.");
60
61 // Find requested pc in metadata
62 auto MD = GV->getMetadata(clspv::PushConstantsMetadataName());
63 bool found = false;
64 uint32_t idx = 0;
65 for (auto &PCMD : MD->operands()) {
66 auto mpc = static_cast<PushConstant>(
67 mdconst::extract<ConstantInt>(PCMD)->getZExtValue());
68 if (mpc == pc) {
69 found = true;
70 break;
71 }
72 idx++;
73 }
74
75 // Assert that it exists
76 assert(found && "Push constant wasn't declared.");
77
78 // Construct pointer
79 IRBuilder<> Builder(BB);
80 Value *Indices[] = {Builder.getInt32(0), Builder.getInt32(idx)};
81 return Builder.CreateInBoundsGEP(GV, Indices);
82}
83
84} // namespace clspv