blob: 2426ae306ac2871a52629167b2082479393d665d [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 Petit21c23c62020-04-29 01:38:28 +010039 case PushConstant::GlobalSize:
40 return "global_size";
41 case PushConstant::RegionOffset:
42 return "region_offset";
43 case PushConstant::NumWorkgroups:
44 return "num_workgroups";
45 case PushConstant::RegionGroupOffset:
46 return "region_group_offset";
Kévin Petitbbbda972020-03-03 19:16:31 +000047 }
48 llvm_unreachable("Unknown PushConstant in GetPushConstantName");
49 return "";
50}
51
52Type *GetPushConstantType(Module &M, PushConstant pc) {
53 auto &C = M.getContext();
54 switch (pc) {
55 case PushConstant::Dimensions:
56 return IntegerType::get(C, 32);
57 case PushConstant::GlobalOffset:
58 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petit1af73be2020-03-11 17:53:44 +000059 case PushConstant::EnqueuedLocalSize:
60 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petit21c23c62020-04-29 01:38:28 +010061 case PushConstant::GlobalSize:
62 return VectorType::get(IntegerType::get(C, 32), 3);
63 case PushConstant::RegionOffset:
64 return VectorType::get(IntegerType::get(C, 32), 3);
65 case PushConstant::NumWorkgroups:
66 return VectorType::get(IntegerType::get(C, 32), 3);
67 case PushConstant::RegionGroupOffset:
68 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petitbbbda972020-03-03 19:16:31 +000069 }
70 llvm_unreachable("Unknown PushConstant in GetPushConstantType");
71 return nullptr;
72}
73
74Value *GetPushConstantPointer(BasicBlock *BB, PushConstant pc) {
75 auto M = BB->getParent()->getParent();
76
77 // Get variable
78 auto GV = M->getGlobalVariable(clspv::PushConstantsVariableName());
79 assert(GV && "Push constants requested but none are declared.");
80
81 // Find requested pc in metadata
82 auto MD = GV->getMetadata(clspv::PushConstantsMetadataName());
83 bool found = false;
84 uint32_t idx = 0;
85 for (auto &PCMD : MD->operands()) {
86 auto mpc = static_cast<PushConstant>(
87 mdconst::extract<ConstantInt>(PCMD)->getZExtValue());
88 if (mpc == pc) {
89 found = true;
90 break;
91 }
92 idx++;
93 }
94
95 // Assert that it exists
96 assert(found && "Push constant wasn't declared.");
97
98 // Construct pointer
99 IRBuilder<> Builder(BB);
100 Value *Indices[] = {Builder.getInt32(0), Builder.getInt32(idx)};
101 return Builder.CreateInBoundsGEP(GV, Indices);
102}
103
104} // namespace clspv