| 1 | //===-- IntelGPUTargetParser - Parser for Intel GPU targets ---------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file implements a target parser for the Intel GPU list. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "llvm/TargetParser/IntelGPUTargetParser.h" |
| 14 | #include "llvm/ADT/Twine.h" |
| 15 | #include <cassert> |
| 16 | |
| 17 | using namespace llvm; |
| 18 | using namespace IntelGPU; |
| 19 | |
| 20 | // A GPU IP version packs four fields, from the most significant bit down: |
| 21 | // |
| 22 | // 31 22 21 14 13 6 5 0 |
| 23 | // +---------------+----------+----------+----------+ |
| 24 | // | major | minor | reserved | revision | |
| 25 | // +---------------+----------+----------+----------+ |
| 26 | // 10 bits 8 bits 8 bits 6 bits |
| 27 | // |
| 28 | // The reserved bits carry no information. |
| 29 | static constexpr uint32_t GPUIPMajorShift = 22; |
| 30 | static constexpr uint32_t GPUIPMinorShift = 14; |
| 31 | [[maybe_unused]] static constexpr uint32_t GPUIPMajorMask = 0x3ff; |
| 32 | static constexpr uint32_t GPUIPMinorMask = 0xff; |
| 33 | static constexpr uint32_t GPUIPRevisionMask = 0x3f; |
| 34 | |
| 35 | // The bits that identify a device: the major and the minor version. Neither the |
| 36 | // revision nor the reserved bits take part in the lookup, because every |
| 37 | // revision of a device is one device as far as the compiler is concerned. |
| 38 | static constexpr uint32_t GPUIPDeviceMask = ~0u << GPUIPMinorShift; |
| 39 | |
| 40 | // Pack a major and a minor version the way a GPU IP version does, so that a |
| 41 | // row of the table can be compared against a reported version as it is. A value |
| 42 | // too wide for its field would silently corrupt the fields above it, which |
| 43 | // would mean a typo in IntelGPUTargetParser.def going unnoticed. |
| 44 | static constexpr uint32_t packDevice(uint32_t Major, uint32_t Minor) { |
| 45 | assert((Major & ~GPUIPMajorMask) == 0 && "major version too wide" ); |
| 46 | assert((Minor & ~GPUIPMinorMask) == 0 && "minor version too wide" ); |
| 47 | return (Major << GPUIPMajorShift) | (Minor << GPUIPMinorShift); |
| 48 | } |
| 49 | |
| 50 | StringRef llvm::IntelGPU::getArchName(uint32_t GPUIPVersion) { |
| 51 | const uint32_t Device = GPUIPVersion & GPUIPDeviceMask; |
| 52 | #define INTEL_GPU(NAME, KIND, MAJOR, MINOR, IGCA_TARGET, IGCA_FEATURE_SETS) \ |
| 53 | if (Device == packDevice(MAJOR, MINOR)) \ |
| 54 | return NAME; |
| 55 | #include "llvm/TargetParser/IntelGPUTargetParser.def" |
| 56 | return "" ; |
| 57 | } |
| 58 | |
| 59 | std::string llvm::IntelGPU::getNumericArchName(uint32_t GPUIPVersion) { |
| 60 | const uint32_t Major = GPUIPVersion >> GPUIPMajorShift; |
| 61 | const uint32_t Minor = (GPUIPVersion >> GPUIPMinorShift) & GPUIPMinorMask; |
| 62 | const uint32_t Revision = GPUIPVersion & GPUIPRevisionMask; |
| 63 | return ("xe_" + Twine(Major) + "." + Twine(Minor) + "." + Twine(Revision)) |
| 64 | .str(); |
| 65 | } |
| 66 | |