18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/TypeSwitch.h"
21 #include "llvm/Support/Casting.h"
26 #include "mlir/Dialect/EmitC/IR/EmitCDialect.cpp.inc"
32 void EmitCDialect::initialize() {
35 #include "mlir/Dialect/EmitC/IR/EmitC.cpp.inc"
38 #define GET_TYPEDEF_LIST
39 #include "mlir/Dialect/EmitC/IR/EmitCTypes.cpp.inc"
42 #define GET_ATTRDEF_LIST
43 #include "mlir/Dialect/EmitC/IR/EmitCAttributes.cpp.inc"
52 return builder.
create<emitc::ConstantOp>(loc, type, value);
58 builder.
create<emitc::YieldOp>(loc);
62 if (llvm::isa<emitc::OpaqueType>(type))
64 if (
auto ptrType = llvm::dyn_cast<emitc::PointerType>(type))
66 if (
auto arrayType = llvm::dyn_cast<emitc::ArrayType>(type)) {
67 auto elemType = arrayType.getElementType();
68 return !llvm::isa<emitc::ArrayType>(elemType) &&
73 if (llvm::isa<IntegerType>(type))
75 if (llvm::isa<FloatType>(type))
77 if (
auto tensorType = llvm::dyn_cast<TensorType>(type)) {
78 if (!tensorType.hasStaticShape()) {
81 auto elemType = tensorType.getElementType();
82 if (llvm::isa<emitc::ArrayType>(elemType)) {
87 if (
auto tupleType = llvm::dyn_cast<TupleType>(type)) {
88 return llvm::all_of(tupleType.getTypes(), [](
Type type) {
89 return !llvm::isa<emitc::ArrayType>(type) && isSupportedEmitCType(type);
96 if (
auto intType = llvm::dyn_cast<IntegerType>(type)) {
97 switch (intType.getWidth()) {
112 return llvm::isa<IndexType, emitc::OpaqueType>(type) ||
117 if (
auto floatType = llvm::dyn_cast<FloatType>(type)) {
118 switch (floatType.getWidth()) {
133 assert(op->
getNumResults() == 1 &&
"operation must have 1 result");
135 if (llvm::isa<emitc::OpaqueAttr>(value))
138 if (llvm::isa<StringAttr>(value))
140 <<
"string attributes are not supported, use #emitc.opaque instead";
143 Type attrType = cast<TypedAttr>(value).getType();
145 if (resultType != attrType)
147 <<
"requires attribute to either be an #emitc.opaque attribute or "
149 << attrType <<
") to match the op's result type (" << resultType
160 Type lhsType = getLhs().getType();
161 Type rhsType = getRhs().getType();
163 if (isa<emitc::PointerType>(lhsType) && isa<emitc::PointerType>(rhsType))
164 return emitOpError(
"requires that at most one operand is a pointer");
166 if ((isa<emitc::PointerType>(lhsType) &&
167 !isa<IntegerType, emitc::OpaqueType>(rhsType)) ||
168 (isa<emitc::PointerType>(rhsType) &&
169 !isa<IntegerType, emitc::OpaqueType>(lhsType)))
170 return emitOpError(
"requires that one operand is an integer or of opaque "
171 "type if the other is a pointer");
181 StringRef applicableOperatorStr = getApplicableOperator();
184 if (applicableOperatorStr.empty())
185 return emitOpError(
"applicable operator must not be empty");
188 if (applicableOperatorStr !=
"&" && applicableOperatorStr !=
"*")
189 return emitOpError(
"applicable operator is illegal");
191 Operation *op = getOperand().getDefiningOp();
192 if (op && dyn_cast<ConstantOp>(op))
193 return emitOpError(
"cannot apply to constant");
205 Value variable = getVar();
208 !llvm::isa<emitc::VariableOp, emitc::SubscriptOp>(variableDef))
209 return emitOpError() <<
"requires first operand (" << variable
210 <<
") to be a Variable or subscript";
212 Value value = getValue();
214 return emitOpError() <<
"requires value's type (" << value.
getType()
215 <<
") to match variable's type (" << variable.
getType()
217 if (isa<ArrayType>(variable.
getType()))
218 return emitOpError() <<
"cannot assign to array type";
227 Type input = inputs.front(), output = outputs.front();
229 return ((llvm::isa<IntegerType,
FloatType, IndexType, emitc::OpaqueType,
230 emitc::PointerType>(input)) &&
231 (llvm::isa<IntegerType,
FloatType, IndexType, emitc::OpaqueType,
232 emitc::PointerType>(output)));
241 if (getCallee().empty())
242 return emitOpError(
"callee must not be empty");
244 if (std::optional<ArrayAttr> argsAttr = getArgs()) {
246 auto intAttr = llvm::dyn_cast<IntegerAttr>(arg);
247 if (intAttr && llvm::isa<IndexType>(intAttr.getType())) {
248 int64_t index = intAttr.getInt();
251 if ((index < 0) || (index >=
static_cast<int64_t
>(getNumOperands())))
252 return emitOpError(
"index argument is out of range");
255 }
else if (llvm::isa<ArrayAttr>(
258 return emitOpError(
"array argument has no type");
263 if (std::optional<ArrayAttr> templateArgsAttr = getTemplateArgs()) {
264 for (
Attribute tArg : *templateArgsAttr) {
265 if (!llvm::isa<TypeAttr, IntegerAttr, FloatAttr, emitc::OpaqueAttr>(tArg))
266 return emitOpError(
"template argument has invalid type");
270 if (llvm::any_of(getResultTypes(), llvm::IsaPred<ArrayType>)) {
271 return emitOpError() <<
"cannot return array type";
285 if (
auto opaqueValue = llvm::dyn_cast<emitc::OpaqueAttr>(value)) {
286 if (opaqueValue.getValue().empty())
287 return emitOpError() <<
"value must not be empty";
292 OpFoldResult emitc::ConstantOp::fold(FoldAdaptor adaptor) {
return getValue(); }
299 auto yieldOp = cast<YieldOp>(getBody()->getTerminator());
300 Value yieldedValue = yieldOp.getResult();
302 assert(rootOp &&
"Yielded value not defined within expression");
307 Type resultType = getResult().getType();
308 Region ®ion = getRegion();
313 return emitOpError(
"must yield a value at termination");
316 Value yieldResult = yield.getResult();
319 return emitOpError(
"must yield a value at termination");
323 if (resultType != yieldType)
324 return emitOpError(
"requires yielded type to match return type");
328 return emitOpError(
"contains an unsupported operation");
330 return emitOpError(
"requires exactly one result for each operation");
332 return emitOpError(
"requires exactly one use for each operation");
343 Value ub,
Value step, BodyBuilderFn bodyBuilder) {
353 ForOp::ensureTerminator(*bodyRegion, builder, result.
location);
381 regionArgs.push_back(inductionVariable);
390 regionArgs.front().type = type;
401 ForOp::ensureTerminator(*body, builder, result.
location);
411 p <<
" " << getInductionVar() <<
" = " <<
getLowerBound() <<
" to "
415 if (
Type t = getInductionVar().getType(); !t.
isIndex())
416 p <<
" : " << t <<
' ';
426 if (getInductionVar().getType() !=
getLowerBound().getType())
428 "expected induction variable to be same type as bounds and step");
441 return emitOpError(
"requires a 'callee' symbol reference attribute");
444 return emitOpError() <<
"'" << fnAttr.getValue()
445 <<
"' does not reference a valid function";
448 auto fnType = fn.getFunctionType();
449 if (fnType.getNumInputs() != getNumOperands())
450 return emitOpError(
"incorrect number of operands for callee");
452 for (
unsigned i = 0, e = fnType.getNumInputs(); i != e; ++i)
453 if (getOperand(i).getType() != fnType.getInput(i))
454 return emitOpError(
"operand type mismatch: expected operand type ")
455 << fnType.getInput(i) <<
", but provided "
456 << getOperand(i).getType() <<
" for operand number " << i;
458 if (fnType.getNumResults() != getNumResults())
459 return emitOpError(
"incorrect number of results for callee");
461 for (
unsigned i = 0, e = fnType.getNumResults(); i != e; ++i)
462 if (getResult(i).getType() != fnType.getResult(i)) {
463 auto diag = emitOpError(
"result type mismatch at index ") << i;
464 diag.attachNote() <<
" op result types: " << getResultTypes();
465 diag.attachNote() <<
"function result types: " << fnType.getResults();
472 FunctionType CallOp::getCalleeType() {
483 auto fnAttr = getSymNameAttr();
485 return emitOpError(
"requires a 'sym_name' symbol reference attribute");
488 return emitOpError() <<
"'" << fnAttr.getValue()
489 <<
"' does not reference a valid function";
503 state.addAttribute(getFunctionTypeAttrName(state.name),
TypeAttr::get(type));
504 state.attributes.append(attrs.begin(), attrs.end());
507 if (argAttrs.empty())
509 assert(type.getNumInputs() == argAttrs.size());
511 builder, state, argAttrs, std::nullopt,
512 getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
522 parser, result,
false,
523 getFunctionTypeAttrName(result.
name), buildFuncType,
524 getArgAttrsAttrName(result.
name), getResAttrsAttrName(result.
name));
529 p, *
this,
false, getFunctionTypeAttrName(),
530 getArgAttrsAttrName(), getResAttrsAttrName());
534 if (getNumResults() > 1)
535 return emitOpError(
"requires zero or exactly one result, but has ")
538 if (getNumResults() == 1 && isa<ArrayType>(getResultTypes()[0]))
539 return emitOpError(
"cannot return array type");
549 auto function = cast<FuncOp>((*this)->getParentOp());
552 if (getNumOperands() !=
function.getNumResults())
553 return emitOpError(
"has ")
554 << getNumOperands() <<
" operands, but enclosing function (@"
555 <<
function.getName() <<
") returns " <<
function.getNumResults();
557 if (
function.getNumResults() == 1)
558 if (getOperand().getType() !=
function.getResultTypes()[0])
559 return emitError() <<
"type of the return operand ("
560 << getOperand().getType()
561 <<
") doesn't match function result type ("
562 <<
function.getResultTypes()[0] <<
")"
563 <<
" in function @" <<
function.getName();
572 bool addThenBlock,
bool addElseBlock) {
573 assert((!addElseBlock || addThenBlock) &&
574 "must not create else block w/o then block");
588 bool withElseRegion) {
598 if (withElseRegion) {
606 assert(thenBuilder &&
"the builder callback for 'then' must be present");
613 thenBuilder(builder, result.
location);
619 elseBuilder(builder, result.
location);
654 bool printBlockTerminators =
false;
656 p <<
" " << getCondition();
660 printBlockTerminators);
663 Region &elseRegion = getElseRegion();
664 if (!elseRegion.
empty()) {
668 printBlockTerminators);
690 Region *elseRegion = &this->getElseRegion();
691 if (elseRegion->
empty())
699 FoldAdaptor adaptor(operands, *
this);
700 auto boolAttr = dyn_cast_or_null<BoolAttr>(adaptor.getCondition());
701 if (!boolAttr || boolAttr.getValue())
702 regions.emplace_back(&getThenRegion());
705 if (!boolAttr || !boolAttr.getValue()) {
706 if (!getElseRegion().empty())
707 regions.emplace_back(&getElseRegion());
709 regions.emplace_back();
713 void IfOp::getRegionInvocationBounds(
716 if (
auto cond = llvm::dyn_cast_or_null<BoolAttr>(operands[0])) {
719 invocationBounds.emplace_back(0, cond.getValue() ? 1 : 0);
720 invocationBounds.emplace_back(0, cond.getValue() ? 0 : 1);
723 invocationBounds.assign(2, {0, 1});
732 bool standardInclude = getIsStandardInclude();
737 p <<
"\"" << getInclude() <<
"\"";
753 <<
"expected trailing '>' for standard include";
768 if (getValue().empty())
769 return emitOpError() <<
"value must not be empty";
777 Type lhsType = getLhs().getType();
778 Type rhsType = getRhs().getType();
779 Type resultType = getResult().getType();
781 if (isa<emitc::PointerType>(rhsType) && !isa<emitc::PointerType>(lhsType))
782 return emitOpError(
"rhs can only be a pointer if lhs is a pointer");
784 if (isa<emitc::PointerType>(lhsType) &&
785 !isa<IntegerType, emitc::OpaqueType, emitc::PointerType>(rhsType))
786 return emitOpError(
"requires that rhs is an integer, pointer or of opaque "
787 "type if lhs is a pointer");
789 if (isa<emitc::PointerType>(lhsType) && isa<emitc::PointerType>(rhsType) &&
790 !isa<IntegerType, emitc::OpaqueType>(resultType))
791 return emitOpError(
"requires that the result is an integer or of opaque "
792 "type if lhs and rhs are pointers");
809 Value result = getResult();
813 return emitOpError() <<
"yields a value not returned by parent";
816 return emitOpError() <<
"does not yield a value to be returned by parent";
827 if (
auto arrayType = llvm::dyn_cast<emitc::ArrayType>(getValue().getType())) {
829 if (
getIndices().size() != (
size_t)arrayType.getRank()) {
830 return emitOpError() <<
"on array operand requires number of indices ("
832 <<
") to match the rank of the array type ("
833 << arrayType.getRank() <<
")";
836 for (
unsigned i = 0, e =
getIndices().size(); i != e; ++i) {
839 return emitOpError() <<
"on array operand requires index operand " << i
840 <<
" to be integer-like, but got " << type;
844 Type elementType = arrayType.getElementType();
845 if (elementType != getType()) {
846 return emitOpError() <<
"on array operand requires element type ("
847 << elementType <<
") and result type (" << getType()
854 if (
auto pointerType =
855 llvm::dyn_cast<emitc::PointerType>(getValue().getType())) {
859 <<
"on pointer operand requires one index operand, but got "
865 return emitOpError() <<
"on pointer operand requires index operand to be "
866 "integer-like, but got "
870 Type pointeeType = pointerType.getPointee();
871 if (pointeeType != getType()) {
872 return emitOpError() <<
"on pointer operand requires pointee type ("
873 << pointeeType <<
") and result type (" << getType()
888 #include "mlir/Dialect/EmitC/IR/EmitCEnums.cpp.inc"
894 #define GET_ATTRDEF_CLASSES
895 #include "mlir/Dialect/EmitC/IR/EmitCAttributes.cpp.inc"
901 #define GET_TYPEDEF_CLASSES
902 #include "mlir/Dialect/EmitC/IR/EmitCTypes.cpp.inc"
923 if (!isValidElementType(elementType))
924 return parser.
emitError(typeLoc,
"invalid array element type"),
Type();
927 return parser.
getChecked<ArrayType>(dimensions, elementType);
933 printer << dim <<
'x';
943 return emitError() <<
"shape must not be empty";
945 for (int64_t dim : shape) {
947 return emitError() <<
"dimensions must have positive size";
951 return emitError() <<
"element type must not be none";
953 if (!isValidElementType(elementType))
954 return emitError() <<
"invalid array element type";
961 Type elementType)
const {
973 llvm::StringRef value) {
975 return emitError() <<
"expected non empty string in !emitc.opaque type";
977 if (value.back() ==
'*') {
978 return emitError() <<
"pointer not allowed as outer type with "
979 "!emitc.opaque, use !emitc.ptr instead";
998 if (
auto array = llvm::dyn_cast<ArrayType>(type))
1018 if (!llvm::isa<ElementsAttr, IntegerAttr, FloatAttr, emitc::OpaqueAttr>(
1021 <<
"initial value should be a integer, float, elements or opaque "
1028 return emitOpError(
"expected valid emitc type");
1030 if (getInitialValue().has_value()) {
1031 Attribute initValue = getInitialValue().value();
1034 if (
auto elementsAttr = llvm::dyn_cast<ElementsAttr>(initValue)) {
1035 auto arrayType = llvm::dyn_cast<ArrayType>(getType());
1037 return emitOpError(
"expected array type, but got ") << getType();
1039 Type initType = elementsAttr.getType();
1041 if (initType != tensorType) {
1042 return emitOpError(
"initial value expected to be of type ")
1043 << getType() <<
", but was of type " << initType;
1045 }
else if (
auto intAttr = dyn_cast<IntegerAttr>(initValue)) {
1046 if (intAttr.getType() != getType()) {
1047 return emitOpError(
"initial value expected to be of type ")
1048 << getType() <<
", but was of type " << intAttr.getType();
1050 }
else if (
auto floatAttr = dyn_cast<FloatAttr>(initValue)) {
1051 if (floatAttr.getType() != getType()) {
1052 return emitOpError(
"initial value expected to be of type ")
1053 << getType() <<
", but was of type " << floatAttr.getType();
1055 }
else if (!isa<emitc::OpaqueAttr>(initValue)) {
1056 return emitOpError(
"initial value should be a integer, float, elements "
1057 "or opaque attribute, but got ")
1061 if (getStaticSpecifier() && getExternSpecifier()) {
1062 return emitOpError(
"cannot have both static and extern specifiers");
1077 return emitOpError(
"'")
1078 << getName() <<
"' does not reference a valid emitc.global";
1080 Type resultType = getResult().getType();
1081 if (global.getType() != resultType)
1082 return emitOpError(
"result type ")
1083 << resultType <<
" does not match type " << global.getType()
1084 <<
" of the global @" << getName();
1092 #define GET_OP_CLASSES
1093 #include "mlir/Dialect/EmitC/IR/EmitC.cpp.inc"
static std::optional< int64_t > getUpperBound(Value iv)
Gets the constant upper bound on an affine.for iv.
static std::optional< int64_t > getLowerBound(Value iv)
Gets the constant lower bound on an iv.
static LogicalResult verifyInitializationAttribute(Operation *op, Attribute value)
Check that the type of the initial value is compatible with the operations result type.
static ParseResult parseEmitCGlobalOpTypeAndInitialValue(OpAsmParser &parser, TypeAttr &typeAttr, Attribute &initialValue)
static void printEmitCGlobalOpTypeAndInitialValue(OpAsmPrinter &p, GlobalOp op, TypeAttr type, Attribute initialValue)
static Type getInitializerTypeForGlobal(Type type)
static Operation * materializeConstant(Dialect *dialect, OpBuilder &builder, Attribute value, Type type, Location loc)
A utility function used to materialize a constant for a given attribute and type.
static MLIRContext * getContext(OpFoldResult val)
static std::string diag(const llvm::Value &value)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity,...
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual ParseResult parseOptionalAttrDict(NamedAttrList &result)=0
Parse a named dictionary into 'result' if it is present.
virtual ParseResult parseOptionalEqual()=0
Parse a = token if present.
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
MLIRContext * getContext() const
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual ParseResult parseOptionalColon()=0
Parse a : token if present.
virtual ParseResult parseLess()=0
Parse a '<' token.
virtual ParseResult parseDimensionList(SmallVectorImpl< int64_t > &dimensions, bool allowDynamic=true, bool withTrailingX=true)=0
Parse a dimension list of a tensor or memref type.
virtual ParseResult parseOptionalGreater()=0
Parse a '>' token if present.
virtual ParseResult parseEqual()=0
Parse a = token.
virtual OptionalParseResult parseOptionalAttribute(Attribute &result, Type type={})=0
Parse an arbitrary optional attribute of a given type and return it in result.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
auto getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
virtual ParseResult parseOptionalLess()=0
Parse a '<' token if present.
virtual ParseResult parseGreater()=0
Parse a '>' token.
virtual ParseResult parseType(Type &result)=0
Parse a type.
ParseResult parseKeyword(StringRef keyword)
Parse a given keyword.
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
This base class exposes generic asm printer hooks, usable across the various derived printers.
virtual void printAttributeWithoutType(Attribute attr)
Print the given attribute without its type.
virtual void printType(Type type)
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
BlockArgument getArgument(unsigned i)
Operation * getTerminator()
Get the terminator operation of this block.
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
bool mightHaveTerminator()
Check whether this block might have a terminator.
iterator_range< iterator > without_terminator()
Return an iterator range over the operation within this block excluding the terminator operation at t...
This class is a general helper class for creating context-global objects like types,...
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
IntegerType getIntegerType(unsigned width)
StringAttr getStringAttr(const Twine &bytes)
A symbol reference with a reference path containing a single element.
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual ParseResult parseRegion(Region ®ion, ArrayRef< Argument > arguments={}, bool enableNameShadowing=false)=0
Parses a region.
virtual ParseResult resolveOperand(const UnresolvedOperand &operand, Type type, SmallVectorImpl< Value > &result)=0
Resolve an operand to an SSA value, emitting an error on failure.
virtual ParseResult parseOperand(UnresolvedOperand &result, bool allowResultNumber=true)=0
Parse a single SSA value operand name along with a result number if allowResultNumber is true.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
virtual void printOptionalAttrDict(ArrayRef< NamedAttribute > attrs, ArrayRef< StringRef > elidedAttrs={})=0
If the specified operation has attributes, print out an attribute dictionary with their values.
virtual void printRegion(Region &blocks, bool printEntryBlockArgs=true, bool printBlockTerminators=true, bool printEmptyBlock=false)=0
Prints a region.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes=std::nullopt, ArrayRef< Location > locs=std::nullopt)
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents a single result from folding an operation.
type_range getType() const
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
unsigned getNumResults()
Return the number of results held by this operation.
This class implements Optional functionality for ParseResult.
bool has_value() const
Returns true if we contain a valid ParseResult value.
This class represents success/failure for parsing-like operations that find it important to chain tog...
This class represents a point being branched from in the methods of the RegionBranchOpInterface.
bool isParent() const
Returns true if branching from the parent op.
This class represents a successor of a region.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class represents a collection of SymbolTables.
Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
bool hasOneUse() const
Returns true if this value has exactly one use.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
A named class for passing around the variadic flag.
void buildTerminatedBody(OpBuilder &builder, Location loc)
Default callback for builders of ops carrying a region.
bool isSupportedFloatType(mlir::Type type)
Determines whether type is a valid floating-point type in EmitC.
bool isSupportedEmitCType(mlir::Type type)
Determines whether type is valid in EmitC.
bool isIntegerIndexOrOpaqueType(Type type)
Determines whether type is integer like, i.e.
bool isSupportedIntegerType(mlir::Type type)
Determines whether type is a valid integer type in EmitC.
void addArgAndResultAttrs(Builder &builder, OperationState &result, ArrayRef< DictionaryAttr > argAttrs, ArrayRef< DictionaryAttr > resultAttrs, StringAttr argAttrsName, StringAttr resAttrsName)
Adds argument and result attributes, provided as argAttrs and resultAttrs arguments,...
void printFunctionOp(OpAsmPrinter &p, FunctionOpInterface op, bool isVariadic, StringRef typeAttrName, StringAttr argAttrsName, StringAttr resAttrsName)
Printer implementation for function-like operations.
ParseResult parseFunctionOp(OpAsmParser &parser, OperationState &result, bool allowVariadic, StringAttr typeAttrName, FuncTypeBuilder funcTypeBuilder, StringAttr argAttrsName, StringAttr resAttrsName)
Parser implementation for function-like operations.
Operation::operand_range getIndices(Operation *op)
Get the indices that the given load/store operation is operating on.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.
UnresolvedOperand ssaName
This is the representation of an operand reference.
This represents an operation in an abstracted form, suitable for use with the builder APIs.
SmallVector< Value, 4 > operands
void addOperands(ValueRange newOperands)
void addAttribute(StringRef name, Attribute attr)
Add an attribute with the specified name.
SmallVector< std::unique_ptr< Region >, 1 > regions
Regions that the op will hold.
Region * addRegion()
Create a region that should be attached to the operation.