blob: 8e3471bd20835ced0f153fc9329e7a61ad3b4a5a [file] [log] [blame]
Matt Arsenaultc791f392014-06-23 18:00:31 +00001//===- AMDGPUIntrinsicInfo.cpp - AMDGPU Intrinsic Information ---*- C++ -*-===//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//==-----------------------------------------------------------------------===//
9//
10/// \file
11/// \brief AMDGPU Implementation of the IntrinsicInfo class.
12//
13//===-----------------------------------------------------------------------===//
14
Matt Arsenaultc791f392014-06-23 18:00:31 +000015#include "AMDGPUIntrinsicInfo.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000016#include "AMDGPUSubtarget.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/DerivedTypes.h"
18#include "llvm/IR/Intrinsics.h"
19#include "llvm/IR/Module.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000020
21using namespace llvm;
22
Eric Christopherac4b69e2014-07-25 22:22:39 +000023AMDGPUIntrinsicInfo::AMDGPUIntrinsicInfo()
Matt Arsenaultc791f392014-06-23 18:00:31 +000024 : TargetIntrinsicInfo() {}
Tom Stellard75aadc22012-12-11 21:25:42 +000025
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000026static const char *const IntrinsicNameTable[] = {
Tom Stellard75aadc22012-12-11 21:25:42 +000027#define GET_INTRINSIC_NAME_TABLE
28#include "AMDGPUGenIntrinsics.inc"
29#undef GET_INTRINSIC_NAME_TABLE
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000030};
Tom Stellard75aadc22012-12-11 21:25:42 +000031
Matt Arsenaulta1fe17c2016-07-19 23:16:53 +000032namespace {
33#define GET_INTRINSIC_ATTRIBUTES
34#include "AMDGPUGenIntrinsics.inc"
35#undef GET_INTRINSIC_ATTRIBUTES
36}
37
38StringRef AMDGPUIntrinsicInfo::getName(unsigned IntrID,
39 ArrayRef<Type *> Tys) const {
40 if (IntrID < Intrinsic::num_intrinsics)
41 return StringRef();
42
Matt Arsenaultc791f392014-06-23 18:00:31 +000043 assert(IntrID < AMDGPUIntrinsic::num_AMDGPU_intrinsics &&
44 "Invalid intrinsic ID");
Tom Stellard75aadc22012-12-11 21:25:42 +000045
Matt Arsenaulta1fe17c2016-07-19 23:16:53 +000046 return IntrinsicNameTable[IntrID - Intrinsic::num_intrinsics];
47}
48
49std::string AMDGPUIntrinsicInfo::getName(unsigned IntrID, Type **Tys,
50 unsigned NumTys) const {
51 return getName(IntrID, makeArrayRef(Tys, NumTys)).str();
52}
53
54FunctionType *AMDGPUIntrinsicInfo::getType(LLVMContext &Context, unsigned ID,
55 ArrayRef<Type*> Tys) const {
56 // FIXME: Re-use Intrinsic::getType machinery
57 switch (ID) {
58 case AMDGPUIntrinsic::amdgcn_fdiv_fast: {
59 Type *F32Ty = Type::getFloatTy(Context);
60 return FunctionType::get(F32Ty, { F32Ty, F32Ty }, false);
61 }
62 default:
63 llvm_unreachable("unhandled intrinsic");
64 }
Tom Stellard75aadc22012-12-11 21:25:42 +000065}
66
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000067unsigned AMDGPUIntrinsicInfo::lookupName(const char *NameData,
Matt Arsenaultc791f392014-06-23 18:00:31 +000068 unsigned Len) const {
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000069 StringRef Name(NameData, Len);
70 if (!Name.startswith("llvm."))
Rafael Espindolaebd8e382013-05-22 14:57:42 +000071 return 0; // All intrinsics start with 'llvm.'
72
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000073 // Look for a name match in our table. If the intrinsic is not overloaded,
74 // require an exact match. If it is overloaded, require a prefix match. The
75 // AMDGPU enum enum starts at Intrinsic::num_intrinsics.
76 int Idx = Intrinsic::lookupLLVMIntrinsicByName(IntrinsicNameTable, Name);
77 if (Idx >= 0) {
78 bool IsPrefixMatch = Name.size() > strlen(IntrinsicNameTable[Idx]);
79 return IsPrefixMatch == isOverloaded(Idx + 1)
80 ? Intrinsic::num_intrinsics + Idx
81 : 0;
Tom Stellard75aadc22012-12-11 21:25:42 +000082 }
Reid Kleckner1c93b4c2016-01-26 23:01:21 +000083
Reid Kleckner5b463712016-01-27 01:43:12 +000084 return 0;
Tom Stellard75aadc22012-12-11 21:25:42 +000085}
86
Matt Arsenaultc791f392014-06-23 18:00:31 +000087bool AMDGPUIntrinsicInfo::isOverloaded(unsigned id) const {
88// Overload Table
Tom Stellard75aadc22012-12-11 21:25:42 +000089#define GET_INTRINSIC_OVERLOAD_TABLE
90#include "AMDGPUGenIntrinsics.inc"
91#undef GET_INTRINSIC_OVERLOAD_TABLE
92}
93
Matt Arsenaultc791f392014-06-23 18:00:31 +000094Function *AMDGPUIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
Matt Arsenaulta1fe17c2016-07-19 23:16:53 +000095 ArrayRef<Type *> Tys) const {
96 FunctionType *FTy = getType(M->getContext(), IntrID, Tys);
97 Function *F
98 = cast<Function>(M->getOrInsertFunction(getName(IntrID, Tys), FTy));
99
100 AttributeSet AS = getAttributes(M->getContext(),
101 static_cast<AMDGPUIntrinsic::ID>(IntrID));
102 F->setAttributes(AS);
103 return F;
104}
105
106Function *AMDGPUIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
Matt Arsenaultc791f392014-06-23 18:00:31 +0000107 Type **Tys,
Matt Arsenaulta1fe17c2016-07-19 23:16:53 +0000108 unsigned NumTys) const {
109 return getDeclaration(M, IntrID, makeArrayRef(Tys, NumTys));
Tom Stellard75aadc22012-12-11 21:25:42 +0000110}