46#include "llvm/Support/Alignment.h"
56constexpr uint64_t IndirectCutoffBytes = 16;
61constexpr unsigned ExtendBelowBits = 32;
64 if (isa<NoneType>(type))
67 if (
auto intTy = dyn_cast<IntegerType>(type)) {
68 if (intTy.getWidth() < ExtendBelowBits) {
75 if (
auto indexTy = dyn_cast<IndexType>(type)) {
77 if (sizeInBits.getFixedValue() < ExtendBelowBits) {
84 if (isa<FloatType, VectorType, MemRefType>(type))
93 if (!isa<DataLayoutTypeInterface>(type))
97 if (sizeInBits.isZero())
100 uint64_t sizeInBytes = (sizeInBits.getFixedValue() + 7) / 8;
101 if (sizeInBytes <= IndirectCutoffBytes)
116 fc.
argInfos.reserve(argTypes.size());
117 for (
Type t : argTypes)
118 fc.
argInfos.push_back(classifyOne(t, dl));
127constexpr StringRef knownArgKeys[] = {
128 "kind",
"coerced_type",
"sign_extend",
129 "can_flatten",
"indirect_align",
"byval",
132bool isKnownArgKey(StringRef key) {
133 for (StringRef k : knownArgKeys)
141std::optional<ArgClassification>
143 StringAttr kindAttr = argDict.getAs<StringAttr>(
"kind");
145 emitError() <<
"missing required 'kind' StringAttr";
150 if (!isKnownArgKey(na.getName().getValue())) {
151 emitError() <<
"unknown key '" << na.getName().getValue()
152 <<
"' in classification dictionary; allowed keys are "
153 <<
"kind, coerced_type, sign_extend, can_flatten, "
154 <<
"indirect_align, byval";
158 StringRef kind = kindAttr.getValue();
160 if (kind ==
"direct") {
162 if (
auto t = argDict.getAs<TypeAttr>(
"coerced_type"))
163 coerced = t.getValue();
165 if (
auto cf = argDict.getAs<
BoolAttr>(
"can_flatten"))
166 c.canFlatten =
cf.getValue();
170 if (kind ==
"extend") {
171 auto coerced = argDict.getAs<TypeAttr>(
"coerced_type");
173 emitError() <<
"kind='extend' requires 'coerced_type' TypeAttr";
176 bool signExt =
false;
177 if (
auto se = argDict.getAs<
BoolAttr>(
"sign_extend"))
178 signExt = se.getValue();
182 if (kind ==
"indirect") {
183 auto align = argDict.getAs<IntegerAttr>(
"indirect_align");
185 emitError() <<
"kind='indirect' requires 'indirect_align' IntegerAttr";
188 if (align.getInt() <= 0 || !llvm::isPowerOf2_64(align.getInt())) {
189 emitError() <<
"'indirect_align' must be a positive power of 2; got "
194 if (
auto bv = argDict.getAs<
BoolAttr>(
"byval"))
195 byVal = bv.getValue();
199 if (kind ==
"ignore") {
203 if (kind ==
"expand") {
210 <<
"'; expected one of direct, extend, indirect, ignore, expand";
218 auto returnDict = attr.getAs<DictionaryAttr>(
"return");
220 emitError() <<
"missing required 'return' DictionaryAttr";
224 auto argsArr = attr.getAs<ArrayAttr>(
"args");
226 emitError() <<
"missing required 'args' ArrayAttr";
231 StringRef k = na.getName().getValue();
232 if (k !=
"return" && k !=
"args") {
233 emitError() <<
"unknown top-level key '" << k
234 <<
"'; only 'return' and 'args' are allowed";
241 std::optional<ArgClassification> ret = parseOne(returnDict,
emitError);
246 fc.
argInfos.reserve(argsArr.size());
248 auto d = dyn_cast<DictionaryAttr>(a);
250 emitError() <<
"'args' entries must be DictionaryAttrs";
253 std::optional<ArgClassification> ac = parseOne(d,
emitError);
Attributes are known-constant values of operations.
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
The main mechanism for performing data layout queries.
uint64_t getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
llvm::TypeSize getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
This class represents a diagnostic that is inflight and set to be reported.
NamedAttribute represents a combination of a name and an Attribute value.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
std::optional< FunctionClassification > parseClassificationAttr(DictionaryAttr attr, function_ref< InFlightDiagnostic()> emitError)
Parse a FunctionClassification from a plain MLIR DictionaryAttr.
FunctionClassification classify(ArrayRef< Type > argTypes, Type returnType, const DataLayout &dl)
Classify a function signature using the test target's predictable rules.
@ Expand
Expand an aggregate into its constituent scalar fields.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::function_ref< Fn > function_ref
Describes how a single argument or return value is passed after ABI lowering.
static ArgClassification getIgnore()
static ArgClassification getDirect(Type coerced=nullptr)
static ArgClassification getIndirect(llvm::Align align, bool byVal=true)
static ArgClassification getExtend(Type coerced, bool signExt)
Holds the full ABI classification for a function: return type and all arguments.
ArgClassification returnInfo
SmallVector< ArgClassification > argInfos