1+ // ===-- TargetDescriptionAnalysis.cpp - target description impl -*- C++ -*-===//
2+ //
3+ // This file is licensed 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+ #include " gc/Analysis/TargetDescriptionAnalysis.h"
10+ #include < limits>
11+ #include < llvm/Support/Debug.h>
12+ #include < regex>
13+
14+ namespace mlir {
15+ namespace gc {
16+
17+ #define DEBUG_TYPE " target-description-analysis"
18+
19+ llvm::DenseMap<DeviceType, std::string>
20+ TargetDescriptionAnalysisBase::DeviceKeyMap = {
21+ {CPU, " CPU" },
22+ };
23+
24+ template <typename T>
25+ void TargetDescriptionAnalysisBase::emitNotFoundWarning (Location loc,
26+ StringRef key,
27+ T value) {
28+ mlir::emitWarning (loc) << key << " not found, using default value " << value;
29+ }
30+
31+ static bool isIntegerNumber (const std::string &token) {
32+ return std::regex_match (token, std::regex ((" (\\ +|-)?[[:digit:]]+" )));
33+ }
34+
35+ static int64_t getIntFromAttribute (Attribute attr) {
36+ if (auto intAttr = dyn_cast<IntegerAttr>(attr)) {
37+ if (intAttr.getType ().isSignedInteger ())
38+ return intAttr.getSInt ();
39+ else if (intAttr.getType ().isUnsignedInteger ())
40+ return intAttr.getUInt ();
41+ else
42+ return intAttr.getInt ();
43+ } else if (auto strAttr = dyn_cast<StringAttr>(attr)) {
44+ std::string str = strAttr.getValue ().str ();
45+ if (isIntegerNumber (str))
46+ return std::stoll (str);
47+ }
48+ llvm_unreachable (" Not an integer attribute or integer like string attribute" );
49+ }
50+
51+ std::optional<Attribute>
52+ TargetDescriptionAnalysisBase::getPropertyValue (StringRef key) {
53+ return layout.getDevicePropertyValue (
54+ Builder (getContext ())
55+ .getStringAttr (DeviceKeyMap[getDevice ()] /* device ID*/ ),
56+ Builder (getContext ()).getStringAttr (key));
57+ }
58+
59+ unsigned CPUTargetDescriptionAnalysis::getNumThreads () {
60+ static const unsigned defaultNumThreads = 1 ;
61+ std::optional<Attribute> numThreads = getPropertyValue (kNumThreads );
62+
63+ if (numThreads)
64+ return getIntFromAttribute (*numThreads);
65+ emitNotFoundWarning (getLocation (), kNumThreads , defaultNumThreads);
66+ return defaultNumThreads;
67+ }
68+
69+ unsigned CPUTargetDescriptionAnalysis::getCacheSize (uint8_t cacheLevel) {
70+ assert (cacheLevel > 0 && cacheLevel < 4 && " Invalid cache level" );
71+ llvm::DenseMap<StringRef, unsigned > CPUTargetCacheSizeValueMap = {
72+ {CPUTargetDescriptionAnalysis::kL1CacheSize , 32 * 1024 },
73+ {CPUTargetDescriptionAnalysis::kL2CacheSize , 1024 * 1024 },
74+ {CPUTargetDescriptionAnalysis::kL3CacheSize , 32 * 1024 * 1024 },
75+ };
76+ StringLiteral key = " " ;
77+ if (cacheLevel == 1 )
78+ key = kL1CacheSize ;
79+ else if (cacheLevel == 2 )
80+ key = kL2CacheSize ;
81+ else if (cacheLevel == 3 )
82+ key = kL3CacheSize ;
83+
84+ std::optional<Attribute> cacheSize = getPropertyValue (key);
85+ if (cacheSize)
86+ return getIntFromAttribute (*cacheSize);
87+
88+ emitNotFoundWarning (getLocation (), key, CPUTargetCacheSizeValueMap[key]);
89+ return CPUTargetCacheSizeValueMap[key];
90+ }
91+
92+ unsigned CPUTargetDescriptionAnalysis::getMaxVectorWidth () {
93+ static const unsigned defaultMaxVectorWidth = 512 ;
94+ std::optional<Attribute> maxVectorWidth = getPropertyValue (kMaxVectorWidth );
95+ if (maxVectorWidth)
96+ return getIntFromAttribute (*maxVectorWidth);
97+ emitNotFoundWarning (getLocation (), kMaxVectorWidth , defaultMaxVectorWidth);
98+ return defaultMaxVectorWidth;
99+ }
100+
101+ } // namespace gc
102+ } // namespace mlir
0 commit comments