blob: c81dbea6c98365f9ed55b5476d6e9aa5f9f19922 [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
42 // Create a function in the module
43 auto M = Insert->getModule();
44 auto Int32Ty = Type::getInt32Ty(M->getContext());
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040045 SmallVector<Type *, 8> ArgTypes = {Int32Ty};
Kévin Petit617a76d2019-04-04 13:54:16 +010046 for (auto Arg : Args) {
47 ArgTypes.push_back(Arg->getType());
48 }
49 auto NewFType = FunctionType::get(RetType, ArgTypes, false);
50 auto NewFTyC = M->getOrInsertFunction(MangledName, NewFType);
51 auto NewF = cast<Function>(NewFTyC.getCallee());
52 for (auto A : Attributes) {
53 NewF->addFnAttr(A);
54 }
55
56 // Now call it with the values we were passed
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040057 SmallVector<Value *, 8> ArgValues = {ConstantInt::get(Int32Ty, Opcode)};
Kévin Petit617a76d2019-04-04 13:54:16 +010058 for (auto Arg : Args) {
59 ArgValues.push_back(Arg);
60 }
61
62 return CallInst::Create(NewF, ArgValues, "", Insert);
63}
64
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040065}; // namespace clspv