12#include "llvm/ADT/SetVector.h"
13#include "llvm/ADT/SmallString.h"
14#include "llvm/ADT/StringSwitch.h"
42 assert(within->
isAncestor(symbol) &&
"expected 'within' to be an ancestor");
46 results.push_back(leafRef);
50 if (within == symbolTableOp)
55 StringAttr symbolNameId =
62 StringAttr symbolTableName =
getNameIfSymbol(symbolTableOp, symbolNameId);
65 results.push_back(SymbolRefAttr::get(symbolTableName, nestedRefs));
68 if (symbolTableOp == within)
70 nestedRefs.insert(nestedRefs.begin(),
79static std::optional<WalkResult>
83 while (!worklist.empty()) {
84 for (
Operation &op : worklist.pop_back_val()->getOps()) {
85 std::optional<WalkResult>
result = callback(&op);
92 for (
Region ®ion : op.getRegions())
93 worklist.push_back(®ion);
103static std::optional<WalkResult>
106 std::optional<WalkResult>
result = callback(op);
118 : symbolTableOp(symbolTableOp) {
120 "expected operation to have SymbolTable trait");
121 assert(symbolTableOp->getNumRegions() == 1 &&
122 "expected operation to have a single region");
123 assert(symbolTableOp->getRegion(0).hasOneBlock() &&
124 "expected operation to have a single block");
126 StringAttr symbolNameId = StringAttr::get(symbolTableOp->getContext(),
139 symbolTable.try_emplace(name, &op);
146 return lookup(StringAttr::get(symbolTableOp->getContext(), name));
149 return symbolTable.lookup(name);
154 assert(name &&
"expected valid 'name' attribute");
156 "expected this operation to be inside of the operation with this "
159 auto it = symbolTable.find(name);
160 if (it != symbolTable.end() && it->second == op)
161 symbolTable.erase(it);
179 auto &body = symbolTableOp->getRegion(0).front();
183 assert((insertPt == body.end() ||
184 insertPt->getParentOp() == symbolTableOp) &&
185 "expected insertPt to be in the associated module operation");
190 insertPt = std::prev(body.end());
192 body.getOperations().insert(insertPt, symbol);
195 "symbol is already inserted in another op");
200 if (symbolTable.insert({name, symbol}).second)
203 if (symbolTable.lookup(name) == symbol)
209 [&](StringRef candidate) {
211 .insert({StringAttr::get(context, candidate), symbol})
215 setSymbolName(symbol, nameBuffer);
216 return getSymbolName(symbol);
228 assert(from &&
"expected valid 'name' attribute");
230 "expected this operation to be inside of the operation with this "
232 assert(
lookup(from) == op &&
"current name does not resolve to op");
233 assert(
lookup(to) ==
nullptr &&
"new name already exists");
244 assert(
lookup(to) == op &&
"new name does not resolve to renamed op");
245 assert(
lookup(from) ==
nullptr &&
"old name still exists");
252 return rename(from, toAttr);
257 return rename(op, toAttr);
270 prefix.push_back(
'_');
272 newName = StringAttr::get(context, prefix + Twine(uniqueId++));
273 auto lookupNewName = [&](
SymbolTable *st) {
return st->lookup(newName); };
274 if (!lookupNewName(
this) && llvm::none_of(others, lookupNewName)) {
281 if (failed(
rename(oldName, newName)))
289 assert(from &&
"expected valid 'name' attribute");
296 assert(name &&
"expected valid symbol name");
331 "unknown symbol visibility kind");
340 assert(from &&
"expected valid operation");
364 SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(op);
365 allSymUsesVisible |= !symbol || symbol.isPrivate();
369 allSymUsesVisible =
true;
373 for (
Block &block : region)
380 callback(op, allSymUsesVisible);
390 Region ®ion = symbolTableOp->getRegion(0);
395 StringAttr symbolNameId = StringAttr::get(symbolTableOp->getContext(),
397 for (
auto &op : region.
front())
403 SymbolRefAttr symbol) {
405 if (failed(
lookupSymbolIn(symbolTableOp, symbol, resolvedSymbols)))
407 return resolvedSymbols.back();
413 Operation *symbolTableOp, SymbolRefAttr symbol,
419 auto *symbolOp = lookupSymbolFn(symbolTableOp, symbol.getRootReference());
422 symbols.push_back(symbolOp);
429 symbolOp = lookupSymbolFn(symbolOp, ref.getAttr());
434 symbols.push_back(symbolOp);
442 auto lookupFn = [](
Operation *symbolTableOp, StringAttr symbol) {
454 return symbolTableOp ?
lookupSymbolIn(symbolTableOp, symbol) :
nullptr;
457 SymbolRefAttr symbol) {
459 return symbolTableOp ?
lookupSymbolIn(symbolTableOp, symbol) :
nullptr;
464 switch (visibility) {
466 return os <<
"public";
468 return os <<
"private";
470 return os <<
"nested";
472 llvm_unreachable(
"Unexpected visibility");
493 if (!verifiedTypes.insert(nestedType))
495 if (
auto user = dyn_cast<SymbolUserTypeInterface>(nestedType))
496 if (failed(user.verifySymbolUses(op, symbolTable)))
503 if (
verify(type).wasInterrupted())
506 if (
verify(type).wasInterrupted())
509 for (
Block &block : region)
511 if (
verify(argument.getType()).wasInterrupted())
517 if (
verify(type).wasInterrupted())
527 <<
"Operations with a 'SymbolTable' must have exactly one region";
530 <<
"Operations with a 'SymbolTable' must have exactly one block";
535 for (
auto &op : block) {
543 auto it = nameToOrigLoc.try_emplace(nameAttr, op.
getLoc());
546 .
append(
"redefinition of symbol named '", nameAttr.getValue(),
"'")
548 .
append(
"see existing symbol definition here");
561 auto verifySymbolUserFn = [&](
Operation *op) -> std::optional<WalkResult> {
562 if (SymbolUserOpInterface user = dyn_cast<SymbolUserOpInterface>(op))
563 if (failed(user.verifySymbolUses(symbolTable)))
566 if (
auto user = dyn_cast<SymbolUserAttrInterface>(attr.getValue())) {
567 if (!verifiedAttrs.insert(attr.getValue()))
569 if (failed(user.verifySymbolUses(op, symbolTable)))
578 std::optional<WalkResult>
result =
586 return op->
emitOpError() <<
"requires string attribute '"
591 StringAttr visStrAttr = llvm::dyn_cast<StringAttr>(vis);
593 return op->
emitOpError() <<
"requires visibility attribute '"
595 <<
"' to be a string attribute, but got " << vis;
598 visStrAttr.getValue()))
600 <<
"visibility expected to be one of [\"public\", \"private\", "
601 "\"nested\"], but got "
618 [&](SymbolRefAttr symbolRef) {
619 if (callback({op, symbolRef}).wasInterrupted())
630static std::optional<WalkResult>
634 [&](
Operation *op) -> std::optional<WalkResult> {
646static std::optional<WalkResult>
678 template <
typename CallbackT,
679 std::enable_if_t<!std::is_same<
680 typename llvm::function_traits<CallbackT>::result_t,
681 void>::value> * =
nullptr>
682 std::optional<WalkResult>
walk(CallbackT cback) {
683 if (Region *region = llvm::dyn_cast_if_present<Region *>(limit))
689 template <
typename CallbackT,
690 std::enable_if_t<std::is_same<
691 typename llvm::function_traits<CallbackT>::result_t,
692 void>::value> * =
nullptr>
693 std::optional<WalkResult>
walk(CallbackT cback) {
694 return walk([=](SymbolTable::SymbolUse use) {
701 template <
typename CallbackT>
703 if (Region *region = llvm::dyn_cast_if_present<Region *>(limit))
704 return ::walkSymbolTable(*region, cback);
705 return ::walkSymbolTable(cast<Operation *>(limit), cback);
709 SymbolRefAttr symbol;
712 llvm::PointerUnion<Operation *, Region *> limit;
729 if (limitAncestor == symbol) {
734 return {{SymbolRefAttr::get(symName), limit}};
738 limitAncestors.insert(limitAncestor);
739 }
while ((limitAncestor = limitAncestor->
getParentOp()));
744 if (limitAncestors.count(commonAncestor))
746 }
while ((commonAncestor = commonAncestor->
getParentOp()));
747 assert(commonAncestor &&
"'limit' and 'symbol' have no common ancestor");
752 bool collectedAllReferences = succeeded(
756 if (commonAncestor == limit) {
762 for (
size_t i = 0, e = references.size(); i != e;
765 scopes.push_back({references[i], &limitIt->
getRegion(0)});
773 if (!collectedAllReferences)
775 return {{references.back(), limit}};
784 scopes.back().limit = limit;
789 return {{SymbolRefAttr::get(symbol), limit}};
795 auto symbolRef = SymbolRefAttr::get(symbol);
797 scopes.push_back({symbolRef, ®ion});
809 if (llvm::isa<FlatSymbolRefAttr>(ref) ||
810 ref.getRootReference() != subRef.getRootReference())
813 auto refLeafs = ref.getNestedReferences();
814 auto subRefLeafs = subRef.getNestedReferences();
815 return subRefLeafs.size() < refLeafs.size() &&
816 subRefLeafs == refLeafs.take_front(subRefLeafs.size());
824template <
typename FromT>
826 std::vector<SymbolTable::SymbolUse> uses;
828 uses.push_back(symbolUse);
832 return result ? std::optional<SymbolTable::UseRange>(std::move(uses))
855template <
typename SymbolT,
typename IRUnitT>
858 std::vector<SymbolTable::SymbolUse> uses;
861 if (isReferencePrefixOf(scope.symbol, symbolUse.getSymbolRef()))
862 uses.push_back(symbolUse);
874 -> std::optional<UseRange> {
878 -> std::optional<UseRange> {
882 -> std::optional<UseRange> {
886 -> std::optional<UseRange> {
895template <
typename SymbolT,
typename IRUnitT>
900 return isReferencePrefixOf(scope.symbol, symbolUse.getSymbolRef())
901 ? WalkResult::interrupt()
902 : WalkResult::advance();
933 if (llvm::isa<FlatSymbolRefAttr>(oldAttr))
935 auto nestedRefs = llvm::to_vector<2>(oldAttr.getNestedReferences());
936 nestedRefs.back() = newLeafAttr;
937 return SymbolRefAttr::get(oldAttr.getRootReference(), nestedRefs);
941template <
typename SymbolT,
typename IRUnitT>
947 SymbolRefAttr oldAttr = scope.symbol;
951 [&](SymbolRefAttr attr) -> std::pair<Attribute, WalkResult> {
958 auto oldNestedRefs = oldAttr.getNestedReferences();
959 auto nestedRefs = attr.getNestedReferences();
960 if (oldNestedRefs.empty())
961 return {SymbolRefAttr::get(newSymbol, nestedRefs),
964 auto newNestedRefs = llvm::to_vector<4>(nestedRefs);
965 newNestedRefs[oldNestedRefs.size() - 1] = newLeafAttr;
966 return {SymbolRefAttr::get(attr.getRootReference(), newNestedRefs),
972 auto walkFn = [&](
Operation *op) -> std::optional<WalkResult> {
976 if (!scope.walkSymbolTable(walkFn))
988 StringAttr newSymbol,
993 StringAttr newSymbol,
998 StringAttr newSymbol,
1003 StringAttr newSymbol,
1013 StringAttr symbol) {
1017 SymbolRefAttr name) {
1021 return symbols.back();
1030 auto lookupFn = [
this](
Operation *symbolTableOp, StringAttr symbol) {
1041 StringAttr symbol) {
1043 return symbolTableOp ?
lookupSymbolIn(symbolTableOp, symbol) :
nullptr;
1047 SymbolRefAttr symbol) {
1049 return symbolTableOp ?
lookupSymbolIn(symbolTableOp, symbol) :
nullptr;
1054 auto it = symbolTables.try_emplace(op,
nullptr);
1056 it.first->second = std::make_unique<SymbolTable>(op);
1057 return *it.first->second;
1061 symbolTables.erase(op);
1069 StringAttr symbol) {
1070 return getSymbolTable(symbolTableOp).lookup(symbol);
1080 SymbolRefAttr name) {
1084 return symbols.back();
1088 Operation *symbolTableOp, SymbolRefAttr name,
1090 auto lookupFn = [
this](
Operation *symbolTableOp, StringAttr symbol) {
1097LockedSymbolTableCollection::getSymbolTable(
Operation *symbolTableOp) {
1101 llvm::sys::SmartScopedReader<true> lock(mutex);
1102 auto it = collection.symbolTables.find(symbolTableOp);
1103 if (it != collection.symbolTables.end())
1108 auto symbolTable = std::make_unique<SymbolTable>(symbolTableOp);
1110 llvm::sys::SmartScopedWriter<true> lock(mutex);
1111 return *collection.symbolTables
1112 .insert({symbolTableOp, std::move(symbolTable)})
1122 : symbolTable(symbolTable) {
1125 auto walkFn = [&](
Operation *symbolTableOp,
bool allUsesVisible) {
1128 assert(symbolUses &&
"expected uses to be valid");
1132 (
void)symbolTable.lookupSymbolIn(symbolTableOp, use.getSymbolRef(),
1135 symbolToUsers[symbolOp].insert(use.getUser());
1146 StringAttr newSymbolName) {
1147 auto it = symbolToUsers.find(symbol);
1148 if (it == symbolToUsers.end())
1158 symbolTable.lookupSymbolIn(symbol->
getParentOp(), newSymbolName);
1159 if (newSymbol != symbol) {
1162 auto newIt = symbolToUsers.try_emplace(newSymbol);
1163 auto oldIt = symbolToUsers.find(symbol);
1164 assert(oldIt != symbolToUsers.end() &&
"missing old users list");
1166 newIt.first->second = std::move(oldIt->second);
1168 newIt.first->second.set_union(oldIt->second);
1169 symbolToUsers.erase(oldIt);
1179 StringRef visibility;
1194#include "mlir/IR/SymbolInterfaces.cpp.inc"
1195#include "mlir/IR/SymbolInterfacesAttrInterface.cpp.inc"
1196#include "mlir/IR/SymbolInterfacesTypeInterface.cpp.inc"
static std::optional< WalkResult > walkSymbolTable(MutableArrayRef< Region > regions, function_ref< std::optional< WalkResult >(Operation *)> callback)
Walk all of the operations within the given set of regions, without traversing into any nested symbol...
static std::optional< SymbolTable::UseRange > getSymbolUsesImpl(FromT from)
The implementation of SymbolTable::getSymbolUses below.
static LogicalResult collectValidReferencesFor(Operation *symbol, StringAttr symbolName, Operation *within, SmallVectorImpl< SymbolRefAttr > &results)
Computes the nested symbol reference attribute for the symbol 'symbolName' that are usable within the...
static bool symbolKnownUseEmptyImpl(SymbolT symbol, IRUnitT *limit)
The implementation of SymbolTable::symbolKnownUseEmpty below.
static SmallVector< SymbolScope, 2 > collectSymbolScopes(Operation *symbol, Operation *limit)
Collect all of the symbol scopes from 'symbol' to (inclusive) 'limit'.
static WalkResult walkSymbolRefs(Operation *op, function_ref< WalkResult(SymbolTable::SymbolUse)> callback)
Walk all of the symbol references within the given operation, invoking the provided callback for each...
static StringAttr getNameIfSymbol(Operation *op)
Returns the string name of the given symbol, or null if this is not a symbol.
static bool isReferencePrefixOf(SymbolRefAttr subRef, SymbolRefAttr ref)
Returns true if the given reference 'SubRef' is a sub reference of the reference 'ref',...
static std::optional< WalkResult > walkSymbolUses(MutableArrayRef< Region > regions, function_ref< WalkResult(SymbolTable::SymbolUse)> callback)
Walk all of the uses, for any symbol, that are nested within the given regions, invoking the provided...
static SymbolRefAttr generateNewRefAttr(SymbolRefAttr oldAttr, FlatSymbolRefAttr newLeafAttr)
Generates a new symbol reference attribute with a new leaf reference.
static LogicalResult verifyOpTypeSymbolUses(Operation *op, SymbolTableCollection &symbolTable, SetVector< Type > &verifiedTypes)
Verify the symbol uses held by the types owned by op: its operand, result, and block-argument types,...
static LogicalResult replaceAllSymbolUsesImpl(SymbolT symbol, StringAttr newSymbol, IRUnitT *limit)
The implementation of SymbolTable::replaceAllSymbolUses below.
static LogicalResult lookupSymbolInImpl(Operation *symbolTableOp, SymbolRefAttr symbol, SmallVectorImpl< Operation * > &symbols, function_ref< Operation *(Operation *, StringAttr)> lookupSymbolFn)
Internal implementation of lookupSymbolIn that allows for specialized implementations of the lookup f...
static bool isPotentiallyUnknownSymbolTable(Operation *op)
Return true if the given operation is unknown and may potentially define a symbol table.
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
This is an attribute/type replacer that is naively cached.
Attributes are known-constant values of operations.
This class represents an argument of a Block.
Block represents an ordered list of Operations.
OpListType::iterator iterator
StringAttr getStringAttr(const Twine &bytes)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
Diagnostic & append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args)
Append arguments to the diagnostic.
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
StringAttr getAttr() const
Returns the name of the held symbol reference as a StringAttr.
InFlightDiagnostic & append(Args &&...args) &
Append arguments to the diagnostic.
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Operation * lookupSymbolIn(Operation *symbolTableOp, StringAttr symbol) override
Look up a symbol with the specified name within the specified symbol table operation,...
MLIRContext is the top-level object for a collection of MLIR operations.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This class provides the API for ops that are known to be terminators.
A trait used to provide symbol table functionalities to a region operation.
Operation is the basic unit of execution within MLIR.
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
AttrClass getAttrOfType(StringAttr name)
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
unsigned getNumRegions()
Returns the number of regions held by this operation.
Location getLoc()
The source location the operation was defined or derived from.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
auto getDiscardableAttrs()
Return a range of all of discardable attributes on this operation.
operand_type_range getOperandTypes()
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
result_type_range getResultTypes()
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
MLIRContext * getContext()
Return the context this operation is associated with.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
void erase()
Remove this operation from its parent block and delete it.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
iterator_range< OpIterator > getOps()
Operation * getParentOp()
Return the parent operation this region is attached to.
bool hasOneBlock()
Return true if this region has exactly one block.
This class represents a collection of SymbolTables.
virtual Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
virtual Operation * lookupSymbolIn(Operation *symbolTableOp, StringAttr symbol)
Look up a symbol with the specified name within the specified symbol table operation,...
virtual void invalidateSymbolTable(Operation *op)
Invalidate the cached symbol table for an operation.
virtual SymbolTable & getSymbolTable(Operation *op)
Lookup, or create, a symbol table for an operation.
This class represents a specific symbol use.
This class implements a range of SymbolRef uses.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
static SmallString< N > generateSymbolName(StringRef name, UniqueChecker uniqueChecker, unsigned &uniquingCounter)
Generate a unique symbol name.
static Visibility getSymbolVisibility(Operation *symbol)
Returns the visibility of the given symbol operation.
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
static void setSymbolVisibility(Operation *symbol, Visibility vis)
Sets the visibility of the given symbol operation.
static LogicalResult replaceAllSymbolUses(StringAttr oldSymbol, StringAttr newSymbol, Operation *from)
Attempt to replace all uses of the given symbol 'oldSymbol' with the provided symbol 'newSymbol' that...
Visibility
An enumeration detailing the different visibility types that a symbol may have.
@ Nested
The symbol is visible to the current IR, which may include operations in symbol tables above the one ...
@ Public
The symbol is public and may be referenced anywhere internal or external to the visible references in...
@ Private
The symbol is private and may only be referenced by SymbolRefAttrs local to the operations within the...
static StringRef getVisibilityAttrName()
Return the name of the attribute used for symbol visibility.
LogicalResult rename(StringAttr from, StringAttr to)
Renames the given op or the op refered to by the given name to the given new name and updates the sym...
void erase(Operation *symbol)
Erase the given symbol from the table and delete the operation.
Operation * getOp() const
Returns the associated operation.
static Operation * lookupSymbolIn(Operation *op, StringAttr symbol)
Returns the operation registered with the given symbol name with the regions of 'symbolTableOp'.
Operation * lookup(StringRef name) const
Look up a symbol with the specified name, returning null if no such name exists.
SymbolTable(Operation *symbolTableOp)
Build a symbol table with the symbols within the given operation.
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
static void setSymbolName(Operation *symbol, StringAttr name)
Sets the name of the given symbol operation.
static bool symbolKnownUseEmpty(StringAttr symbol, Operation *from)
Return if the given symbol is known to have no uses that are nested within the given operation 'from'...
FailureOr< StringAttr > renameToUnique(StringAttr from, ArrayRef< SymbolTable * > others)
Renames the given op or the op refered to by the given name to the a name that is unique within this ...
static void walkSymbolTables(Operation *op, bool allSymUsesVisible, function_ref< void(Operation *, bool)> callback)
Walks all symbol table operations nested within, and including, op.
static StringAttr getSymbolName(Operation *symbol)
Returns the name of the given symbol operation, aborting if no symbol is present.
static std::optional< UseRange > getSymbolUses(Operation *from)
Get an iterator range for all of the uses, for any symbol, that are nested within the given operation...
StringAttr insert(Operation *symbol, Block::iterator insertPt={})
Insert a new symbol into the table, and rename it as necessary to avoid collisions.
void remove(Operation *op)
Remove the given symbol from the table, without deleting it.
static Operation * getNearestSymbolTable(Operation *from)
Returns the nearest symbol table from a given operation from.
void replaceAllUsesWith(Operation *symbol, StringAttr newSymbolName)
Replace all of the uses of the given symbol with newSymbolName.
SymbolUserMap(SymbolTableCollection &symbolTable, Operation *symbolTableOp)
Build a user map for all of the symbols defined in regions nested under 'symbolTableOp'.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
A utility result that is used to signal how to proceed with an ongoing walk:
static WalkResult advance()
bool wasInterrupted() const
Returns true if the walk was interrupted.
static WalkResult interrupt()
void addReplacement(ReplaceFn< Attribute > fn)
AttrTypeReplacerBase.
void replaceElementsIn(Operation *op, bool replaceAttrs=true, bool replaceLocs=false, bool replaceTypes=false)
Replace the elements within the given operation.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
LogicalResult verifySymbol(Operation *op)
LogicalResult verifySymbolTable(Operation *op)
ParseResult parseOptionalVisibilityKeyword(OpAsmParser &parser, NamedAttrList &attrs)
Parse an optional visibility attribute keyword (i.e., public, private, or nested) without quotes in a...
Include the generated interface declarations.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
llvm::SetVector< T, Vector, Set, N > SetVector
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
llvm::StringSwitch< T, R > StringSwitch
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
llvm::function_ref< Fn > function_ref