diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt --- a/llvm/lib/Target/DirectX/CMakeLists.txt +++ b/llvm/lib/Target/DirectX/CMakeLists.txt @@ -6,6 +6,7 @@ set(LLVM_TARGET_DEFINITIONS DXIL.td) tablegen(LLVM DXILConstants.inc -gen-dxil-enum) +tablegen(LLVM DXILIntrinsicMap.inc -gen-dxil-intrinsic-map) add_public_tablegen_target(DirectXCommonTableGen) diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -229,8 +229,7 @@ static bool lowerIntrinsics(Module &M) { bool Updated = false; - static SmallDenseMap LowerMap = { - {Intrinsic::sin, DXIL::OpCode::Sin}}; +#include "DXILIntrinsicMap.inc" for (Function &F : make_early_inc_range(M.functions())) { if (!F.isDeclaration()) continue; diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp --- a/llvm/utils/TableGen/DXILEmitter.cpp +++ b/llvm/utils/TableGen/DXILEmitter.cpp @@ -59,9 +59,11 @@ StringRef OverloadTypes; // overload types if applicable StringRef FnAttr; // attribute shorthands: rn=does not access // memory,ro=only reads from memory, - bool IsDeriv; // whether this is some kind of derivative - bool IsGradient; // whether this requires a gradient calculation - bool IsFeedback; // whether this is a sampler feedback op + StringRef Intrinsic; // The llvm intrinsic map to DXILOp. Default is "" which + // means no map exist. + bool IsDeriv; // whether this is some kind of derivative + bool IsGradient; // whether this requires a gradient calculation + bool IsFeedback; // whether this is a sampler feedback op bool IsWave; // whether this requires in-wave, cross-lane functionality bool RequiresUniformInputs; // whether this operation requires that all // of its inputs are uniform across the wave @@ -85,6 +87,7 @@ } OverloadTypes = R->getValueAsString("oload_types"); FnAttr = R->getValueAsString("fn_attr"); + Intrinsic = R->getValueAsString("llvm_intrinsic"); } }; } // end anonymous namespace @@ -170,4 +173,23 @@ OS << "\n"; } +// Emit map from llvm intrinsic to DXIL operation. +void EmitDXILIntrinsicMap(RecordKeeper &Records, raw_ostream &OS) { + std::vector Ops = Records.getAllDerivedDefinitions("dxil_op"); + OS << "// Generated code, do not edit.\n"; + OS << "\n"; + OS << "static const SmallDenseMap LowerMap = " + "{\n"; + for (auto *Record : Ops) { + DXILOperationData DXILOp(Record); + if (DXILOp.Intrinsic.empty()) + continue; + // {Intrinsic::sin, DXIL::OpCode::Sin}, + OS << " { Intrinsic::" << DXILOp.Intrinsic + << ", DXIL::OpCode::" << DXILOp.DXILOp << "},\n"; + } + OS << "};\n"; + OS << "\n"; +} + } // namespace llvm diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -59,6 +59,7 @@ GenDirectivesEnumDecl, GenDirectivesEnumImpl, GenDXILEnum, + GenDXILIntrinsicMap, }; namespace llvm { @@ -143,7 +144,9 @@ "Generate directive related declaration code (header file)"), clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl", "Generate directive related implementation code"), - clEnumValN(GenDXILEnum, "gen-dxil-enum", "Generate enum for DXIL"))); + clEnumValN(GenDXILEnum, "gen-dxil-enum", "Generate enum for DXIL"), + clEnumValN(GenDXILIntrinsicMap, "gen-dxil-intrinsic-map", + "Generate map from llvm intrinsic to DXIL operation"))); cl::OptionCategory PrintEnumsCat("Options for -print-enums"); cl::opt Class("class", cl::desc("Print Enum list for this class"), @@ -283,6 +286,9 @@ case GenDXILEnum: EmitDXILEnum(Records, OS); break; + case GenDXILIntrinsicMap: + EmitDXILIntrinsicMap(Records, OS); + break; } return false; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -95,6 +95,7 @@ void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS); void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS); void EmitDXILEnum(RecordKeeper &RK, raw_ostream &OS); +void EmitDXILIntrinsicMap(RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace