blob: 883427b504e6affa249b63443ea6a44eaf7a78c2 [file] [log] [blame]
Kévin Petit617a76d2019-04-04 13:54:16 +01001// Copyright 2019 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 "SPIRVOp.h"
16
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/IR/Instructions.h"
20#include "llvm/IR/Module.h"
21
SJW61531372020-06-09 07:31:08 -050022#include "Builtins.h"
Kévin Petit617a76d2019-04-04 13:54:16 +010023#include "Constants.h"
24
25namespace clspv {
26
27using namespace llvm;
28
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040029Instruction *InsertSPIRVOp(Instruction *Insert, spv::Op Opcode,
Kévin Petit617a76d2019-04-04 13:54:16 +010030 ArrayRef<Attribute::AttrKind> Attributes,
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040031 Type *RetType, ArrayRef<Value *> Args) {
Kévin Petit617a76d2019-04-04 13:54:16 +010032
33 // Prepare mangled name
34 std::string MangledName = clspv::SPIRVOpIntrinsicFunction();
SJW61531372020-06-09 07:31:08 -050035 MangledName += ".";
Kévin Petit617a76d2019-04-04 13:54:16 +010036 MangledName += std::to_string(Opcode);
37 MangledName += ".";
38 for (auto Arg : Args) {
SJW61531372020-06-09 07:31:08 -050039 MangledName += Builtins::GetMangledTypeName(Arg->getType());
Kévin Petit617a76d2019-04-04 13:54:16 +010040 }
41
Kévin Petit617a76d2019-04-04 13:54:16 +010042 auto M = Insert->getModule();
43 auto Int32Ty = Type::getInt32Ty(M->getContext());
alan-baker5f2e88e2020-12-07 15:24:04 -050044 Function *func = M->getFunction(MangledName);
45 if (!func) {
46 // Create a function in the module
47 SmallVector<Type *, 8> ArgTypes = {Int32Ty};
48 for (auto Arg : Args) {
49 ArgTypes.push_back(Arg->getType());
50 }
51 auto NewFType = FunctionType::get(RetType, ArgTypes, false);
52 auto NewFTyC = M->getOrInsertFunction(MangledName, NewFType);
53 func = cast<Function>(NewFTyC.getCallee());
54 for (auto A : Attributes) {
55 func->addFnAttr(A);
56 }
Kévin Petit617a76d2019-04-04 13:54:16 +010057 }
58
59 // Now call it with the values we were passed
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040060 SmallVector<Value *, 8> ArgValues = {ConstantInt::get(Int32Ty, Opcode)};
Kévin Petit617a76d2019-04-04 13:54:16 +010061 for (auto Arg : Args) {
62 ArgValues.push_back(Arg);
63 }
64
alan-baker5f2e88e2020-12-07 15:24:04 -050065 return CallInst::Create(func, ArgValues, "", Insert);
Kévin Petit617a76d2019-04-04 13:54:16 +010066}
67
Marco Antognini7e338402021-03-15 12:48:37 +000068} // namespace clspv