blob: 6e63df0ef5360806f8bdaa3aa1a2bb9af7e0ac90 [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
39 bool runOnModule(Module &M) override;
40};
41} // namespace
42
43char DeclarePushConstantsPass::ID = 0;
44INITIALIZE_PASS(DeclarePushConstantsPass, "DeclarePushConstants",
45 "Declare push constants", false, false)
46
47namespace clspv {
48ModulePass *createDeclarePushConstantsPass() {
49 return new DeclarePushConstantsPass();
50}
51} // namespace clspv
52
53bool DeclarePushConstantsPass::runOnModule(Module &M) {
54
55 bool changed = false;
56
57 std::vector<clspv::PushConstant> PushConstants;
58
59 auto &C = M.getContext();
60
61 if (clspv::Option::GlobalOffset()) {
62 PushConstants.emplace_back(clspv::PushConstant::GlobalOffset);
63 }
64
Kévin Petit1af73be2020-03-11 17:53:44 +000065 if ((clspv::Option::Language() ==
66 clspv::Option::SourceLanguage::OpenCL_C_20) ||
67 (clspv::Option::Language() ==
68 clspv::Option::SourceLanguage::OpenCL_CPP)) {
69 PushConstants.push_back(clspv::PushConstant::EnqueuedLocalSize);
70 }
71
Kévin Petitbbbda972020-03-03 19:16:31 +000072 if (clspv::Option::WorkDim()) {
73 PushConstants.push_back(clspv::PushConstant::Dimensions);
74 }
75
76 if (PushConstants.size() > 0) {
77 changed = true;
78
79 std::vector<Type *> Members;
80
81 for (auto &pc : PushConstants) {
82 Members.push_back(GetPushConstantType(M, pc));
83 }
84
85 auto STy = StructType::create(C, Members);
86
87 auto GV =
88 new GlobalVariable(M, STy, false, GlobalValue::ExternalLinkage, nullptr,
89 clspv::PushConstantsVariableName(), nullptr,
90 GlobalValue::ThreadLocalMode::NotThreadLocal,
91 clspv::AddressSpace::PushConstant);
92
93 GV->setInitializer(Constant::getNullValue(STy));
94
95 std::vector<llvm::Metadata *> MDArgs;
96 for (auto &pc : PushConstants) {
97 auto Cst =
98 ConstantInt::get(IntegerType::get(C, 32), static_cast<int>(pc));
99 MDArgs.push_back(llvm::ConstantAsMetadata::get(Cst));
100 };
101
102 GV->setMetadata(clspv::PushConstantsMetadataName(),
103 llvm::MDNode::get(C, MDArgs));
104 }
105
106 return changed;
107}