Skip to content

Commit 218206d

Browse files
committed
add a means of registering emitters per target
1 parent f1406f8 commit 218206d

File tree

3 files changed

+78
-21
lines changed

3 files changed

+78
-21
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18215,9 +18215,11 @@ Value *CodeGenFunction::EmitHLSLMadIntrinsic(const CallExpr *E) {
1821518215
Value *Mul = Builder.CreateNUWMul(M, A);
1821618216
return Builder.CreateNUWAdd(Mul, B);
1821718217
};
18218-
18219-
return CGM.getHLSLRuntime().emitHLSLIntrinsic(
18220-
EmitHLSLIMadDirectX, EmitHLSLIMadGeneric, EmitHLSLIMadGeneric);
18218+
CGM.getHLSLRuntime().registerHLSLTargetIntrinsic(
18219+
Builtin::BI__builtin_hlsl_mad, llvm::Triple::dxil, EmitHLSLIMadDirectX);
18220+
CGM.getHLSLRuntime().registerHLSLGenericIntrinsic(
18221+
Builtin::BI__builtin_hlsl_mad, EmitHLSLIMadGeneric);
18222+
return CGM.getHLSLRuntime().emitHLSLIntrinsic(Builtin::BI__builtin_hlsl_mad);
1822118223
}
1822218224

1822318225
Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,31 @@ llvm::Triple::ArchType CGHLSLRuntime::getArch() {
119119
return CGM.getTarget().getTriple().getArch();
120120
}
121121

122-
Value *
123-
CGHLSLRuntime::emitHLSLIntrinsic(llvm::function_ref<Value *()> DxilEmitter,
124-
llvm::function_ref<Value *()> SPIRVEmitter,
125-
llvm::function_ref<Value *()> GenericEmitter) {
122+
void CGHLSLRuntime::registerHLSLTargetIntrinsic(
123+
Builtin::ID Id, llvm::Triple::ArchType Arch,
124+
llvm::function_ref<llvm::Value *()> IntrinsicImpl) {
125+
if (!IntrinsicCodeGen.count(Id))
126+
IntrinsicCodeGen[Id] = CGHLSLIntrinsic();
127+
IntrinsicCodeGen[Id].targetImplementations[Arch] = IntrinsicImpl;
128+
}
129+
void CGHLSLRuntime::registerHLSLGenericIntrinsic(
130+
Builtin::ID Id, llvm::function_ref<llvm::Value *()> IntrinsicImpl) {
131+
if (!IntrinsicCodeGen.count(Id))
132+
IntrinsicCodeGen[Id] = CGHLSLIntrinsic();
133+
IntrinsicCodeGen[Id].genericImplementation = IntrinsicImpl;
134+
}
135+
136+
llvm::Value *CGHLSLRuntime::emitHLSLIntrinsic(Builtin::ID id) {
137+
auto it = IntrinsicCodeGen.find(id);
138+
assert(it != IntrinsicCodeGen.end() &&
139+
" HLSL intrinsics need to be reigstered before use.");
126140
llvm::Triple::ArchType Arch = getArch();
127-
switch (Arch) {
128-
case llvm::Triple::dxil:
129-
return DxilEmitter();
130-
case llvm::Triple::spirv:
131-
return SPIRVEmitter();
132-
default:
133-
return GenericEmitter();
141+
auto targets = it->second.targetImplementations;
142+
auto targetIt = targets.find(Arch);
143+
if (targetIt == targets.end()) {
144+
return it->second.genericImplementation();
134145
}
146+
return targetIt->second();
135147
}
136148

137149
void CGHLSLRuntime::addConstant(VarDecl *D, Buffer &CB) {

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,41 @@ class GlobalVariable;
5151
class Function;
5252
class StructType;
5353
class Value;
54+
55+
template <> struct DenseMapInfo<clang::Builtin::ID> {
56+
static clang::Builtin::ID getEmptyKey() { return clang::Builtin::NotBuiltin; }
57+
58+
static clang::Builtin::ID getTombstoneKey() {
59+
return clang::Builtin::FirstTSBuiltin;
60+
}
61+
62+
static unsigned getHashValue(clang::Builtin::ID Val) {
63+
return static_cast<unsigned>(Val);
64+
}
65+
66+
static bool isEqual(clang::Builtin::ID LHS, clang::Builtin::ID RHS) {
67+
return LHS == RHS;
68+
}
69+
};
70+
71+
template <> struct DenseMapInfo<llvm::Triple::ArchType> {
72+
static llvm::Triple::ArchType getEmptyKey() {
73+
return llvm::Triple::ArchType::UnknownArch;
74+
}
75+
76+
static llvm::Triple::ArchType getTombstoneKey() {
77+
return llvm::Triple::ArchType::LastArchType;
78+
}
79+
80+
static unsigned getHashValue(llvm::Triple::ArchType Val) {
81+
return static_cast<unsigned>(Val);
82+
}
83+
84+
static bool isEqual(llvm::Triple::ArchType LHS, llvm::Triple::ArchType RHS) {
85+
return LHS == RHS;
86+
}
87+
};
88+
5489
} // namespace llvm
5590

5691
namespace clang {
@@ -67,6 +102,15 @@ namespace CodeGen {
67102

68103
class CodeGenModule;
69104

105+
struct CGHLSLIntrinsic {
106+
llvm::DenseMap<llvm::Triple::ArchType, llvm::function_ref<llvm::Value *()>>
107+
targetImplementations;
108+
llvm::function_ref<llvm::Value *()> genericImplementation =
109+
[]() -> llvm::Value * {
110+
llvm_unreachable("Intrinsic not supported by target architecture.");
111+
};
112+
};
113+
70114
class CGHLSLRuntime {
71115
public:
72116
//===----------------------------------------------------------------------===//
@@ -80,13 +124,11 @@ class CGHLSLRuntime {
80124
//===----------------------------------------------------------------------===//
81125
// End of reserved area for HLSL intrinsic getters.
82126
//===----------------------------------------------------------------------===//
83-
llvm::Value *emitHLSLIntrinsic(
84-
llvm::function_ref<llvm::Value *()> DxilEmitter,
85-
llvm::function_ref<llvm::Value *()> SPIRVEmitter,
86-
llvm::function_ref<llvm::Value *()> GenericEmitter =
87-
[]() -> llvm::Value * {
88-
llvm_unreachable("Intrinsic not supported by target architecture.");
89-
});
127+
void registerHLSLTargetIntrinsic(Builtin::ID, llvm::Triple::ArchType,
128+
llvm::function_ref<llvm::Value *()>);
129+
void registerHLSLGenericIntrinsic(Builtin::ID,
130+
llvm::function_ref<llvm::Value *()>);
131+
llvm::Value *emitHLSLIntrinsic(Builtin::ID);
90132
struct BufferResBinding {
91133
// The ID like 2 in register(b2, space1).
92134
std::optional<unsigned> Reg;
@@ -137,6 +179,7 @@ class CGHLSLRuntime {
137179
void addBufferDecls(const DeclContext *DC, Buffer &CB);
138180
llvm::Triple::ArchType getArch();
139181
llvm::SmallVector<Buffer> Buffers;
182+
llvm::DenseMap<clang::Builtin::ID, CGHLSLIntrinsic> IntrinsicCodeGen;
140183
};
141184

142185
} // namespace CodeGen

0 commit comments

Comments
 (0)