blob: a2c1c86044251524ae721dc5e1e6e52f3449ec18 [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 "llvm/IR/Constants.h"
16#include "llvm/IR/IRBuilder.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/Module.h"
19#include "llvm/Pass.h"
20#include "llvm/Transforms/Utils/Cloning.h"
21
22#include "clspv/AddressSpace.h"
23#include "clspv/Option.h"
24#include "clspv/PushConstant.h"
25
26#include "Constants.h"
27#include "Passes.h"
28#include "PushConstant.h"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "declarepushconstants"
33
34namespace {
35struct DeclarePushConstantsPass : public ModulePass {
36 static char ID;
37 DeclarePushConstantsPass() : ModulePass(ID) {}
38
Kévin Petit0936e292020-03-16 15:10:37 +000039 bool shouldDeclareDimensions(Module &M);
40 bool shouldDeclareEnqueuedLocalSize(Module &M);
41 bool shouldDeclareGlobalOffset(Module &M);
42
Kévin Petitbbbda972020-03-03 19:16:31 +000043 bool runOnModule(Module &M) override;
44};
45} // namespace
46
47char DeclarePushConstantsPass::ID = 0;
48INITIALIZE_PASS(DeclarePushConstantsPass, "DeclarePushConstants",
49 "Declare push constants", false, false)
50
51namespace clspv {
52ModulePass *createDeclarePushConstantsPass() {
53 return new DeclarePushConstantsPass();
54}
55} // namespace clspv
56
Kévin Petit0936e292020-03-16 15:10:37 +000057bool DeclarePushConstantsPass::shouldDeclareEnqueuedLocalSize(Module &M) {
58 bool isEnabled = ((clspv::Option::Language() ==
59 clspv::Option::SourceLanguage::OpenCL_C_20) ||
60 (clspv::Option::Language() ==
61 clspv::Option::SourceLanguage::OpenCL_CPP));
62 bool isUsed = M.getFunction("_Z23get_enqueued_local_sizej") != nullptr;
63 return isEnabled && isUsed;
64}
65
66bool DeclarePushConstantsPass::shouldDeclareGlobalOffset(Module &M) {
67 bool isEnabled = clspv::Option::GlobalOffset();
68 bool isUsed = (M.getFunction("_Z17get_global_offsetj") != nullptr) ||
69 (M.getFunction("_Z13get_global_idj") != nullptr);
70 return isEnabled && isUsed;
71}
72
Kévin Petitbbbda972020-03-03 19:16:31 +000073bool DeclarePushConstantsPass::runOnModule(Module &M) {
74
75 bool changed = false;
76
77 std::vector<clspv::PushConstant> PushConstants;
78
79 auto &C = M.getContext();
80
Kévin Petit0936e292020-03-16 15:10:37 +000081 if (shouldDeclareGlobalOffset(M)) {
Kévin Petitbbbda972020-03-03 19:16:31 +000082 PushConstants.emplace_back(clspv::PushConstant::GlobalOffset);
83 }
84
Kévin Petit0936e292020-03-16 15:10:37 +000085 if (shouldDeclareEnqueuedLocalSize(M)) {
Kévin Petit1af73be2020-03-11 17:53:44 +000086 PushConstants.push_back(clspv::PushConstant::EnqueuedLocalSize);
87 }
88
Kévin Petitbbbda972020-03-03 19:16:31 +000089 if (PushConstants.size() > 0) {
90 changed = true;
91
92 std::vector<Type *> Members;
93
94 for (auto &pc : PushConstants) {
95 Members.push_back(GetPushConstantType(M, pc));
96 }
97
98 auto STy = StructType::create(C, Members);
99
100 auto GV =
101 new GlobalVariable(M, STy, false, GlobalValue::ExternalLinkage, nullptr,
102 clspv::PushConstantsVariableName(), nullptr,
103 GlobalValue::ThreadLocalMode::NotThreadLocal,
104 clspv::AddressSpace::PushConstant);
105
106 GV->setInitializer(Constant::getNullValue(STy));
107
108 std::vector<llvm::Metadata *> MDArgs;
109 for (auto &pc : PushConstants) {
110 auto Cst =
111 ConstantInt::get(IntegerType::get(C, 32), static_cast<int>(pc));
112 MDArgs.push_back(llvm::ConstantAsMetadata::get(Cst));
113 };
114
115 GV->setMetadata(clspv::PushConstantsMetadataName(),
116 llvm::MDNode::get(C, MDArgs));
117 }
118
119 return changed;
120}