blob: 32c931d37a6a92b5360833b4d253715c69931901 [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";
Kévin Petit1af73be2020-03-11 17:53:44 +000037 case PushConstant::EnqueuedLocalSize:
38 return "enqueued_local_size";
Kévin Petitbbbda972020-03-03 19:16:31 +000039 }
40 llvm_unreachable("Unknown PushConstant in GetPushConstantName");
41 return "";
42}
43
44Type *GetPushConstantType(Module &M, PushConstant pc) {
45 auto &C = M.getContext();
46 switch (pc) {
47 case PushConstant::Dimensions:
48 return IntegerType::get(C, 32);
49 case PushConstant::GlobalOffset:
50 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petit1af73be2020-03-11 17:53:44 +000051 case PushConstant::EnqueuedLocalSize:
52 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petitbbbda972020-03-03 19:16:31 +000053 }
54 llvm_unreachable("Unknown PushConstant in GetPushConstantType");
55 return nullptr;
56}
57
58Value *GetPushConstantPointer(BasicBlock *BB, PushConstant pc) {
59 auto M = BB->getParent()->getParent();
60
61 // Get variable
62 auto GV = M->getGlobalVariable(clspv::PushConstantsVariableName());
63 assert(GV && "Push constants requested but none are declared.");
64
65 // Find requested pc in metadata
66 auto MD = GV->getMetadata(clspv::PushConstantsMetadataName());
67 bool found = false;
68 uint32_t idx = 0;
69 for (auto &PCMD : MD->operands()) {
70 auto mpc = static_cast<PushConstant>(
71 mdconst::extract<ConstantInt>(PCMD)->getZExtValue());
72 if (mpc == pc) {
73 found = true;
74 break;
75 }
76 idx++;
77 }
78
79 // Assert that it exists
80 assert(found && "Push constant wasn't declared.");
81
82 // Construct pointer
83 IRBuilder<> Builder(BB);
84 Value *Indices[] = {Builder.getInt32(0), Builder.getInt32(idx)};
85 return Builder.CreateInBoundsGEP(GV, Indices);
86}
87
88} // namespace clspv