1 //===- AMDGPUIntrinsicInfo.cpp - AMDGPU Intrinsic Information ---*- C++ -*-===// 2 // 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 /// AMDGPU Implementation of the IntrinsicInfo class. 12 // 13 //===-----------------------------------------------------------------------===// 14 15 #include "AMDGPUIntrinsicInfo.h" 16 #include "AMDGPUSubtarget.h" 17 #include "llvm/IR/DerivedTypes.h" 18 #include "llvm/IR/Intrinsics.h" 19 #include "llvm/IR/Module.h" 20 21 using namespace llvm; 22 23 AMDGPUIntrinsicInfo::AMDGPUIntrinsicInfo() 24 : TargetIntrinsicInfo() {} 25 26 static const char *const IntrinsicNameTable[] = { 27 #define GET_INTRINSIC_NAME_TABLE 28 #include "AMDGPUGenIntrinsicImpl.inc" 29 #undef GET_INTRINSIC_NAME_TABLE 30 }; 31 32 namespace { 33 #define GET_INTRINSIC_ATTRIBUTES 34 #include "AMDGPUGenIntrinsicImpl.inc" 35 #undef GET_INTRINSIC_ATTRIBUTES 36 } 37 38 StringRef AMDGPUIntrinsicInfo::getName(unsigned IntrID, 39 ArrayRef<Type *> Tys) const { 40 if (IntrID < Intrinsic::num_intrinsics) 41 return StringRef(); 42 43 assert(IntrID < SIIntrinsic::num_AMDGPU_intrinsics && 44 "Invalid intrinsic ID"); 45 46 return IntrinsicNameTable[IntrID - Intrinsic::num_intrinsics]; 47 } 48 49 std::string AMDGPUIntrinsicInfo::getName(unsigned IntrID, Type **Tys, 50 unsigned NumTys) const { 51 return getName(IntrID, makeArrayRef(Tys, NumTys)).str(); 52 } 53 54 FunctionType *AMDGPUIntrinsicInfo::getType(LLVMContext &Context, unsigned ID, 55 ArrayRef<Type*> Tys) const { 56 // FIXME: Re-use Intrinsic::getType machinery 57 llvm_unreachable("unhandled intrinsic"); 58 } 59 60 unsigned AMDGPUIntrinsicInfo::lookupName(const char *NameData, 61 unsigned Len) const { 62 StringRef Name(NameData, Len); 63 if (!Name.startswith("llvm.")) 64 return 0; // All intrinsics start with 'llvm.' 65 66 // Look for a name match in our table. If the intrinsic is not overloaded, 67 // require an exact match. If it is overloaded, require a prefix match. The 68 // AMDGPU enum enum starts at Intrinsic::num_intrinsics. 69 int Idx = Intrinsic::lookupLLVMIntrinsicByName(IntrinsicNameTable, Name); 70 if (Idx >= 0) { 71 bool IsPrefixMatch = Name.size() > strlen(IntrinsicNameTable[Idx]); 72 return IsPrefixMatch == isOverloaded(Idx + 1) 73 ? Intrinsic::num_intrinsics + Idx 74 : 0; 75 } 76 77 return 0; 78 } 79 80 bool AMDGPUIntrinsicInfo::isOverloaded(unsigned id) const { 81 // Overload Table 82 #define GET_INTRINSIC_OVERLOAD_TABLE 83 #include "AMDGPUGenIntrinsicImpl.inc" 84 #undef GET_INTRINSIC_OVERLOAD_TABLE 85 } 86 87 Function *AMDGPUIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID, 88 ArrayRef<Type *> Tys) const { 89 FunctionType *FTy = getType(M->getContext(), IntrID, Tys); 90 Function *F 91 = cast<Function>(M->getOrInsertFunction(getName(IntrID, Tys), FTy)); 92 93 AttributeList AS = 94 getAttributes(M->getContext(), static_cast<SIIntrinsic::ID>(IntrID)); 95 F->setAttributes(AS); 96 return F; 97 } 98 99 Function *AMDGPUIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID, 100 Type **Tys, 101 unsigned NumTys) const { 102 return getDeclaration(M, IntrID, makeArrayRef(Tys, NumTys)); 103 } 104