File: IntrinsicsWrapper.cpp

package info (click to toggle)
intel-graphics-compiler2 2.22.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 107,676 kB
  • sloc: cpp: 809,645; lisp: 288,070; ansic: 16,397; python: 4,010; yacc: 2,588; lex: 1,666; pascal: 314; sh: 186; makefile: 38
file content (131 lines) | stat: -rw-r--r-- 4,447 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*========================== begin_copyright_notice ============================

Copyright (C) 2022-2024 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#include "vc/Utils/GenX/IntrinsicsWrapper.h"

using namespace llvm;

unsigned vc::getAnyIntrinsicID(const Function *F) {
  IGC_ASSERT(F);
  if (GenXIntrinsic::isGenXNonTrivialIntrinsic(F))
    return GenXIntrinsic::getGenXIntrinsicID(F);
  if (InternalIntrinsic::isInternalNonTrivialIntrinsic(F))
    return InternalIntrinsic::getInternalIntrinsicID(F);

  Intrinsic::ID IID = F->getIntrinsicID();
  // TODO: return the biggest constant from intrinsics ID
  // currently saved the expected behaviour
  // to make sure assert
  // ID != GenXIntrinsics::not_any_intrinsic
  // works right
  if (IID == Intrinsic::not_intrinsic)
    return GenXIntrinsic::not_any_intrinsic;
  return IID;
}

unsigned vc::getAnyIntrinsicID(const llvm::Value *V) {
  if (!V)
    return GenXIntrinsic::not_any_intrinsic;
  const CallInst *CI = dyn_cast<CallInst>(V);
  if (!CI)
    return GenXIntrinsic::not_any_intrinsic;
  Function *Callee = CI->getCalledFunction();
  // TODO: may be this is error?
  // nullptr = this is an indirect function
  // invocation or the function signature
  // does not match the call signature
  if (!Callee)
    return GenXIntrinsic::not_any_intrinsic;

  return getAnyIntrinsicID(Callee);
}

bool vc::isAnyVcIntrinsic(unsigned ID) {
  return InternalIntrinsic::isInternalNonTrivialIntrinsic(ID) ||
         GenXIntrinsic::isGenXNonTrivialIntrinsic(ID);
}

bool vc::isAnyVcIntrinsic(const Function *F) {
  return InternalIntrinsic::isInternalNonTrivialIntrinsic(F) ||
         GenXIntrinsic::isGenXNonTrivialIntrinsic(F);
}

bool vc::isAnyVcIntrinsic(const Value *V) {
  return InternalIntrinsic::isInternalNonTrivialIntrinsic(V) ||
         GenXIntrinsic::isGenXNonTrivialIntrinsic(V);
}

bool vc::isAnyNonTrivialIntrinsic(unsigned ID) {
  return InternalIntrinsic::isInternalNonTrivialIntrinsic(ID) ||
         GenXIntrinsic::isAnyNonTrivialIntrinsic(ID);
}

bool vc::isOverloadedRet(unsigned ID) {
  if (GenXIntrinsic::isGenXNonTrivialIntrinsic(ID))
    return GenXIntrinsic::isOverloadedRet(ID);
  if (vc::InternalIntrinsic::isInternalNonTrivialIntrinsic(ID))
    return vc::InternalIntrinsic::isOverloadedRet(ID);
  // Assume that LLVM intrinsics can only be overloaded by the return value
  // type.
  // FIXME: This is not true for all LLVM intrinsics.
  return Intrinsic::isOverloaded(ID);
}

bool vc::isOverloadedArg(unsigned ID, unsigned ArgumentNum) {
  if (GenXIntrinsic::isGenXNonTrivialIntrinsic(ID))
    return GenXIntrinsic::isOverloadedArg(ID, ArgumentNum);
  if (vc::InternalIntrinsic::isInternalNonTrivialIntrinsic(ID))
    return vc::InternalIntrinsic::isOverloadedArg(ID, ArgumentNum);
  return false;
}

Function *vc::getAnyDeclaration(Module *M, unsigned ID, ArrayRef<Type *> Tys) {
  if (GenXIntrinsic::isGenXNonTrivialIntrinsic(ID))
    return GenXIntrinsic::getGenXDeclaration(
        M, static_cast<llvm::GenXIntrinsic::ID>(ID), Tys);
  if (InternalIntrinsic::isInternalNonTrivialIntrinsic(ID))
    return InternalIntrinsic::getInternalDeclaration(
        M, static_cast<vc::InternalIntrinsic::ID>(ID), Tys);
  return Intrinsic::getDeclaration(M, static_cast<Intrinsic::ID>(ID), Tys);
}

std::string vc::getAnyName(unsigned Id, ArrayRef<Type *> Tys) {
  if (vc::InternalIntrinsic::isInternalIntrinsic(Id))
    return vc::InternalIntrinsic::getInternalName(
        static_cast<InternalIntrinsic::ID>(Id), Tys);
  return GenXIntrinsic::getAnyName(Id, Tys);
}

llvm::Function *
vc::getAnyDeclarationForArgs(llvm::Module *M, unsigned ID, Type *RetTy,
                             llvm::ArrayRef<llvm::Value *> Args) {
  SmallVector<Type *, 8> Tys;

  if (vc::isOverloadedRet(ID))
    Tys.push_back(RetTy);

  for (auto &ArgIdx : llvm::enumerate(Args))
    if (vc::isOverloadedArg(ID, ArgIdx.index()))
      Tys.push_back(ArgIdx.value()->getType());

  return vc::getAnyDeclaration(M, ID, Tys);
}

bool vc::isAbsIntrinsic(unsigned ID) {
  if (ID == Intrinsic::fabs)
    return true;
  return GenXIntrinsic::isAbs(ID);
}

int vc::getTwoAddrOpIndex(CallInst *CI) {
  if (InternalIntrinsic::isInternalNonTrivialIntrinsic(CI))
    return InternalIntrinsic::getTwoAddrOpIndex(CI);
  if (GenXIntrinsic::isGenXNonTrivialIntrinsic(CI))
    return CI->arg_size() - 1;
  return -1;
}