blob: 64e0ee12fea232d54b0f9c530fda5ec078cfdf6a [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
alan-bakerc4579bb2020-04-29 14:15:50 -040025#include "clspv/Option.h"
26
Kévin Petitbbbda972020-03-03 19:16:31 +000027#include "Constants.h"
28
29using namespace llvm;
30
31namespace clspv {
32
33const char *GetPushConstantName(PushConstant pc) {
34 switch (pc) {
35 case PushConstant::Dimensions:
36 return "dimensions";
37 case PushConstant::GlobalOffset:
38 return "global_offset";
Kévin Petit1af73be2020-03-11 17:53:44 +000039 case PushConstant::EnqueuedLocalSize:
40 return "enqueued_local_size";
Kévin Petit21c23c62020-04-29 01:38:28 +010041 case PushConstant::GlobalSize:
42 return "global_size";
43 case PushConstant::RegionOffset:
44 return "region_offset";
45 case PushConstant::NumWorkgroups:
46 return "num_workgroups";
47 case PushConstant::RegionGroupOffset:
48 return "region_group_offset";
Kévin Petitbbbda972020-03-03 19:16:31 +000049 }
50 llvm_unreachable("Unknown PushConstant in GetPushConstantName");
51 return "";
52}
53
54Type *GetPushConstantType(Module &M, PushConstant pc) {
55 auto &C = M.getContext();
56 switch (pc) {
57 case PushConstant::Dimensions:
58 return IntegerType::get(C, 32);
59 case PushConstant::GlobalOffset:
60 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petit1af73be2020-03-11 17:53:44 +000061 case PushConstant::EnqueuedLocalSize:
62 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petit21c23c62020-04-29 01:38:28 +010063 case PushConstant::GlobalSize:
64 return VectorType::get(IntegerType::get(C, 32), 3);
65 case PushConstant::RegionOffset:
66 return VectorType::get(IntegerType::get(C, 32), 3);
67 case PushConstant::NumWorkgroups:
68 return VectorType::get(IntegerType::get(C, 32), 3);
69 case PushConstant::RegionGroupOffset:
70 return VectorType::get(IntegerType::get(C, 32), 3);
Kévin Petitbbbda972020-03-03 19:16:31 +000071 }
72 llvm_unreachable("Unknown PushConstant in GetPushConstantType");
73 return nullptr;
74}
75
76Value *GetPushConstantPointer(BasicBlock *BB, PushConstant pc) {
77 auto M = BB->getParent()->getParent();
78
79 // Get variable
80 auto GV = M->getGlobalVariable(clspv::PushConstantsVariableName());
81 assert(GV && "Push constants requested but none are declared.");
82
83 // Find requested pc in metadata
84 auto MD = GV->getMetadata(clspv::PushConstantsMetadataName());
85 bool found = false;
86 uint32_t idx = 0;
87 for (auto &PCMD : MD->operands()) {
88 auto mpc = static_cast<PushConstant>(
89 mdconst::extract<ConstantInt>(PCMD)->getZExtValue());
90 if (mpc == pc) {
91 found = true;
92 break;
93 }
94 idx++;
95 }
96
97 // Assert that it exists
98 assert(found && "Push constant wasn't declared.");
99
100 // Construct pointer
101 IRBuilder<> Builder(BB);
102 Value *Indices[] = {Builder.getInt32(0), Builder.getInt32(idx)};
103 return Builder.CreateInBoundsGEP(GV, Indices);
104}
105
alan-bakerc4579bb2020-04-29 14:15:50 -0400106bool UsesGlobalPushConstants(Module &M) {
107 return clspv::Option::NonUniformNDRangeSupported() ||
alan-bakere1996972020-05-04 08:38:12 -0400108 ShouldDeclareGlobalOffsetPushConstant(M);
alan-bakerc4579bb2020-04-29 14:15:50 -0400109}
110
alan-bakere1996972020-05-04 08:38:12 -0400111bool ShouldDeclareGlobalOffsetPushConstant(Module &M) {
112 bool isEnabled = (clspv::Option::GlobalOffset() &&
113 clspv::Option::NonUniformNDRangeSupported()) ||
114 clspv::Option::GlobalOffsetPushConstant();
alan-bakerc4579bb2020-04-29 14:15:50 -0400115 bool isUsed = (M.getFunction("_Z17get_global_offsetj") != nullptr) ||
116 (M.getFunction("_Z13get_global_idj") != nullptr);
117 return isEnabled && isUsed;
118}
119
Kévin Petitbbbda972020-03-03 19:16:31 +0000120} // namespace clspv