Remove const from Value, Instruction, Argument, and the various methods on the

*Op classes.  This is a net reduction by almost 400LOC.

PiperOrigin-RevId: 239972443
This commit is contained in:
Chris Lattner 2019-03-23 15:09:06 -07:00 committed by jpienaar
parent b236041b93
commit 986310a68f
51 changed files with 494 additions and 836 deletions

View File

@ -35,7 +35,7 @@ class FuncBuilder;
/// A utility function to check if a value is defined at the top level of a
/// function. A value defined at the top level is always a valid symbol.
bool isTopLevelSymbol(const Value *value);
bool isTopLevelSymbol(Value *value);
class AffineOpsDialect : public Dialect {
public:
@ -64,15 +64,15 @@ public:
ArrayRef<Value *> operands);
/// Returns the affine map to be applied by this operation.
AffineMap getAffineMap() const {
AffineMap getAffineMap() {
return getAttrOfType<AffineMapAttr>("map").getValue();
}
/// Returns true if the result of this operation can be used as dimension id.
bool isValidDim() const;
bool isValidDim();
/// Returns true if the result of this operation is a symbol.
bool isValidSymbol() const;
bool isValidSymbol();
static StringRef getOperationName() { return "affine.apply"; }
@ -87,7 +87,7 @@ public:
private:
friend class Instruction;
explicit AffineApplyOp(const Instruction *state) : Op(state) {}
explicit AffineApplyOp(Instruction *state) : Op(state) {}
};
/// The "for" instruction represents an affine loop nest, defining an SSA value
@ -141,16 +141,13 @@ public:
Block *createBody();
/// Get the body of the AffineForOp.
Block *getBody() const { return &getRegion().front(); }
Block *getBody() { return &getRegion().front(); }
/// Get the body region of the AffineForOp.
Region &getRegion() const { return getInstruction()->getRegion(0); }
Region &getRegion() { return getInstruction()->getRegion(0); }
/// Returns the induction variable for this loop.
Value *getInductionVar();
const Value *getInductionVar() const {
return const_cast<AffineForOp *>(this)->getInductionVar();
}
//===--------------------------------------------------------------------===//
// Bounds and step
@ -161,29 +158,27 @@ public:
/// Returns operands for the lower bound map.
operand_range getLowerBoundOperands();
const_operand_range getLowerBoundOperands() const;
/// Returns operands for the upper bound map.
operand_range getUpperBoundOperands();
const_operand_range getUpperBoundOperands() const;
/// Returns information about the lower bound as a single object.
const AffineBound getLowerBound() const;
AffineBound getLowerBound();
/// Returns information about the upper bound as a single object.
const AffineBound getUpperBound() const;
AffineBound getUpperBound();
/// Returns loop step.
int64_t getStep() const {
int64_t getStep() {
return getAttr(getStepAttrName()).cast<IntegerAttr>().getInt();
}
/// Returns affine map for the lower bound.
AffineMap getLowerBoundMap() const {
AffineMap getLowerBoundMap() {
return getAttr(getLowerBoundAttrName()).cast<AffineMapAttr>().getValue();
}
/// Returns affine map for the upper bound. The upper bound is exclusive.
AffineMap getUpperBoundMap() const {
AffineMap getUpperBoundMap() {
return getAttr(getUpperBoundAttrName()).cast<AffineMapAttr>().getValue();
}
@ -209,19 +204,19 @@ public:
}
/// Returns true if the lower bound is constant.
bool hasConstantLowerBound() const;
bool hasConstantLowerBound();
/// Returns true if the upper bound is constant.
bool hasConstantUpperBound() const;
bool hasConstantUpperBound();
/// Returns true if both bounds are constant.
bool hasConstantBounds() const {
bool hasConstantBounds() {
return hasConstantLowerBound() && hasConstantUpperBound();
}
/// Returns the value of the constant lower bound.
/// Fails assertion if the bound is non-constant.
int64_t getConstantLowerBound() const;
int64_t getConstantLowerBound();
/// Returns the value of the constant upper bound. The upper bound is
/// exclusive. Fails assertion if the bound is non-constant.
int64_t getConstantUpperBound() const;
int64_t getConstantUpperBound();
/// Sets the lower bound to the given constant value.
void setConstantLowerBound(int64_t value);
/// Sets the upper bound to the given constant value.
@ -229,19 +224,19 @@ public:
/// Returns true if both the lower and upper bound have the same operand lists
/// (same operands in the same order).
bool matchingBoundOperandList() const;
bool matchingBoundOperandList();
private:
friend class Instruction;
explicit AffineForOp(const Instruction *state) : Op(state) {}
explicit AffineForOp(Instruction *state) : Op(state) {}
};
/// Returns if the provided value is the induction variable of a AffineForOp.
bool isForInductionVar(const Value *val);
bool isForInductionVar(Value *val);
/// Returns the loop parent of an induction variable. If the provided value is
/// not an induction variable, then return nullptr.
OpPointer<AffineForOp> getForInductionVarOwner(const Value *val);
OpPointer<AffineForOp> getForInductionVarOwner(Value *val);
/// Extracts the induction variables from a list of AffineForOps and places them
/// in the output argument `ivs`.
@ -262,7 +257,7 @@ public:
AffineValueMap getAsAffineValueMap();
unsigned getNumOperands() const { return opEnd - opStart; }
const Value *getOperand(unsigned idx) const {
Value *getOperand(unsigned idx) const {
return inst->getInstruction()->getOperand(opStart + idx);
}
@ -323,20 +318,14 @@ public:
static StringRef getOperationName() { return "if"; }
static StringRef getConditionAttrName() { return "condition"; }
IntegerSet getIntegerSet() const;
IntegerSet getIntegerSet();
void setIntegerSet(IntegerSet newSet);
/// Returns the 'then' region.
Region &getThenBlocks();
Region &getThenBlocks() const {
return const_cast<AffineIfOp *>(this)->getThenBlocks();
}
/// Returns the 'else' blocks.
Region &getElseBlocks();
Region &getElseBlocks() const {
return const_cast<AffineIfOp *>(this)->getElseBlocks();
}
bool verify();
static bool parse(OpAsmParser *parser, OperationState *result);
@ -344,14 +333,14 @@ public:
private:
friend class Instruction;
explicit AffineIfOp(const Instruction *state) : Op(state) {}
explicit AffineIfOp(Instruction *state) : Op(state) {}
};
/// Returns true if the given Value can be used as a dimension id.
bool isValidDim(const Value *value);
bool isValidDim(Value *value);
/// Returns true if the given Value can be used as a symbol.
bool isValidSymbol(const Value *value);
bool isValidSymbol(Value *value);
/// Modifies both `map` and `operands` in-place so as to:
/// 1. drop duplicate operands

View File

@ -443,16 +443,16 @@ public:
/// Sets the identifier corresponding to the specified Value id to a
/// constant. Asserts if the 'id' is not found.
void setIdToConstant(const Value &id, int64_t val);
void setIdToConstant(Value &id, int64_t val);
/// Looks up the position of the identifier with the specified Value. Returns
/// true if found (false otherwise). `pos' is set to the (column) position of
/// the identifier.
bool findId(const Value &id, unsigned *pos) const;
bool findId(Value &id, unsigned *pos) const;
/// Returns true if an identifier with the specified Value exists, false
/// otherwise.
bool containsId(const Value &id) const;
bool containsId(Value &id) const;
// Add identifiers of the specified kind - specified positions are relative to
// the kind of identifier. The coefficient column corresponding to the added

View File

@ -66,18 +66,18 @@ public:
using super::super;
/// Return true if instruction A properly dominates instruction B.
bool properlyDominates(const Instruction *a, const Instruction *b);
bool properlyDominates(Instruction *a, Instruction *b);
/// Return true if instruction A dominates instruction B.
bool dominates(const Instruction *a, const Instruction *b) {
bool dominates(Instruction *a, Instruction *b) {
return a == b || properlyDominates(a, b);
}
/// Return true if value A properly dominates instruction B.
bool properlyDominates(const Value *a, const Instruction *b);
bool properlyDominates(Value *a, Instruction *b);
/// Return true if instruction A dominates instruction B.
bool dominates(const Value *a, const Instruction *b) {
bool dominates(Value *a, Instruction *b) {
return (Instruction *)a->getDefiningInst() == b || properlyDominates(a, b);
}
@ -98,10 +98,10 @@ public:
using super::super;
/// Return true if instruction A properly postdominates instruction B.
bool properlyPostDominates(const Instruction *a, const Instruction *b);
bool properlyPostDominates(Instruction *a, Instruction *b);
/// Return true if instruction A postdominates instruction B.
bool postDominates(const Instruction *a, const Instruction *b) {
bool postDominates(Instruction *a, Instruction *b) {
return a == b || properlyPostDominates(a, b);
}

View File

@ -72,7 +72,7 @@ uint64_t getLargestDivisorOfTripCount(OpPointer<AffineForOp> forOp);
///
/// Returns false in cases with more than one AffineApplyOp, this is
/// conservative.
bool isAccessInvariant(const Value &iv, const Value &index);
bool isAccessInvariant(Value &iv, Value &index);
/// Given an induction variable `iv` of type AffineForOp and `indices` of type
/// IndexType, returns the set of `indices` that are independent of `iv`.
@ -83,8 +83,8 @@ bool isAccessInvariant(const Value &iv, const Value &index);
///
/// Returns false in cases with more than one AffineApplyOp, this is
/// conservative.
llvm::DenseSet<const Value *, llvm::DenseMapInfo<const Value *>>
getInvariantAccesses(const Value &iv, llvm::ArrayRef<const Value *> indices);
llvm::DenseSet<Value *, llvm::DenseMapInfo<Value *>>
getInvariantAccesses(Value &iv, llvm::ArrayRef<Value *> indices);
/// Checks whether the loop is structurally vectorizable; i.e.:
/// 1. the loop has proper dependence semantics (parallel, reduction, etc);

View File

@ -94,8 +94,8 @@ private:
/// aggressive unrolling. As experience has shown, it is generally better to use
/// a plain walk over instructions to match flat patterns but the current
/// implementation is competitive nonetheless.
using FilterFunctionType = std::function<bool(const Instruction &)>;
static bool defaultFilterFunction(const Instruction &) { return true; };
using FilterFunctionType = std::function<bool(Instruction &)>;
static bool defaultFilterFunction(Instruction &) { return true; };
struct NestedPattern {
NestedPattern(ArrayRef<NestedPattern> nested,
FilterFunctionType filter = defaultFilterFunction);
@ -182,9 +182,9 @@ NestedPattern For(ArrayRef<NestedPattern> nested = {});
NestedPattern For(FilterFunctionType filter,
ArrayRef<NestedPattern> nested = {});
bool isParallelLoop(const Instruction &inst);
bool isReductionLoop(const Instruction &inst);
bool isLoadOrStore(const Instruction &inst);
bool isParallelLoop(Instruction &inst);
bool isReductionLoop(Instruction &inst);
bool isLoadOrStore(Instruction &inst);
} // end namespace matcher
} // end namespace mlir

View File

@ -48,12 +48,12 @@ class Value;
/// Populates 'loops' with IVs of the loops surrounding 'inst' ordered from
/// the outermost 'for' instruction to the innermost one.
// TODO(bondhugula): handle 'if' inst's.
void getLoopIVs(const Instruction &inst,
void getLoopIVs(Instruction &inst,
SmallVectorImpl<OpPointer<AffineForOp>> *loops);
/// Returns the nesting depth of this instruction, i.e., the number of loops
/// surrounding this instruction.
unsigned getNestingDepth(const Instruction &stmt);
unsigned getNestingDepth(Instruction &inst);
/// Returns in 'sequentialLoops' all sequential loops in loop nest rooted
/// at 'forOp'.
@ -231,8 +231,7 @@ LogicalResult boundCheckLoadOrStoreOp(LoadOrStoreOpPointer loadOrStoreOp,
bool emitError = true);
/// Returns the number of surrounding loops common to both A and B.
unsigned getNumCommonSurroundingLoops(const Instruction &A,
const Instruction &B);
unsigned getNumCommonSurroundingLoops(Instruction &A, Instruction &B);
/// Gets the memory footprint of all data touched in the specified memory space
/// in bytes; if the memory space is unspecified, considers all memory spaces.

View File

@ -135,7 +135,7 @@ namespace matcher {
/// TODO(ntv): this could all be much simpler if we added a bit that a vector
/// type to mark that a vector is a strict super-vector but it still does not
/// warrant adding even 1 extra bit in the IR for now.
bool operatesOnSuperVectors(const Instruction &inst, VectorType subVectorType);
bool operatesOnSuperVectors(Instruction &inst, VectorType subVectorType);
} // end namespace matcher
} // end namespace mlir

View File

@ -32,7 +32,7 @@ namespace OpTrait {
// corresponding trait classes. This avoids them being template
// instantiated/duplicated.
namespace impl {
bool verifyCompatibleOperandBroadcast(const Instruction *op);
bool verifyCompatibleOperandBroadcast(Instruction *op);
} // namespace impl
namespace util {
@ -78,7 +78,7 @@ template <typename ConcreteType>
class BroadcastableTwoOperandsOneResult
: public TraitBase<ConcreteType, BroadcastableTwoOperandsOneResult> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyCompatibleOperandBroadcast(op);
}
};

View File

@ -173,7 +173,7 @@ public:
/// the latter fails.
/// TODO: This is very specific functionality that should live somewhere else,
/// probably in Dominance.cpp.
Instruction *findAncestorInstInBlock(const Instruction &inst);
Instruction *findAncestorInstInBlock(Instruction &inst);
/// This drops all operand uses from instructions within this block, which is
/// an essential step in breaking cyclic dependences between references when

View File

@ -37,7 +37,7 @@ public:
/// Inserts a new mapping for 'from' to 'to'. If there is an existing mapping,
/// it is overwritten.
void map(Block *from, Block *to) { valueMap[from] = to; }
void map(const Value *from, Value *to) { valueMap[from] = to; }
void map(Value *from, Value *to) { valueMap[from] = to; }
/// Erases a mapping for 'from'.
void erase(const IRObjectWithUseList *from) { valueMap.erase(from); }
@ -52,7 +52,7 @@ public:
Block *lookupOrNull(Block *from) const {
return lookupOrValue(from, (Block *)nullptr);
}
Value *lookupOrNull(const Value *from) const {
Value *lookupOrNull(Value *from) const {
return lookupOrValue(from, (Value *)nullptr);
}

View File

@ -268,12 +268,12 @@ public:
/// ( leaving them alone if no entry is present). Replaces references to
/// cloned sub-instructions to the corresponding instruction that is copied,
/// and adds those mappings to the map.
Instruction *clone(const Instruction &inst, BlockAndValueMapping &mapper) {
Instruction *clone(Instruction &inst, BlockAndValueMapping &mapper) {
Instruction *cloneInst = inst.clone(mapper, getContext());
block->getInstructions().insert(insertPoint, cloneInst);
return cloneInst;
}
Instruction *clone(const Instruction &inst) {
Instruction *clone(Instruction &inst) {
Instruction *cloneInst = inst.clone(getContext());
block->getInstructions().insert(insertPoint, cloneInst);
return cloneInst;

View File

@ -32,7 +32,7 @@ class Type;
using DialectConstantDecodeHook =
std::function<bool(const OpaqueElementsAttr, ElementsAttr &)>;
using DialectConstantFoldHook = std::function<LogicalResult(
const Instruction *, ArrayRef<Attribute>, SmallVectorImpl<Attribute> &)>;
Instruction *, ArrayRef<Attribute>, SmallVectorImpl<Attribute> &)>;
using DialectExtractElementHook =
std::function<Attribute(const OpaqueElementsAttr, ArrayRef<uint64_t>)>;
@ -57,7 +57,7 @@ public:
/// `results` vector. If not, this returns failure and `results` is
/// unspecified.
DialectConstantFoldHook constantFoldHook =
[](const Instruction *op, ArrayRef<Attribute> operands,
[](Instruction *op, ArrayRef<Attribute> operands,
SmallVectorImpl<Attribute> &results) { return failure(); };
/// Registered hook to decode opaque constants associated with this
@ -117,7 +117,7 @@ public:
/// Verify an attribute from this dialect on the given instruction. Returns
/// true if the verification failed, false otherwise.
virtual bool verifyInstructionAttribute(const Instruction *, NamedAttribute) {
virtual bool verifyInstructionAttribute(Instruction *, NamedAttribute) {
return false;
}

View File

@ -68,11 +68,11 @@ public:
bool resizableOperandList, MLIRContext *context);
/// The name of an operation is the key identifier for it.
OperationName getName() const { return name; }
OperationName getName() { return name; }
/// If this operation has a registered operation description, return it.
/// Otherwise return null.
const AbstractOperation *getAbstractOperation() const {
const AbstractOperation *getAbstractOperation() {
return getName().getAbstractOperation();
}
@ -84,29 +84,29 @@ public:
/// them alone if no entry is present). Replaces references to cloned
/// sub-instructions to the corresponding instruction that is copied, and adds
/// those mappings to the map.
Instruction *clone(BlockAndValueMapping &mapper, MLIRContext *context) const;
Instruction *clone(MLIRContext *context) const;
Instruction *clone(BlockAndValueMapping &mapper, MLIRContext *context);
Instruction *clone(MLIRContext *context);
/// Returns the instruction block that contains this instruction.
Block *getBlock() const { return block; }
Block *getBlock() { return block; }
/// Return the context this operation is associated with.
MLIRContext *getContext() const;
MLIRContext *getContext();
/// The source location the operation was defined or derived from.
Location getLoc() const { return location; }
Location getLoc() { return location; }
/// Set the source location the operation was defined or derived from.
void setLoc(Location loc) { location = loc; }
/// Returns the closest surrounding instruction that contains this instruction
/// or nullptr if this is a top-level instruction.
Instruction *getParentInst() const;
Instruction *getParentInst();
/// Returns the function that this instruction is part of.
/// The function is determined by traversing the chain of parent instructions.
/// Returns nullptr if the instruction is unlinked.
Function *getFunction() const;
Function *getFunction();
/// Destroys this instruction and its subclass data.
void destroy();
@ -130,10 +130,10 @@ public:
/// of the parent block.
/// Note: This function has an average complexity of O(1), but worst case may
/// take O(N) where N is the number of instructions within the parent block.
bool isBeforeInBlock(const Instruction *other) const;
bool isBeforeInBlock(Instruction *other);
void print(raw_ostream &os) const;
void dump() const;
void print(raw_ostream &os);
void dump();
//===--------------------------------------------------------------------===//
// Operands
@ -141,9 +141,7 @@ public:
/// Returns if the operation has a resizable operation list, i.e. operands can
/// be added.
bool hasResizableOperandsList() const {
return getOperandStorage().isResizable();
}
bool hasResizableOperandsList() { return getOperandStorage().isResizable(); }
/// Replace the current operands of this operation with the ones provided in
/// 'operands'. If the operands list is not resizable, the size of 'operands'
@ -152,12 +150,9 @@ public:
getOperandStorage().setOperands(this, operands);
}
unsigned getNumOperands() const { return getOperandStorage().size(); }
unsigned getNumOperands() { return getOperandStorage().size(); }
Value *getOperand(unsigned idx) { return getInstOperand(idx).get(); }
const Value *getOperand(unsigned idx) const {
return getInstOperand(idx).get();
}
void setOperand(unsigned idx, Value *value) {
return getInstOperand(idx).set(value);
}
@ -172,77 +167,40 @@ public:
/// Returns an iterator on the underlying Value's (Value *).
operand_range getOperands();
// Support const operand iteration.
using const_operand_iterator =
OperandIterator<const Instruction, const Value>;
using const_operand_range = llvm::iterator_range<const_operand_iterator>;
const_operand_iterator operand_begin() const;
const_operand_iterator operand_end() const;
/// Returns a const iterator on the underlying Value's (Value *).
llvm::iterator_range<const_operand_iterator> getOperands() const;
ArrayRef<InstOperand> getInstOperands() const {
return getOperandStorage().getInstOperands();
}
MutableArrayRef<InstOperand> getInstOperands() {
return getOperandStorage().getInstOperands();
}
InstOperand &getInstOperand(unsigned idx) { return getInstOperands()[idx]; }
const InstOperand &getInstOperand(unsigned idx) const {
return getInstOperands()[idx];
}
//===--------------------------------------------------------------------===//
// Results
//===--------------------------------------------------------------------===//
/// Return true if there are no users of any results of this operation.
bool use_empty() const;
bool use_empty();
unsigned getNumResults() const { return numResults; }
unsigned getNumResults() { return numResults; }
Value *getResult(unsigned idx) { return &getInstResult(idx); }
const Value *getResult(unsigned idx) const { return &getInstResult(idx); }
// Support non-const result iteration.
// Support result iteration.
using result_iterator = ResultIterator<Instruction, Value>;
result_iterator result_begin();
result_iterator result_end();
llvm::iterator_range<result_iterator> getResults();
// Support const result iteration.
using const_result_iterator = ResultIterator<const Instruction, const Value>;
const_result_iterator result_begin() const;
const_result_iterator result_end() const;
llvm::iterator_range<const_result_iterator> getResults() const;
ArrayRef<InstResult> getInstResults() const {
return {getTrailingObjects<InstResult>(), numResults};
}
MutableArrayRef<InstResult> getInstResults() {
return {getTrailingObjects<InstResult>(), numResults};
}
InstResult &getInstResult(unsigned idx) { return getInstResults()[idx]; }
const InstResult &getInstResult(unsigned idx) const {
return getInstResults()[idx];
}
// Support result type iteration.
using result_type_iterator =
ResultTypeIterator<const Instruction, const Type>;
result_type_iterator result_type_begin() const;
result_type_iterator result_type_end() const;
llvm::iterator_range<result_type_iterator> getResultTypes() const;
using result_type_iterator = ResultTypeIterator<Instruction, Type>;
result_type_iterator result_type_begin();
result_type_iterator result_type_end();
llvm::iterator_range<result_type_iterator> getResultTypes();
//===--------------------------------------------------------------------===//
// Attributes
@ -253,17 +211,17 @@ public:
// the lifetime of an instruction.
/// Return all of the attributes on this instruction.
ArrayRef<NamedAttribute> getAttrs() const { return attrs.getAttrs(); }
ArrayRef<NamedAttribute> getAttrs() { return attrs.getAttrs(); }
/// Return the specified attribute if present, null otherwise.
Attribute getAttr(Identifier name) const { return attrs.get(name); }
Attribute getAttr(StringRef name) const { return attrs.get(name); }
Attribute getAttr(Identifier name) { return attrs.get(name); }
Attribute getAttr(StringRef name) { return attrs.get(name); }
template <typename AttrClass> AttrClass getAttrOfType(Identifier name) const {
template <typename AttrClass> AttrClass getAttrOfType(Identifier name) {
return getAttr(name).dyn_cast_or_null<AttrClass>();
}
template <typename AttrClass> AttrClass getAttrOfType(StringRef name) const {
template <typename AttrClass> AttrClass getAttrOfType(StringRef name) {
return getAttr(name).dyn_cast_or_null<AttrClass>();
}
@ -287,16 +245,16 @@ public:
//===--------------------------------------------------------------------===//
/// Returns the number of regions held by this operation.
unsigned getNumRegions() const { return numRegions; }
unsigned getNumRegions() { return numRegions; }
/// Returns the regions held by this operation.
MutableArrayRef<Region> getRegions() const {
MutableArrayRef<Region> getRegions() {
auto *regions = getTrailingObjects<Region>();
return {const_cast<Region *>(regions), numRegions};
return {regions, numRegions};
}
/// Returns the region held by this operation at position 'index'.
Region &getRegion(unsigned index) const {
Region &getRegion(unsigned index) {
assert(index < numRegions && "invalid region index");
return getRegions()[index];
}
@ -308,15 +266,10 @@ public:
MutableArrayRef<BlockOperand> getBlockOperands() {
return {getTrailingObjects<BlockOperand>(), numSuccs};
}
ArrayRef<BlockOperand> getBlockOperands() const {
return const_cast<Instruction *>(this)->getBlockOperands();
}
/// Return the operands of this operation that are *not* successor arguments.
const_operand_range getNonSuccessorOperands() const;
operand_range getNonSuccessorOperands();
const_operand_range getSuccessorOperands(unsigned index) const;
operand_range getSuccessorOperands(unsigned index);
Value *getSuccessorOperand(unsigned succIndex, unsigned opIndex) {
@ -324,19 +277,15 @@ public:
assert(opIndex < getNumSuccessorOperands(succIndex));
return getOperand(getSuccessorOperandIndex(succIndex) + opIndex);
}
const Value *getSuccessorOperand(unsigned succIndex, unsigned index) const {
return const_cast<Instruction *>(this)->getSuccessorOperand(succIndex,
index);
}
unsigned getNumSuccessors() const { return numSuccs; }
unsigned getNumSuccessorOperands(unsigned index) const {
unsigned getNumSuccessors() { return numSuccs; }
unsigned getNumSuccessorOperands(unsigned index) {
assert(!isKnownNonTerminator() && "only terminators may have successors");
assert(index < getNumSuccessors());
return getTrailingObjects<unsigned>()[index];
}
Block *getSuccessor(unsigned index) const {
Block *getSuccessor(unsigned index) {
assert(index < getNumSuccessors());
return getBlockOperands()[index].get();
}
@ -354,21 +303,21 @@ public:
/// Get the index of the first operand of the successor at the provided
/// index.
unsigned getSuccessorOperandIndex(unsigned index) const;
unsigned getSuccessorOperandIndex(unsigned index);
//===--------------------------------------------------------------------===//
// Accessors for various properties of operations
//===--------------------------------------------------------------------===//
/// Returns whether the operation is commutative.
bool isCommutative() const {
bool isCommutative() {
if (auto *absOp = getAbstractOperation())
return absOp->hasProperty(OperationProperty::Commutative);
return false;
}
/// Returns whether the operation has side-effects.
bool hasNoSideEffect() const {
bool hasNoSideEffect() {
if (auto *absOp = getAbstractOperation())
return absOp->hasProperty(OperationProperty::NoSideEffect);
return false;
@ -380,7 +329,7 @@ public:
enum class TerminatorStatus { Terminator, NonTerminator, Unknown };
/// Returns the status of whether this operation is a terminator or not.
TerminatorStatus getTerminatorStatus() const {
TerminatorStatus getTerminatorStatus() {
if (auto *absOp = getAbstractOperation()) {
return absOp->hasProperty(OperationProperty::Terminator)
? TerminatorStatus::Terminator
@ -390,12 +339,12 @@ public:
}
/// Returns if the operation is known to be a terminator.
bool isKnownTerminator() const {
bool isKnownTerminator() {
return getTerminatorStatus() == TerminatorStatus::Terminator;
}
/// Returns if the operation is known to *not* be a terminator.
bool isKnownNonTerminator() const {
bool isKnownNonTerminator() {
return getTerminatorStatus() == TerminatorStatus::NonTerminator;
}
@ -405,7 +354,7 @@ public:
/// constant folding is successful, this fills in the `results` vector. If
/// not, `results` is unspecified.
LogicalResult constantFold(ArrayRef<Attribute> operands,
SmallVectorImpl<Attribute> &results) const;
SmallVectorImpl<Attribute> &results);
/// Attempt to fold this operation using the Op's registered foldHook.
LogicalResult fold(SmallVectorImpl<Value *> &results);
@ -421,7 +370,7 @@ public:
/// The dyn_cast methods perform a dynamic cast from an Instruction to a typed
/// Op like DimOp. This returns a null OpPointer on failure.
template <typename OpClass> OpPointer<OpClass> dyn_cast() const {
template <typename OpClass> OpPointer<OpClass> dyn_cast() {
if (isa<OpClass>()) {
return cast<OpClass>();
} else {
@ -432,16 +381,14 @@ public:
/// The cast methods perform a cast from an Instruction to a typed Op like
/// DimOp. This aborts if the parameter to the template isn't an instance of
/// the template type argument.
template <typename OpClass> OpPointer<OpClass> cast() const {
template <typename OpClass> OpPointer<OpClass> cast() {
assert(isa<OpClass>() && "cast<Ty>() argument of incompatible type!");
return OpPointer<OpClass>(OpClass(this));
}
/// The is methods return true if the operation is a typed op (like DimOp) of
/// of the given class.
template <typename OpClass> bool isa() const {
return OpClass::isClassFor(const_cast<Instruction *>(this));
}
template <typename OpClass> bool isa() { return OpClass::isClassFor(this); }
//===--------------------------------------------------------------------===//
// Instruction Walkers
@ -479,21 +426,21 @@ public:
/// Emit an error with the op name prefixed, like "'dim' op " which is
/// convenient for verifiers. This function always returns true.
bool emitOpError(const Twine &message) const;
bool emitOpError(const Twine &message);
/// Emit an error about fatal conditions with this operation, reporting up to
/// any diagnostic handlers that may be listening. This function always
/// returns true. NOTE: This may terminate the containing application, only
/// use when the IR is in an inconsistent state.
bool emitError(const Twine &message) const;
bool emitError(const Twine &message);
/// Emit a warning about this operation, reporting up to any diagnostic
/// handlers that may be listening.
void emitWarning(const Twine &message) const;
void emitWarning(const Twine &message);
/// Emit a note about this operation, reporting up to any diagnostic
/// handlers that may be listening.
void emitNote(const Twine &message) const;
void emitNote(const Twine &message);
private:
Instruction(Location location, OperationName name, unsigned numResults,
@ -508,12 +455,9 @@ private:
detail::OperandStorage &getOperandStorage() {
return *getTrailingObjects<detail::OperandStorage>();
}
const detail::OperandStorage &getOperandStorage() const {
return *getTrailingObjects<detail::OperandStorage>();
}
// Provide a 'getParent' method for ilist_node_with_parent methods.
Block *getParent() const { return getBlock(); }
Block *getParent() { return getBlock(); }
/// The instruction block that containts this instruction.
Block *block = nullptr;
@ -556,7 +500,7 @@ private:
size_t numTrailingObjects(OverloadToken<unsigned>) const { return numSuccs; }
};
inline raw_ostream &operator<<(raw_ostream &os, const Instruction &inst) {
inline raw_ostream &operator<<(raw_ostream &os, Instruction &inst) {
inst.print(os);
return os;
}
@ -573,13 +517,6 @@ public:
: IndexedAccessorIterator<OperandIterator<ObjectType, ElementType>,
ObjectType, ElementType>(object, index) {}
/// Support converting to the const variant. This will be a no-op for const
/// variant.
operator OperandIterator<const ObjectType, const ElementType>() const {
return OperandIterator<const ObjectType, const ElementType>(this->object,
this->index);
}
ElementType *operator*() const {
return this->object->getOperand(this->index);
}
@ -598,18 +535,6 @@ inline auto Instruction::getOperands() -> operand_range {
return {operand_begin(), operand_end()};
}
inline auto Instruction::operand_begin() const -> const_operand_iterator {
return const_operand_iterator(this, 0);
}
inline auto Instruction::operand_end() const -> const_operand_iterator {
return const_operand_iterator(this, getNumOperands());
}
inline auto Instruction::getOperands() const -> const_operand_range {
return {operand_begin(), operand_end()};
}
/// This template implements the result iterators for the Instruction class
/// in terms of getResult(idx).
template <typename ObjectType, typename ElementType>
@ -622,13 +547,6 @@ public:
: IndexedAccessorIterator<ResultIterator<ObjectType, ElementType>,
ObjectType, ElementType>(object, index) {}
/// Support converting to the const variant. This will be a no-op for const
/// variant.
operator ResultIterator<const ObjectType, const ElementType>() const {
return ResultIterator<const ObjectType, const ElementType>(this->object,
this->index);
}
ElementType *operator*() const {
return this->object->getResult(this->index);
}
@ -672,28 +590,15 @@ inline auto Instruction::getResults() -> llvm::iterator_range<result_iterator> {
return {result_begin(), result_end()};
}
inline auto Instruction::result_begin() const -> const_result_iterator {
return const_result_iterator(this, 0);
}
inline auto Instruction::result_end() const -> const_result_iterator {
return const_result_iterator(this, getNumResults());
}
inline auto Instruction::getResults() const
-> llvm::iterator_range<const_result_iterator> {
return {result_begin(), result_end()};
}
inline auto Instruction::result_type_begin() const -> result_type_iterator {
inline auto Instruction::result_type_begin() -> result_type_iterator {
return result_type_iterator(this, 0);
}
inline auto Instruction::result_type_end() const -> result_type_iterator {
inline auto Instruction::result_type_end() -> result_type_iterator {
return result_type_iterator(this, getNumResults());
}
inline auto Instruction::getResultTypes() const
inline auto Instruction::getResultTypes()
-> llvm::iterator_range<result_type_iterator> {
return {result_type_begin(), result_type_end()};
}

View File

@ -103,7 +103,7 @@ private:
class OpState {
public:
/// Return the operation that this refers to.
const Instruction *getInstruction() const { return state; }
Instruction *getInstruction() const { return state; }
Instruction *getInstruction() { return state; }
/// The source location the operation was defined or derived from.
@ -176,7 +176,7 @@ protected:
/// Mutability management is handled by the OpWrapper/OpConstWrapper classes,
/// so we can cast it away here.
explicit OpState(const Instruction *state)
explicit OpState(Instruction *state)
: state(const_cast<Instruction *>(state)) {}
private:
@ -327,22 +327,22 @@ namespace OpTrait {
// corresponding trait classes. This avoids them being template
// instantiated/duplicated.
namespace impl {
bool verifyZeroOperands(const Instruction *op);
bool verifyOneOperand(const Instruction *op);
bool verifyNOperands(const Instruction *op, unsigned numOperands);
bool verifyAtLeastNOperands(const Instruction *op, unsigned numOperands);
bool verifyOperandsAreIntegerLike(const Instruction *op);
bool verifySameTypeOperands(const Instruction *op);
bool verifyZeroResult(const Instruction *op);
bool verifyOneResult(const Instruction *op);
bool verifyNResults(const Instruction *op, unsigned numOperands);
bool verifyAtLeastNResults(const Instruction *op, unsigned numOperands);
bool verifySameOperandsAndResultShape(const Instruction *op);
bool verifySameOperandsAndResultType(const Instruction *op);
bool verifyResultsAreBoolLike(const Instruction *op);
bool verifyResultsAreFloatLike(const Instruction *op);
bool verifyResultsAreIntegerLike(const Instruction *op);
bool verifyIsTerminator(const Instruction *op);
bool verifyZeroOperands(Instruction *op);
bool verifyOneOperand(Instruction *op);
bool verifyNOperands(Instruction *op, unsigned numOperands);
bool verifyAtLeastNOperands(Instruction *op, unsigned numOperands);
bool verifyOperandsAreIntegerLike(Instruction *op);
bool verifySameTypeOperands(Instruction *op);
bool verifyZeroResult(Instruction *op);
bool verifyOneResult(Instruction *op);
bool verifyNResults(Instruction *op, unsigned numOperands);
bool verifyAtLeastNResults(Instruction *op, unsigned numOperands);
bool verifySameOperandsAndResultShape(Instruction *op);
bool verifySameOperandsAndResultType(Instruction *op);
bool verifyResultsAreBoolLike(Instruction *op);
bool verifyResultsAreFloatLike(Instruction *op);
bool verifyResultsAreIntegerLike(Instruction *op);
bool verifyIsTerminator(Instruction *op);
} // namespace impl
/// Helper class for implementing traits. Clients are not expected to interact
@ -361,13 +361,13 @@ protected:
auto *base = static_cast<OpState *>(concrete);
return base->getInstruction();
}
const Instruction *getInstruction() const {
Instruction *getInstruction() const {
return const_cast<TraitBase *>(this)->getInstruction();
}
/// Provide default implementations of trait hooks. This allows traits to
/// provide exactly the overrides they care about.
static bool verifyTrait(const Instruction *op) { return false; }
static bool verifyTrait(Instruction *op) { return false; }
static AbstractOperation::OperationProperties getTraitProperties() {
return 0;
}
@ -378,7 +378,7 @@ protected:
template <typename ConcreteType>
class ZeroOperands : public TraitBase<ConcreteType, ZeroOperands> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyZeroOperands(op);
}
@ -393,17 +393,13 @@ private:
template <typename ConcreteType>
class OneOperand : public TraitBase<ConcreteType, OneOperand> {
public:
const Value *getOperand() const {
return this->getInstruction()->getOperand(0);
}
Value *getOperand() { return this->getInstruction()->getOperand(0); }
Value *getOperand() const { return this->getInstruction()->getOperand(0); }
void setOperand(Value *value) {
this->getInstruction()->setOperand(0, value);
}
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyOneOperand(op);
}
};
@ -418,11 +414,7 @@ public:
template <typename ConcreteType>
class Impl : public TraitBase<ConcreteType, NOperands<N>::Impl> {
public:
const Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
Value *getOperand(unsigned i) {
Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
@ -430,7 +422,7 @@ public:
this->getInstruction()->setOperand(i, value);
}
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyNOperands(op, N);
}
};
@ -449,11 +441,7 @@ public:
unsigned getNumOperands() const {
return this->getInstruction()->getNumOperands();
}
const Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
Value *getOperand(unsigned i) {
Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
@ -473,19 +461,7 @@ public:
return this->getInstruction()->getOperands();
}
// Support const operand iteration.
using const_operand_iterator = Instruction::const_operand_iterator;
const_operand_iterator operand_begin() const {
return this->getInstruction()->operand_begin();
}
const_operand_iterator operand_end() const {
return this->getInstruction()->operand_end();
}
llvm::iterator_range<const_operand_iterator> getOperands() const {
return this->getInstruction()->getOperands();
}
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyAtLeastNOperands(op, N);
}
};
@ -500,11 +476,7 @@ public:
return this->getInstruction()->getNumOperands();
}
const Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
Value *getOperand(unsigned i) {
Value *getOperand(unsigned i) const {
return this->getInstruction()->getOperand(i);
}
@ -522,19 +494,6 @@ public:
return this->getInstruction()->operand_end();
}
operand_range getOperands() { return this->getInstruction()->getOperands(); }
// Support const operand iteration.
using const_operand_iterator = Instruction::const_operand_iterator;
using const_operand_range = Instruction::const_operand_range;
const_operand_iterator operand_begin() const {
return this->getInstruction()->operand_begin();
}
const_operand_iterator operand_end() const {
return this->getInstruction()->operand_end();
}
const_operand_range getOperands() const {
return this->getInstruction()->getOperands();
}
};
/// This class provides return value APIs for ops that are known to have
@ -542,7 +501,7 @@ public:
template <typename ConcreteType>
class ZeroResult : public TraitBase<ConcreteType, ZeroResult> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyZeroResult(op);
}
};
@ -552,10 +511,7 @@ public:
template <typename ConcreteType>
class OneResult : public TraitBase<ConcreteType, OneResult> {
public:
Value *getResult() { return this->getInstruction()->getResult(0); }
const Value *getResult() const {
return this->getInstruction()->getResult(0);
}
Value *getResult() const { return this->getInstruction()->getResult(0); }
Type getType() const { return getResult()->getType(); }
@ -566,9 +522,7 @@ public:
getResult()->replaceAllUsesWith(newValue);
}
static bool verifyTrait(const Instruction *op) {
return impl::verifyOneResult(op);
}
static bool verifyTrait(Instruction *op) { return impl::verifyOneResult(op); }
};
/// This class provides the API for ops that are known to have a specified
@ -583,17 +537,13 @@ public:
public:
static unsigned getNumResults() { return N; }
const Value *getResult(unsigned i) const {
return this->getInstruction()->getResult(i);
}
Value *getResult(unsigned i) {
Value *getResult(unsigned i) const {
return this->getInstruction()->getResult(i);
}
Type getType(unsigned i) const { return getResult(i)->getType(); }
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyNResults(op, N);
}
};
@ -609,17 +559,13 @@ public:
template <typename ConcreteType>
class Impl : public TraitBase<ConcreteType, AtLeastNResults<N>::Impl> {
public:
const Value *getResult(unsigned i) const {
return this->getInstruction()->getResult(i);
}
Value *getResult(unsigned i) {
Value *getResult(unsigned i) const {
return this->getInstruction()->getResult(i);
}
Type getType(unsigned i) const { return getResult(i)->getType(); }
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyAtLeastNResults(op, N);
}
};
@ -634,12 +580,10 @@ public:
return this->getInstruction()->getNumResults();
}
const Value *getResult(unsigned i) const {
Value *getResult(unsigned i) const {
return this->getInstruction()->getResult(i);
}
Value *getResult(unsigned i) { return this->getInstruction()->getResult(i); }
void setResult(unsigned i, Value *value) {
this->getInstruction()->setResult(i, value);
}
@ -653,18 +597,6 @@ public:
llvm::iterator_range<result_iterator> getResults() {
return this->getInstruction()->getResults();
}
// Support const result iteration.
using const_result_iterator = Instruction::const_result_iterator;
const_result_iterator result_begin() const {
return this->getInstruction()->result_begin();
}
const_result_iterator result_end() const {
return this->getInstruction()->result_end();
}
llvm::iterator_range<const_result_iterator> getResults() const {
return this->getInstruction()->getResults();
}
};
/// This class provides verification for ops that are known to have the same
@ -674,7 +606,7 @@ template <typename ConcreteType>
class SameOperandsAndResultShape
: public TraitBase<ConcreteType, SameOperandsAndResultShape> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifySameOperandsAndResultShape(op);
}
};
@ -689,7 +621,7 @@ template <typename ConcreteType>
class SameOperandsAndResultType
: public TraitBase<ConcreteType, SameOperandsAndResultType> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifySameOperandsAndResultType(op);
}
};
@ -699,7 +631,7 @@ public:
template <typename ConcreteType>
class ResultsAreBoolLike : public TraitBase<ConcreteType, ResultsAreBoolLike> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyResultsAreBoolLike(op);
}
};
@ -710,7 +642,7 @@ template <typename ConcreteType>
class ResultsAreFloatLike
: public TraitBase<ConcreteType, ResultsAreFloatLike> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyResultsAreFloatLike(op);
}
};
@ -721,7 +653,7 @@ template <typename ConcreteType>
class ResultsAreIntegerLike
: public TraitBase<ConcreteType, ResultsAreIntegerLike> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyResultsAreIntegerLike(op);
}
};
@ -752,7 +684,7 @@ template <typename ConcreteType>
class OperandsAreIntegerLike
: public TraitBase<ConcreteType, OperandsAreIntegerLike> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyOperandsAreIntegerLike(op);
}
};
@ -762,7 +694,7 @@ public:
template <typename ConcreteType>
class SameTypeOperands : public TraitBase<ConcreteType, SameTypeOperands> {
public:
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifySameTypeOperands(op);
}
};
@ -775,7 +707,7 @@ public:
return static_cast<AbstractOperation::OperationProperties>(
OperationProperty::Terminator);
}
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return impl::verifyIsTerminator(op);
}
@ -820,10 +752,7 @@ class Op : public OpState,
Traits<ConcreteType>...>::value> {
public:
/// Return the operation that this refers to.
const Instruction *getInstruction() const {
return OpState::getInstruction();
}
Instruction *getInstruction() { return OpState::getInstruction(); }
Instruction *getInstruction() const { return OpState::getInstruction(); }
/// Return true if this "op class" can match against the specified operation.
/// This hook can be overridden with a more specific implementation in
@ -875,20 +804,20 @@ public:
using ConcreteOpType = ConcreteType;
protected:
explicit Op(const Instruction *state) : OpState(state) {}
explicit Op(Instruction *state) : OpState(state) {}
private:
template <typename... Types> struct BaseVerifier;
template <typename First, typename... Rest>
struct BaseVerifier<First, Rest...> {
static bool verifyTrait(const Instruction *op) {
static bool verifyTrait(Instruction *op) {
return First::verifyTrait(op) || BaseVerifier<Rest...>::verifyTrait(op);
}
};
template <typename...> struct BaseVerifier {
static bool verifyTrait(const Instruction *op) { return false; }
static bool verifyTrait(Instruction *op) { return false; }
};
template <typename... Types> struct BaseProperties;
@ -917,7 +846,7 @@ bool parseBinaryOp(OpAsmParser *parser, OperationState *result);
// Prints the given binary `op` in custom assembly form if both the two operands
// and the result have the same time. Otherwise, prints the generic assembly
// form.
void printBinaryOp(const Instruction *op, OpAsmPrinter *p);
void printBinaryOp(Instruction *op, OpAsmPrinter *p);
} // namespace impl
// These functions are out-of-line implementations of the methods in CastOp,
@ -926,7 +855,7 @@ namespace impl {
void buildCastOp(Builder *builder, OperationState *result, Value *source,
Type destType);
bool parseCastOp(OpAsmParser *parser, OperationState *result);
void printCastOp(const Instruction *op, OpAsmPrinter *p);
void printCastOp(Instruction *op, OpAsmPrinter *p);
} // namespace impl
/// This template is used for operations that are cast operations, that have a
@ -951,7 +880,7 @@ public:
}
protected:
explicit CastOp(const Instruction *state)
explicit CastOp(Instruction *state)
: Op<ConcreteType, OpTrait::OneOperand, OpTrait::OneResult,
OpTrait::HasNoSideEffect, Traits...>(state) {}
};

View File

@ -48,7 +48,7 @@ public:
virtual raw_ostream &getStream() const = 0;
/// Print implementations for various things an operation contains.
virtual void printOperand(const Value *value) = 0;
virtual void printOperand(Value *value) = 0;
/// Print a comma separated list of operands.
template <typename ContainerType>
@ -76,8 +76,7 @@ public:
/// Print a successor, and use list, of a terminator operation given the
/// terminator and the successor index.
virtual void printSuccessorAndUseList(const Instruction *term,
unsigned index) = 0;
virtual void printSuccessorAndUseList(Instruction *term, unsigned index) = 0;
/// If the specified operation has attributes, print out an attribute
/// dictionary with their values. elidedAttrs allows the client to ignore
@ -87,7 +86,7 @@ public:
ArrayRef<StringRef> elidedAttrs = {}) = 0;
/// Print the entire operation with the default generic assembly form.
virtual void printGenericOp(const Instruction *op) = 0;
virtual void printGenericOp(Instruction *op) = 0;
/// Prints a region.
virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true) = 0;
@ -98,7 +97,7 @@ private:
};
// Make the implementations convenient to use.
inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const Value &value) {
inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Value &value) {
p.printOperand(&value);
return p;
}

View File

@ -86,8 +86,8 @@ public:
/// This hook implements the AsmPrinter for this operation.
void (&printAssembly)(Instruction *op, OpAsmPrinter *p);
/// This hook implements the verifier for this operation. It should emit an
/// error message and returns true if a problem is detected, or return false
/// This hook implements the verifier for this operation. It should emits an
/// error message and returns true if a problem is detected, or returns false
/// if everything is ok.
bool (&verifyInvariants)(Instruction *op);

View File

@ -97,7 +97,7 @@ public:
/// Return the owner of this operand.
Instruction *getOwner() { return owner; }
const Instruction *getOwner() const { return owner; }
Instruction *getOwner() const { return owner; }
/// \brief Remove this use of the operand.
void drop() {
@ -176,13 +176,13 @@ public:
: IROperand(owner, value) {}
/// Return the current value being used by this operand.
IRValueTy *get() const { return (IRValueTy *)IROperand::get(); }
IRValueTy *get() { return (IRValueTy *)IROperand::get(); }
/// Set the current value being used by this operand.
void set(IRValueTy *newValue) { IROperand::set(newValue); }
/// Return which operand this is in the operand list of the User.
unsigned getOperandNumber() const;
unsigned getOperandNumber();
};
/// An iterator over all uses of a ValueBase.

View File

@ -48,9 +48,9 @@ public:
~Value() {}
Kind getKind() const { return typeAndKind.getInt(); }
Kind getKind() { return typeAndKind.getInt(); }
Type getType() const { return typeAndKind.getPointer(); }
Type getType() { return typeAndKind.getPointer(); }
/// Replace all uses of 'this' value with the new value, updating anything in
/// the IR that uses 'this' to use the other value instead. When this returns
@ -60,26 +60,23 @@ public:
}
/// Return the function that this Value is defined in.
Function *getFunction() const;
Function *getFunction();
/// If this value is the result of an operation, return the instruction
/// that defines it.
Instruction *getDefiningInst();
const Instruction *getDefiningInst() const {
return const_cast<Value *>(this)->getDefiningInst();
}
using use_iterator = ValueUseIterator<InstOperand>;
using use_range = llvm::iterator_range<use_iterator>;
inline use_iterator use_begin() const;
inline use_iterator use_end() const;
inline use_iterator use_begin();
inline use_iterator use_end();
/// Returns a range of all uses, which is useful for iterating over all uses.
inline use_range getUses() const;
inline use_range getUses();
void print(raw_ostream &os) const;
void dump() const;
void print(raw_ostream &os);
void dump();
protected:
Value(Kind kind, Type type) : typeAndKind(type, kind) {}
@ -88,21 +85,19 @@ private:
const llvm::PointerIntPair<Type, 1, Kind> typeAndKind;
};
inline raw_ostream &operator<<(raw_ostream &os, const Value &value) {
inline raw_ostream &operator<<(raw_ostream &os, Value &value) {
value.print(os);
return os;
}
// Utility functions for iterating through Value uses.
inline auto Value::use_begin() const -> use_iterator {
inline auto Value::use_begin() -> use_iterator {
return use_iterator((InstOperand *)getFirstUse());
}
inline auto Value::use_end() const -> use_iterator {
return use_iterator(nullptr);
}
inline auto Value::use_end() -> use_iterator { return use_iterator(nullptr); }
inline auto Value::getUses() const -> llvm::iterator_range<use_iterator> {
inline auto Value::getUses() -> llvm::iterator_range<use_iterator> {
return {use_begin(), use_end()};
}
@ -110,19 +105,19 @@ inline auto Value::getUses() const -> llvm::iterator_range<use_iterator> {
class BlockArgument : public Value {
public:
static bool classof(const Value *value) {
return value->getKind() == Kind::BlockArgument;
return const_cast<Value *>(value)->getKind() == Kind::BlockArgument;
}
/// Return the function that this argument is defined in.
Function *getFunction() const;
Function *getFunction();
Block *getOwner() const { return owner; }
Block *getOwner() { return owner; }
/// Returns the number of this argument.
unsigned getArgNumber() const;
unsigned getArgNumber();
/// Returns if the current argument is a function argument.
bool isFunctionArgument() const;
bool isFunctionArgument();
private:
friend class Block; // For access to private constructor.
@ -142,14 +137,13 @@ public:
: Value(Value::Kind::InstResult, type), owner(owner) {}
static bool classof(const Value *value) {
return value->getKind() == Kind::InstResult;
return const_cast<Value *>(value)->getKind() == Kind::InstResult;
}
Instruction *getOwner() { return owner; }
const Instruction *getOwner() const { return owner; }
/// Returns the number of this result.
unsigned getResultNumber() const;
unsigned getResultNumber();
private:
/// The owner of this operand.

View File

@ -35,7 +35,7 @@ class Builder;
namespace detail {
/// A custom binary operation printer that omits the "std." prefix from the
/// operation names.
void printStandardBinaryOp(const Instruction *op, OpAsmPrinter *p);
void printStandardBinaryOp(Instruction *op, OpAsmPrinter *p);
} // namespace detail
class StandardOpsDialect : public Dialect {
@ -69,9 +69,7 @@ class AllocOp
: public Op<AllocOp, OpTrait::VariadicOperands, OpTrait::OneResult> {
public:
/// The result of an alloc is always a MemRefType.
MemRefType getType() const {
return getResult()->getType().cast<MemRefType>();
}
MemRefType getType() { return getResult()->getType().cast<MemRefType>(); }
static StringRef getOperationName() { return "std.alloc"; }
@ -86,7 +84,7 @@ public:
private:
friend class Instruction;
explicit AllocOp(const Instruction *state) : Op(state) {}
explicit AllocOp(Instruction *state) : Op(state) {}
};
/// The "br" operation represents a branch instruction in a function.
@ -113,7 +111,6 @@ public:
/// Return the block this branch jumps to.
Block *getDest();
Block *getDest() const { return const_cast<BranchOp *>(this)->getDest(); }
void setDest(Block *block);
/// Erase the operand at 'index' from the operand list.
@ -121,7 +118,7 @@ public:
private:
friend class Instruction;
explicit BranchOp(const Instruction *state) : Op(state) {}
explicit BranchOp(Instruction *state) : Op(state) {}
};
/// The "call" operation represents a direct call to a function. The operands
@ -138,21 +135,15 @@ public:
static void build(Builder *builder, OperationState *result, Function *callee,
ArrayRef<Value *> operands);
Function *getCallee() const {
Function *getCallee() {
return getAttrOfType<FunctionAttr>("callee").getValue();
}
/// Get the argument operands to the called function.
llvm::iterator_range<const_operand_iterator> getArgOperands() const {
return {arg_operand_begin(), arg_operand_end()};
}
llvm::iterator_range<operand_iterator> getArgOperands() {
return {arg_operand_begin(), arg_operand_end()};
}
const_operand_iterator arg_operand_begin() const { return operand_begin(); }
const_operand_iterator arg_operand_end() const { return operand_end(); }
operand_iterator arg_operand_begin() { return operand_begin(); }
operand_iterator arg_operand_end() { return operand_end(); }
@ -163,7 +154,7 @@ public:
protected:
friend class Instruction;
explicit CallOp(const Instruction *state) : Op(state) {}
explicit CallOp(Instruction *state) : Op(state) {}
};
/// The "call_indirect" operation represents an indirect call to a value of
@ -182,20 +173,13 @@ public:
static void build(Builder *builder, OperationState *result, Value *callee,
ArrayRef<Value *> operands);
const Value *getCallee() const { return getOperand(0); }
Value *getCallee() { return getOperand(0); }
/// Get the argument operands to the called function.
llvm::iterator_range<const_operand_iterator> getArgOperands() const {
return {arg_operand_begin(), arg_operand_end()};
}
llvm::iterator_range<operand_iterator> getArgOperands() {
return {arg_operand_begin(), arg_operand_end()};
}
const_operand_iterator arg_operand_begin() const { return ++operand_begin(); }
const_operand_iterator arg_operand_end() const { return operand_end(); }
operand_iterator arg_operand_begin() { return ++operand_begin(); }
operand_iterator arg_operand_end() { return operand_end(); }
@ -208,7 +192,7 @@ public:
protected:
friend class Instruction;
explicit CallIndirectOp(const Instruction *state) : Op(state) {}
explicit CallIndirectOp(Instruction *state) : Op(state) {}
};
/// The predicate indicates the type of the comparison to perform:
@ -274,7 +258,7 @@ public:
private:
friend class Instruction;
explicit CmpIOp(const Instruction *state) : Op(state) {}
explicit CmpIOp(Instruction *state) : Op(state) {}
};
/// The "cond_br" operation represents a conditional branch instruction in a
@ -314,29 +298,20 @@ public:
MLIRContext *context);
// The condition operand is the first operand in the list.
Value *getCondition() { return getOperand(0); }
const Value *getCondition() const { return getOperand(0); }
Value *getCondition() const { return getOperand(0); }
/// Return the destination if the condition is true.
Block *getTrueDest();
Block *getTrueDest() const {
return const_cast<CondBranchOp *>(this)->getTrueDest();
}
/// Return the destination if the condition is false.
Block *getFalseDest();
Block *getFalseDest() const {
return const_cast<CondBranchOp *>(this)->getFalseDest();
}
// Accessors for operands to the 'true' destination.
Value *getTrueOperand(unsigned idx) {
assert(idx < getNumTrueOperands());
return getOperand(getTrueDestOperandIndex() + idx);
}
const Value *getTrueOperand(unsigned idx) const {
return const_cast<CondBranchOp *>(this)->getTrueOperand(idx);
}
void setTrueOperand(unsigned idx, Value *value) {
assert(idx < getNumTrueOperands());
setOperand(getTrueDestOperandIndex() + idx, value);
@ -352,16 +327,6 @@ public:
return {true_operand_begin(), true_operand_end()};
}
const_operand_iterator true_operand_begin() const {
return operand_begin() + getTrueDestOperandIndex();
}
const_operand_iterator true_operand_end() const {
return true_operand_begin() + getNumTrueOperands();
}
llvm::iterator_range<const_operand_iterator> getTrueOperands() const {
return {true_operand_begin(), true_operand_end()};
}
unsigned getNumTrueOperands() const;
/// Erase the operand at 'index' from the true operand list.
@ -372,7 +337,7 @@ public:
assert(idx < getNumFalseOperands());
return getOperand(getFalseDestOperandIndex() + idx);
}
const Value *getFalseOperand(unsigned idx) const {
Value *getFalseOperand(unsigned idx) const {
return const_cast<CondBranchOp *>(this)->getFalseOperand(idx);
}
void setFalseOperand(unsigned idx, Value *value) {
@ -388,16 +353,6 @@ public:
return {false_operand_begin(), false_operand_end()};
}
const_operand_iterator false_operand_begin() const {
return true_operand_end();
}
const_operand_iterator false_operand_end() const {
return false_operand_begin() + getNumFalseOperands();
}
llvm::iterator_range<const_operand_iterator> getFalseOperands() const {
return {false_operand_begin(), false_operand_end()};
}
unsigned getNumFalseOperands() const;
/// Erase the operand at 'index' from the false operand list.
@ -413,7 +368,7 @@ private:
}
friend class Instruction;
explicit CondBranchOp(const Instruction *state) : Op(state) {}
explicit CondBranchOp(Instruction *state) : Op(state) {}
};
/// The "constant" operation requires a single attribute named "value".
@ -445,7 +400,7 @@ public:
protected:
friend class Instruction;
explicit ConstantOp(const Instruction *state) : Op(state) {}
explicit ConstantOp(Instruction *state) : Op(state) {}
};
/// This is a refinement of the "constant" op for the case where it is
@ -467,7 +422,7 @@ public:
private:
friend class Instruction;
explicit ConstantFloatOp(const Instruction *state) : ConstantOp(state) {}
explicit ConstantFloatOp(Instruction *state) : ConstantOp(state) {}
};
/// This is a refinement of the "constant" op for the case where it is
@ -494,7 +449,7 @@ public:
private:
friend class Instruction;
explicit ConstantIntOp(const Instruction *state) : ConstantOp(state) {}
explicit ConstantIntOp(Instruction *state) : ConstantOp(state) {}
};
/// This is a refinement of the "constant" op for the case where it is
@ -515,7 +470,7 @@ public:
private:
friend class Instruction;
explicit ConstantIndexOp(const Instruction *state) : ConstantOp(state) {}
explicit ConstantIndexOp(Instruction *state) : ConstantOp(state) {}
};
/// The "dealloc" operation frees the region of memory referenced by a memref
@ -531,8 +486,7 @@ private:
class DeallocOp
: public Op<DeallocOp, OpTrait::OneOperand, OpTrait::ZeroResult> {
public:
Value *getMemRef() { return getOperand(); }
const Value *getMemRef() const { return getOperand(); }
Value *getMemRef() const { return getOperand(); }
void setMemRef(Value *value) { setOperand(value); }
static StringRef getOperationName() { return "std.dealloc"; }
@ -547,7 +501,7 @@ public:
private:
friend class Instruction;
explicit DeallocOp(const Instruction *state) : Op(state) {}
explicit DeallocOp(Instruction *state) : Op(state) {}
};
/// The "dim" operation takes a memref or tensor operand and returns an
@ -578,7 +532,7 @@ public:
private:
friend class Instruction;
explicit DimOp(const Instruction *state) : Op(state) {}
explicit DimOp(Instruction *state) : Op(state) {}
};
// DmaStartOp starts a non-blocking DMA operation that transfers data from a
@ -629,22 +583,19 @@ public:
Value *elementsPerStride = nullptr);
// Returns the source MemRefType for this DMA operation.
const Value *getSrcMemRef() const { return getOperand(0); }
Value *getSrcMemRef() const { return getOperand(0); }
// Returns the rank (number of indices) of the source MemRefType.
unsigned getSrcMemRefRank() const {
return getSrcMemRef()->getType().cast<MemRefType>().getRank();
}
// Returns the source memerf indices for this DMA operation.
llvm::iterator_range<Instruction::const_operand_iterator>
getSrcIndices() const {
llvm::iterator_range<Instruction::operand_iterator> getSrcIndices() {
return {getInstruction()->operand_begin() + 1,
getInstruction()->operand_begin() + 1 + getSrcMemRefRank()};
}
// Returns the destination MemRefType for this DMA operations.
const Value *getDstMemRef() const {
return getOperand(1 + getSrcMemRefRank());
}
Value *getDstMemRef() const { return getOperand(1 + getSrcMemRefRank()); }
// Returns the rank (number of indices) of the destination MemRefType.
unsigned getDstMemRefRank() const {
return getDstMemRef()->getType().cast<MemRefType>().getRank();
@ -657,20 +608,19 @@ public:
}
// Returns the destination memref indices for this DMA operation.
llvm::iterator_range<Instruction::const_operand_iterator>
getDstIndices() const {
llvm::iterator_range<Instruction::operand_iterator> getDstIndices() {
return {getInstruction()->operand_begin() + 1 + getSrcMemRefRank() + 1,
getInstruction()->operand_begin() + 1 + getSrcMemRefRank() + 1 +
getDstMemRefRank()};
}
// Returns the number of elements being transferred by this DMA operation.
const Value *getNumElements() const {
Value *getNumElements() const {
return getOperand(1 + getSrcMemRefRank() + 1 + getDstMemRefRank());
}
// Returns the Tag MemRef for this DMA operation.
const Value *getTagMemRef() const {
Value *getTagMemRef() const {
return getOperand(1 + getSrcMemRefRank() + 1 + getDstMemRefRank() + 1);
}
// Returns the rank (number of indices) of the tag MemRefType.
@ -679,8 +629,7 @@ public:
}
// Returns the tag memref index for this DMA operation.
llvm::iterator_range<Instruction::const_operand_iterator>
getTagIndices() const {
llvm::iterator_range<Instruction::operand_iterator> getTagIndices() const {
unsigned tagIndexStartPos =
1 + getSrcMemRefRank() + 1 + getDstMemRefRank() + 1 + 1;
return {getInstruction()->operand_begin() + tagIndexStartPos,
@ -725,22 +674,16 @@ public:
return nullptr;
return getOperand(getNumOperands() - 1 - 1);
}
const Value *getStride() const {
return const_cast<DmaStartOp *>(this)->getStride();
}
Value *getNumElementsPerStride() {
if (!isStrided())
return nullptr;
return getOperand(getNumOperands() - 1);
}
const Value *getNumElementsPerStride() const {
return const_cast<DmaStartOp *>(this)->getNumElementsPerStride();
}
protected:
friend class Instruction;
explicit DmaStartOp(const Instruction *state) : Op(state) {}
explicit DmaStartOp(Instruction *state) : Op(state) {}
};
// DmaWaitOp blocks until the completion of a DMA operation associated with the
@ -765,12 +708,10 @@ public:
static StringRef getOperationName() { return "std.dma_wait"; }
// Returns the Tag MemRef associated with the DMA operation being waited on.
const Value *getTagMemRef() const { return getOperand(0); }
Value *getTagMemRef() { return getOperand(0); }
Value *getTagMemRef() const { return getOperand(0); }
// Returns the tag memref index for this DMA operation.
llvm::iterator_range<Instruction::const_operand_iterator>
getTagIndices() const {
llvm::iterator_range<Instruction::operand_iterator> getTagIndices() const {
return {getInstruction()->operand_begin() + 1,
getInstruction()->operand_begin() + 1 + getTagMemRefRank()};
}
@ -781,9 +722,7 @@ public:
}
// Returns the number of elements transferred in the associated DMA operation.
const Value *getNumElements() const {
return getOperand(1 + getTagMemRefRank());
}
Value *getNumElements() const { return getOperand(1 + getTagMemRefRank()); }
static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p);
@ -792,7 +731,7 @@ public:
protected:
friend class Instruction;
explicit DmaWaitOp(const Instruction *state) : Op(state) {}
explicit DmaWaitOp(Instruction *state) : Op(state) {}
};
/// The "extract_element" op reads a tensor or vector and returns one element
@ -813,19 +752,13 @@ public:
static void build(Builder *builder, OperationState *result, Value *aggregate,
ArrayRef<Value *> indices = {});
Value *getAggregate() { return getOperand(0); }
const Value *getAggregate() const { return getOperand(0); }
Value *getAggregate() const { return getOperand(0); }
llvm::iterator_range<Instruction::operand_iterator> getIndices() {
return {getInstruction()->operand_begin() + 1,
getInstruction()->operand_end()};
}
llvm::iterator_range<Instruction::const_operand_iterator> getIndices() const {
return {getInstruction()->operand_begin() + 1,
getInstruction()->operand_end()};
}
static StringRef getOperationName() { return "std.extract_element"; }
// Hooks to customize behavior of this op.
@ -836,7 +769,7 @@ public:
private:
friend class Instruction;
explicit ExtractElementOp(const Instruction *state) : Op(state) {}
explicit ExtractElementOp(Instruction *state) : Op(state) {}
};
/// The "load" op reads an element from a memref specified by an index list. The
@ -854,8 +787,7 @@ public:
static void build(Builder *builder, OperationState *result, Value *memref,
ArrayRef<Value *> indices = {});
Value *getMemRef() { return getOperand(0); }
const Value *getMemRef() const { return getOperand(0); }
Value *getMemRef() const { return getOperand(0); }
void setMemRef(Value *value) { setOperand(0, value); }
MemRefType getMemRefType() const {
return getMemRef()->getType().cast<MemRefType>();
@ -866,11 +798,6 @@ public:
getInstruction()->operand_end()};
}
llvm::iterator_range<Instruction::const_operand_iterator> getIndices() const {
return {getInstruction()->operand_begin() + 1,
getInstruction()->operand_end()};
}
static StringRef getOperationName() { return "std.load"; }
bool verify();
@ -881,7 +808,7 @@ public:
private:
friend class Instruction;
explicit LoadOp(const Instruction *state) : Op(state) {}
explicit LoadOp(Instruction *state) : Op(state) {}
};
/// The "memref_cast" operation converts a memref from one type to an equivalent
@ -914,7 +841,7 @@ public:
private:
friend class Instruction;
explicit MemRefCastOp(const Instruction *state) : CastOp(state) {}
explicit MemRefCastOp(Instruction *state) : CastOp(state) {}
};
/// The "return" operation represents a return instruction within a function.
@ -941,7 +868,7 @@ public:
private:
friend class Instruction;
explicit ReturnOp(const Instruction *state) : Op(state) {}
explicit ReturnOp(Instruction *state) : Op(state) {}
};
/// The "select" operation chooses one value based on a binary condition
@ -965,18 +892,15 @@ public:
void print(OpAsmPrinter *p);
bool verify();
Value *getCondition() { return getOperand(0); }
const Value *getCondition() const { return getOperand(0); }
Value *getTrueValue() { return getOperand(1); }
const Value *getTrueValue() const { return getOperand(1); }
Value *getFalseValue() { return getOperand(2); }
const Value *getFalseValue() const { return getOperand(2); }
Value *getCondition() const { return getOperand(0); }
Value *getTrueValue() const { return getOperand(1); }
Value *getFalseValue() const { return getOperand(2); }
Value *fold();
private:
friend class Instruction;
explicit SelectOp(const Instruction *state) : Op(state) {}
explicit SelectOp(Instruction *state) : Op(state) {}
};
/// The "store" op writes an element to a memref specified by an index list.
@ -997,13 +921,11 @@ public:
Value *valueToStore, Value *memref,
ArrayRef<Value *> indices = {});
Value *getValueToStore() { return getOperand(0); }
const Value *getValueToStore() const { return getOperand(0); }
Value *getValueToStore() const { return getOperand(0); }
Value *getMemRef() { return getOperand(1); }
const Value *getMemRef() const { return getOperand(1); }
void setMemRef(Value *value) { setOperand(1, value); }
MemRefType getMemRefType() const {
MemRefType getMemRefType() {
return getMemRef()->getType().cast<MemRefType>();
}
@ -1012,11 +934,6 @@ public:
getInstruction()->operand_end()};
}
llvm::iterator_range<Instruction::const_operand_iterator> getIndices() const {
return {getInstruction()->operand_begin() + 2,
getInstruction()->operand_end()};
}
static StringRef getOperationName() { return "std.store"; }
bool verify();
@ -1028,7 +945,7 @@ public:
private:
friend class Instruction;
explicit StoreOp(const Instruction *state) : Op(state) {}
explicit StoreOp(Instruction *state) : Op(state) {}
};
/// The "tensor_cast" operation converts a tensor from one type to an equivalent
@ -1046,9 +963,7 @@ public:
static StringRef getOperationName() { return "std.tensor_cast"; }
/// The result of a tensor_cast is always a tensor.
TensorType getType() const {
return getResult()->getType().cast<TensorType>();
}
TensorType getType() { return getResult()->getType().cast<TensorType>(); }
void print(OpAsmPrinter *p);
@ -1056,13 +971,13 @@ public:
private:
friend class Instruction;
explicit TensorCastOp(const Instruction *state) : CastOp(state) {}
explicit TensorCastOp(Instruction *state) : CastOp(state) {}
};
/// Prints dimension and symbol list.
void printDimAndSymbolList(Instruction::const_operand_iterator begin,
Instruction::const_operand_iterator end,
unsigned numDims, OpAsmPrinter *p);
void printDimAndSymbolList(Instruction::operand_iterator begin,
Instruction::operand_iterator end, unsigned numDims,
OpAsmPrinter *p);
/// Parses dimension and symbol list and returns true if parsing failed.
bool parseDimAndSymbolList(OpAsmParser *parser,

View File

@ -102,22 +102,18 @@ public:
VectorType vectorType, Value *srcMemRef,
ArrayRef<Value *> srcIndices, AffineMap permutationMap,
Optional<Value *> paddingValue = None);
VectorType getResultType() const {
VectorType getResultType() {
return getResult()->getType().cast<VectorType>();
}
Value *getVector() { return getResult(); }
const Value *getVector() const { return getResult(); }
Value *getMemRef() { return getOperand(Offsets::MemRefOffset); }
const Value *getMemRef() const { return getOperand(Offsets::MemRefOffset); }
VectorType getVectorType() const { return getResultType(); }
MemRefType getMemRefType() const {
VectorType getVectorType() { return getResultType(); }
MemRefType getMemRefType() {
return getMemRef()->getType().cast<MemRefType>();
}
llvm::iterator_range<Instruction::operand_iterator> getIndices();
llvm::iterator_range<Instruction::const_operand_iterator> getIndices() const;
Optional<Value *> getPaddingValue();
Optional<const Value *> getPaddingValue() const;
AffineMap getPermutationMap() const;
AffineMap getPermutationMap();
static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p);
@ -125,7 +121,7 @@ public:
private:
friend class Instruction;
explicit VectorTransferReadOp(const Instruction *state) : Op(state) {}
explicit VectorTransferReadOp(Instruction *state) : Op(state) {}
};
/// VectorTransferWriteOp performs a blocking write from a super-vector to
@ -172,18 +168,15 @@ public:
Value *dstMemRef, ArrayRef<Value *> dstIndices,
AffineMap permutationMap);
Value *getVector() { return getOperand(Offsets::VectorOffset); }
const Value *getVector() const { return getOperand(Offsets::VectorOffset); }
VectorType getVectorType() const {
VectorType getVectorType() {
return getVector()->getType().cast<VectorType>();
}
Value *getMemRef() { return getOperand(Offsets::MemRefOffset); }
const Value *getMemRef() const { return getOperand(Offsets::MemRefOffset); }
MemRefType getMemRefType() const {
MemRefType getMemRefType() {
return getMemRef()->getType().cast<MemRefType>();
}
llvm::iterator_range<Instruction::operand_iterator> getIndices();
llvm::iterator_range<Instruction::const_operand_iterator> getIndices() const;
AffineMap getPermutationMap() const;
AffineMap getPermutationMap();
static bool parse(OpAsmParser *parser, OperationState *result);
void print(OpAsmPrinter *p);
@ -191,7 +184,7 @@ public:
private:
friend class Instruction;
explicit VectorTransferWriteOp(const Instruction *state) : Op(state) {}
explicit VectorTransferWriteOp(Instruction *state) : Op(state) {}
};
/// VectorTypeCastOp performs a conversion from a memref with scalar element to
@ -215,7 +208,7 @@ public:
private:
friend class Instruction;
explicit VectorTypeCastOp(const Instruction *state) : Op(state) {}
explicit VectorTypeCastOp(Instruction *state) : Op(state) {}
};
} // end namespace mlir

View File

@ -69,12 +69,12 @@ class Function;
// extra operands, note that 'indexRemap' would just be applied to existing
// indices (%i, %j).
// TODO(bondhugula): allow extraIndices to be added at any position.
bool replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef,
bool replaceAllMemRefUsesWith(Value *oldMemRef, Value *newMemRef,
ArrayRef<Value *> extraIndices = {},
AffineMap indexRemap = AffineMap(),
ArrayRef<Value *> extraOperands = {},
const Instruction *domInstFilter = nullptr,
const Instruction *postDomInstFilter = nullptr);
Instruction *domInstFilter = nullptr,
Instruction *postDomInstFilter = nullptr);
/// Creates and inserts into 'builder' a new AffineApplyOp, with the number of
/// its results equal to the number of operands, as a composition

View File

@ -42,7 +42,7 @@ AffineOpsDialect::AffineOpsDialect(MLIRContext *context)
/// A utility function to check if a value is defined at the top level of a
/// function. A value defined at the top level is always a valid symbol.
bool mlir::isTopLevelSymbol(const Value *value) {
bool mlir::isTopLevelSymbol(Value *value) {
if (auto *arg = dyn_cast<BlockArgument>(value))
return arg->getOwner()->getParent()->getContainingFunction();
return value->getDefiningInst()->getParentInst() == nullptr;
@ -51,7 +51,7 @@ bool mlir::isTopLevelSymbol(const Value *value) {
// Value can be used as a dimension id if it is valid as a symbol, or
// it is an induction variable, or it is a result of affine apply operation
// with dimension id arguments.
bool mlir::isValidDim(const Value *value) {
bool mlir::isValidDim(Value *value) {
// The value must be an index type.
if (!value->getType().isIndex())
return false;
@ -76,7 +76,7 @@ bool mlir::isValidDim(const Value *value) {
// Value can be used as a symbol if it is a constant, or it is defined at
// the top level, or it is a result of affine apply operation with symbol
// arguments.
bool mlir::isValidSymbol(const Value *value) {
bool mlir::isValidSymbol(Value *value) {
// The value must be an index type.
if (!value->getType().isIndex())
return false;
@ -105,10 +105,9 @@ bool mlir::isValidSymbol(const Value *value) {
/// was an invalid operand. An operation is provided to emit any necessary
/// errors.
template <typename OpTy>
static bool
verifyDimAndSymbolIdentifiers(const OpTy &op,
Instruction::const_operand_range operands,
unsigned numDims) {
static bool verifyDimAndSymbolIdentifiers(OpTy &op,
Instruction::operand_range operands,
unsigned numDims) {
unsigned opIt = 0;
for (auto *operand : operands) {
if (opIt++ < numDims) {
@ -189,16 +188,16 @@ bool AffineApplyOp::verify() {
// The result of the affine apply operation can be used as a dimension id if it
// is a CFG value or if it is an Value, and all the operands are valid
// dimension ids.
bool AffineApplyOp::isValidDim() const {
bool AffineApplyOp::isValidDim() {
return llvm::all_of(getOperands(),
[](const Value *op) { return mlir::isValidDim(op); });
[](Value *op) { return mlir::isValidDim(op); });
}
// The result of the affine apply operation can be used as a symbol if it is
// a CFG value or if it is an Value, and all the operands are symbols.
bool AffineApplyOp::isValidSymbol() const {
bool AffineApplyOp::isValidSymbol() {
return llvm::all_of(getOperands(),
[](const Value *op) { return mlir::isValidSymbol(op); });
[](Value *op) { return mlir::isValidSymbol(op); });
}
Attribute AffineApplyOp::constantFold(ArrayRef<Attribute> operands,
@ -1069,13 +1068,13 @@ Block *AffineForOp::createBody() {
return body;
}
const AffineBound AffineForOp::getLowerBound() const {
AffineBound AffineForOp::getLowerBound() {
auto lbMap = getLowerBoundMap();
return AffineBound(OpPointer<AffineForOp>(*this), 0, lbMap.getNumInputs(),
lbMap);
}
const AffineBound AffineForOp::getUpperBound() const {
AffineBound AffineForOp::getUpperBound() {
auto lbMap = getLowerBoundMap();
auto ubMap = getUpperBoundMap();
return AffineBound(OpPointer<AffineForOp>(*this), lbMap.getNumInputs(),
@ -1124,19 +1123,19 @@ void AffineForOp::setUpperBoundMap(AffineMap map) {
setAttr(getUpperBoundAttrName(), AffineMapAttr::get(map));
}
bool AffineForOp::hasConstantLowerBound() const {
bool AffineForOp::hasConstantLowerBound() {
return getLowerBoundMap().isSingleConstant();
}
bool AffineForOp::hasConstantUpperBound() const {
bool AffineForOp::hasConstantUpperBound() {
return getUpperBoundMap().isSingleConstant();
}
int64_t AffineForOp::getConstantLowerBound() const {
int64_t AffineForOp::getConstantLowerBound() {
return getLowerBoundMap().getSingleConstantResult();
}
int64_t AffineForOp::getConstantUpperBound() const {
int64_t AffineForOp::getConstantUpperBound() {
return getUpperBoundMap().getSingleConstantResult();
}
@ -1154,19 +1153,11 @@ AffineForOp::operand_range AffineForOp::getLowerBoundOperands() {
return {operand_begin(), operand_begin() + getLowerBoundMap().getNumInputs()};
}
AffineForOp::const_operand_range AffineForOp::getLowerBoundOperands() const {
return {operand_begin(), operand_begin() + getLowerBoundMap().getNumInputs()};
}
AffineForOp::operand_range AffineForOp::getUpperBoundOperands() {
return {operand_begin() + getLowerBoundMap().getNumInputs(), operand_end()};
}
AffineForOp::const_operand_range AffineForOp::getUpperBoundOperands() const {
return {operand_begin() + getLowerBoundMap().getNumInputs(), operand_end()};
}
bool AffineForOp::matchingBoundOperandList() const {
bool AffineForOp::matchingBoundOperandList() {
auto lbMap = getLowerBoundMap();
auto ubMap = getUpperBoundMap();
if (lbMap.getNumDims() != ubMap.getNumDims() ||
@ -1186,14 +1177,14 @@ bool AffineForOp::matchingBoundOperandList() const {
Value *AffineForOp::getInductionVar() { return getBody()->getArgument(0); }
/// Returns if the provided value is the induction variable of a AffineForOp.
bool mlir::isForInductionVar(const Value *val) {
bool mlir::isForInductionVar(Value *val) {
return getForInductionVarOwner(val) != nullptr;
}
/// Returns the loop parent of an induction variable. If the provided value is
/// not an induction variable, then return nullptr.
OpPointer<AffineForOp> mlir::getForInductionVarOwner(const Value *val) {
const BlockArgument *ivArg = dyn_cast<BlockArgument>(val);
OpPointer<AffineForOp> mlir::getForInductionVarOwner(Value *val) {
auto *ivArg = dyn_cast<BlockArgument>(val);
if (!ivArg || !ivArg->getOwner())
return OpPointer<AffineForOp>();
auto *containingInst = ivArg->getOwner()->getParent()->getContainingInst();
@ -1320,7 +1311,7 @@ void AffineIfOp::print(OpAsmPrinter *p) {
/*elidedAttrs=*/getConditionAttrName());
}
IntegerSet AffineIfOp::getIntegerSet() const {
IntegerSet AffineIfOp::getIntegerSet() {
return getAttrOfType<IntegerSetAttr>(getConditionAttrName()).getValue();
}
void AffineIfOp::setIntegerSet(IntegerSet newSet) {

View File

@ -118,7 +118,7 @@ LogicalResult mlir::getIndexSet(MutableArrayRef<OpPointer<AffineForOp>> forOps,
// 'indexSet' correspond to the loops surounding 'inst' from outermost to
// innermost.
// TODO(andydavis) Add support to handle IfInsts surrounding 'inst'.
static LogicalResult getInstIndexSet(const Instruction *inst,
static LogicalResult getInstIndexSet(Instruction *inst,
FlatAffineConstraints *indexSet) {
// TODO(andydavis) Extend this to gather enclosing IfInsts and consider
// factoring it out into a utility function.
@ -147,25 +147,25 @@ static LogicalResult getInstIndexSet(const Instruction *inst,
// of maps to check. So getSrcDimOrSymPos would be "getPos(value, {0, 2})".
class ValuePositionMap {
public:
void addSrcValue(const Value *value) {
void addSrcValue(Value *value) {
if (addValueAt(value, &srcDimPosMap, numSrcDims))
++numSrcDims;
}
void addDstValue(const Value *value) {
void addDstValue(Value *value) {
if (addValueAt(value, &dstDimPosMap, numDstDims))
++numDstDims;
}
void addSymbolValue(const Value *value) {
void addSymbolValue(Value *value) {
if (addValueAt(value, &symbolPosMap, numSymbols))
++numSymbols;
}
unsigned getSrcDimOrSymPos(const Value *value) const {
unsigned getSrcDimOrSymPos(Value *value) const {
return getDimOrSymPos(value, srcDimPosMap, 0);
}
unsigned getDstDimOrSymPos(const Value *value) const {
unsigned getDstDimOrSymPos(Value *value) const {
return getDimOrSymPos(value, dstDimPosMap, numSrcDims);
}
unsigned getSymPos(const Value *value) const {
unsigned getSymPos(Value *value) const {
auto it = symbolPosMap.find(value);
assert(it != symbolPosMap.end());
return numSrcDims + numDstDims + it->second;
@ -177,7 +177,7 @@ public:
unsigned getNumSymbols() const { return numSymbols; }
private:
bool addValueAt(const Value *value, DenseMap<const Value *, unsigned> *posMap,
bool addValueAt(Value *value, DenseMap<Value *, unsigned> *posMap,
unsigned position) {
auto it = posMap->find(value);
if (it == posMap->end()) {
@ -186,8 +186,8 @@ private:
}
return false;
}
unsigned getDimOrSymPos(const Value *value,
const DenseMap<const Value *, unsigned> &dimPosMap,
unsigned getDimOrSymPos(Value *value,
const DenseMap<Value *, unsigned> &dimPosMap,
unsigned dimPosOffset) const {
auto it = dimPosMap.find(value);
if (it != dimPosMap.end()) {
@ -201,9 +201,9 @@ private:
unsigned numSrcDims = 0;
unsigned numDstDims = 0;
unsigned numSymbols = 0;
DenseMap<const Value *, unsigned> srcDimPosMap;
DenseMap<const Value *, unsigned> dstDimPosMap;
DenseMap<const Value *, unsigned> symbolPosMap;
DenseMap<Value *, unsigned> srcDimPosMap;
DenseMap<Value *, unsigned> dstDimPosMap;
DenseMap<Value *, unsigned> symbolPosMap;
};
// Builds a map from Value to identifier position in a new merged identifier
@ -451,7 +451,7 @@ addMemRefAccessConstraints(const AffineValueMap &srcAccessMap,
}
// Add equality constraints for any operands that are defined by constant ops.
auto addEqForConstOperands = [&](ArrayRef<const Value *> operands) {
auto addEqForConstOperands = [&](ArrayRef<Value *> operands) {
for (unsigned i = 0, e = operands.size(); i < e; ++i) {
if (isForInductionVar(operands[i]))
continue;

View File

@ -677,7 +677,7 @@ LogicalResult FlatAffineConstraints::composeMap(AffineValueMap *vMap) {
}
// Turn a dimension into a symbol.
static void turnDimIntoSymbol(FlatAffineConstraints *cst, const Value &id) {
static void turnDimIntoSymbol(FlatAffineConstraints *cst, Value &id) {
unsigned pos;
if (cst->findId(id, &pos) && pos < cst->getNumDimIds()) {
swapId(cst, pos, cst->getNumDimIds() - 1);
@ -686,7 +686,7 @@ static void turnDimIntoSymbol(FlatAffineConstraints *cst, const Value &id) {
}
// Turn a symbol into a dimension.
static void turnSymbolIntoDim(FlatAffineConstraints *cst, const Value &id) {
static void turnSymbolIntoDim(FlatAffineConstraints *cst, Value &id) {
unsigned pos;
if (cst->findId(id, &pos) && pos >= cst->getNumDimIds() &&
pos < cst->getNumDimAndSymbolIds()) {
@ -1669,7 +1669,7 @@ FlatAffineConstraints::addLowerOrUpperBound(unsigned pos, AffineMap boundMap,
if (localVarCst.getNumLocalIds() > 0) {
// Set values for localVarCst.
localVarCst.setIdValues(0, localVarCst.getNumDimAndSymbolIds(), operands);
for (const auto *operand : operands) {
for (auto *operand : operands) {
unsigned pos;
if (findId(*operand, &pos)) {
if (pos >= getNumDimIds() && pos < getNumDimAndSymbolIds()) {
@ -1689,7 +1689,7 @@ FlatAffineConstraints::addLowerOrUpperBound(unsigned pos, AffineMap boundMap,
// this here since the constraint system changes after a bound is added.
SmallVector<unsigned, 8> positions;
unsigned numOperands = operands.size();
for (const auto *operand : operands) {
for (auto *operand : operands) {
unsigned pos;
if (!findId(*operand, &pos))
assert(0 && "expected to be found");
@ -1859,7 +1859,7 @@ void FlatAffineConstraints::addLocalFloorDiv(ArrayRef<int64_t> dividend,
addInequality(bound);
}
bool FlatAffineConstraints::findId(const Value &id, unsigned *pos) const {
bool FlatAffineConstraints::findId(Value &id, unsigned *pos) const {
unsigned i = 0;
for (const auto &mayBeId : ids) {
if (mayBeId.hasValue() && mayBeId.getValue() == &id) {
@ -1871,7 +1871,7 @@ bool FlatAffineConstraints::findId(const Value &id, unsigned *pos) const {
return false;
}
bool FlatAffineConstraints::containsId(const Value &id) const {
bool FlatAffineConstraints::containsId(Value &id) const {
return llvm::any_of(ids, [&](const Optional<Value *> &mayBeId) {
return mayBeId.hasValue() && mayBeId.getValue() == &id;
});
@ -1896,7 +1896,7 @@ void FlatAffineConstraints::setIdToConstant(unsigned pos, int64_t val) {
/// Sets the specified identifer to a constant value; asserts if the id is not
/// found.
void FlatAffineConstraints::setIdToConstant(const Value &id, int64_t val) {
void FlatAffineConstraints::setIdToConstant(Value &id, int64_t val) {
unsigned pos;
if (!findId(id, &pos))
// This is a pre-condition for this method.

View File

@ -101,8 +101,7 @@ template class mlir::detail::DominanceInfoBase</*IsPostDom=*/false>;
//===----------------------------------------------------------------------===//
/// Return true if instruction A properly dominates instruction B.
bool DominanceInfo::properlyDominates(const Instruction *a,
const Instruction *b) {
bool DominanceInfo::properlyDominates(Instruction *a, Instruction *b) {
auto *aBlock = a->getBlock(), *bBlock = b->getBlock();
// If the blocks are the same, then check if b is before a in the block.
@ -122,7 +121,7 @@ bool DominanceInfo::properlyDominates(const Instruction *a,
}
/// Return true if value A properly dominates instruction B.
bool DominanceInfo::properlyDominates(const Value *a, const Instruction *b) {
bool DominanceInfo::properlyDominates(Value *a, Instruction *b) {
if (auto *aInst = a->getDefiningInst())
return properlyDominates(aInst, b);
@ -136,8 +135,7 @@ bool DominanceInfo::properlyDominates(const Value *a, const Instruction *b) {
//===----------------------------------------------------------------------===//
/// Returns true if statement 'a' properly postdominates statement b.
bool PostDominanceInfo::properlyPostDominates(const Instruction *a,
const Instruction *b) {
bool PostDominanceInfo::properlyPostDominates(Instruction *a, Instruction *b) {
auto *aBlock = a->getBlock(), *bBlock = b->getBlock();
// If the blocks are the same, check if b is before a in the block.
@ -145,7 +143,7 @@ bool PostDominanceInfo::properlyPostDominates(const Instruction *a,
return b->isBeforeInBlock(a);
// Traverse up b's hierarchy to check if b's block is contained in a's.
if (const auto *bAncestor = a->getBlock()->findAncestorInstInBlock(*b))
if (auto *bAncestor = a->getBlock()->findAncestorInstInBlock(*b))
// Since we already know that aBlock != bBlock, here bAncestor != b.
// a and bAncestor are in the same block; check if 'a' postdominates
// bAncestor.

View File

@ -179,7 +179,7 @@ uint64_t mlir::getLargestDivisorOfTripCount(OpPointer<AffineForOp> forOp) {
return gcd.getValue();
}
bool mlir::isAccessInvariant(const Value &iv, const Value &index) {
bool mlir::isAccessInvariant(Value &iv, Value &index) {
assert(isForInductionVar(&iv) && "iv must be a AffineForOp");
assert(index.getType().isa<IndexType>() && "index must be of IndexType");
SmallVector<Instruction *, 4> affineApplyOps;
@ -203,10 +203,9 @@ bool mlir::isAccessInvariant(const Value &iv, const Value &index) {
return !(AffineValueMap(composeOp).isFunctionOf(0, const_cast<Value *>(&iv)));
}
llvm::DenseSet<const Value *>
mlir::getInvariantAccesses(const Value &iv,
llvm::ArrayRef<const Value *> indices) {
llvm::DenseSet<const Value *> res;
llvm::DenseSet<Value *>
mlir::getInvariantAccesses(Value &iv, llvm::ArrayRef<Value *> indices) {
llvm::DenseSet<Value *> res;
for (unsigned idx = 0, n = indices.size(); idx < n; ++idx) {
auto *val = indices[idx];
if (isAccessInvariant(iv, *val)) {
@ -236,29 +235,29 @@ mlir::getInvariantAccesses(const Value &iv,
///
// TODO(ntv): check strides.
template <typename LoadOrStoreOp>
static bool isContiguousAccess(const Value &iv, const LoadOrStoreOp &memoryOp,
static bool isContiguousAccess(Value &iv, OpPointer<LoadOrStoreOp> memoryOp,
unsigned fastestVaryingDim) {
static_assert(std::is_same<LoadOrStoreOp, LoadOp>::value ||
std::is_same<LoadOrStoreOp, StoreOp>::value,
"Must be called on either const LoadOp & or const StoreOp &");
auto memRefType = memoryOp.getMemRefType();
auto memRefType = memoryOp->getMemRefType();
if (fastestVaryingDim >= memRefType.getRank()) {
memoryOp.emitError("fastest varying dim out of bounds");
memoryOp->emitError("fastest varying dim out of bounds");
return false;
}
auto layoutMap = memRefType.getAffineMaps();
// TODO(ntv): remove dependence on Builder once we support non-identity
// layout map.
Builder b(memoryOp.getInstruction()->getContext());
Builder b(memoryOp->getInstruction()->getContext());
if (layoutMap.size() >= 2 ||
(layoutMap.size() == 1 &&
!(layoutMap[0] ==
b.getMultiDimIdentityMap(layoutMap[0].getNumDims())))) {
return memoryOp.emitError("NYI: non-trivial layoutMap"), false;
return memoryOp->emitError("NYI: non-trivial layoutMap"), false;
}
auto indices = memoryOp.getIndices();
auto indices = memoryOp->getIndices();
auto numIndices = llvm::size(indices);
unsigned d = 0;
for (auto index : indices) {
@ -278,12 +277,12 @@ static bool isVectorElement(LoadOrStoreOpPointer memoryOp) {
return memRefType.getElementType().template isa<VectorType>();
}
static bool isVectorTransferReadOrWrite(const Instruction &inst) {
static bool isVectorTransferReadOrWrite(Instruction &inst) {
return inst.isa<VectorTransferReadOp>() || inst.isa<VectorTransferWriteOp>();
}
using VectorizableInstFun =
std::function<bool(OpPointer<AffineForOp>, const Instruction &)>;
std::function<bool(OpPointer<AffineForOp>, Instruction &)>;
static bool isVectorizableLoopWithCond(OpPointer<AffineForOp> loop,
VectorizableInstFun isVectorizableInst) {
@ -302,7 +301,7 @@ static bool isVectorizableLoopWithCond(OpPointer<AffineForOp> loop,
}
// No vectorization across unknown regions.
auto regions = matcher::Op([](const Instruction &inst) -> bool {
auto regions = matcher::Op([](Instruction &inst) -> bool {
return inst.getNumRegions() != 0 &&
!(inst.isa<AffineIfOp>() || inst.isa<AffineForOp>());
});
@ -342,22 +341,22 @@ static bool isVectorizableLoopWithCond(OpPointer<AffineForOp> loop,
bool mlir::isVectorizableLoopAlongFastestVaryingMemRefDim(
OpPointer<AffineForOp> loop, unsigned fastestVaryingDim) {
VectorizableInstFun fun([fastestVaryingDim](OpPointer<AffineForOp> loop,
const Instruction &op) {
auto load = op.dyn_cast<LoadOp>();
auto store = op.dyn_cast<StoreOp>();
return load ? isContiguousAccess(*loop->getInductionVar(), *load,
fastestVaryingDim)
: isContiguousAccess(*loop->getInductionVar(), *store,
fastestVaryingDim);
});
VectorizableInstFun fun(
[fastestVaryingDim](OpPointer<AffineForOp> loop, Instruction &op) {
auto load = op.dyn_cast<LoadOp>();
auto store = op.dyn_cast<StoreOp>();
return load ? isContiguousAccess(*loop->getInductionVar(), load,
fastestVaryingDim)
: isContiguousAccess(*loop->getInductionVar(), store,
fastestVaryingDim);
});
return isVectorizableLoopWithCond(loop, fun);
}
bool mlir::isVectorizableLoop(OpPointer<AffineForOp> loop) {
VectorizableInstFun fun(
// TODO: implement me
[](OpPointer<AffineForOp> loop, const Instruction &op) { return true; });
[](OpPointer<AffineForOp> loop, Instruction &op) { return true; });
return isVectorizableLoopWithCond(loop, fun);
}
@ -373,9 +372,9 @@ bool mlir::isInstwiseShiftValid(OpPointer<AffineForOp> forOp,
// Work backwards over the body of the block so that the shift of a use's
// ancestor instruction in the block gets recorded before it's looked up.
DenseMap<const Instruction *, uint64_t> forBodyShift;
DenseMap<Instruction *, uint64_t> forBodyShift;
for (auto it : llvm::enumerate(llvm::reverse(forBody->getInstructions()))) {
const auto &inst = it.value();
auto &inst = it.value();
// Get the index of the current instruction, note that we are iterating in
// reverse so we need to fix it up.
@ -387,7 +386,7 @@ bool mlir::isInstwiseShiftValid(OpPointer<AffineForOp> forOp,
// Validate the results of this instruction if it were to be shifted.
for (unsigned i = 0, e = inst.getNumResults(); i < e; ++i) {
const Value *result = inst.getResult(i);
Value *result = inst.getResult(i);
for (const InstOperand &use : result->getUses()) {
// If an ancestor instruction doesn't lie in the block of forOp,
// there is no shift to check.

View File

@ -110,13 +110,9 @@ void NestedPattern::matchOne(Instruction *inst,
}
}
static bool isAffineForOp(const Instruction &inst) {
return inst.isa<AffineForOp>();
}
static bool isAffineForOp(Instruction &inst) { return inst.isa<AffineForOp>(); }
static bool isAffineIfOp(const Instruction &inst) {
return inst.isa<AffineIfOp>();
}
static bool isAffineIfOp(Instruction &inst) { return inst.isa<AffineIfOp>(); }
namespace mlir {
namespace matcher {
@ -129,7 +125,7 @@ NestedPattern If(NestedPattern child) {
return NestedPattern(child, isAffineIfOp);
}
NestedPattern If(FilterFunctionType filter, NestedPattern child) {
return NestedPattern(child, [filter](const Instruction &inst) {
return NestedPattern(child, [filter](Instruction &inst) {
return isAffineIfOp(inst) && filter(inst);
});
}
@ -137,7 +133,7 @@ NestedPattern If(ArrayRef<NestedPattern> nested) {
return NestedPattern(nested, isAffineIfOp);
}
NestedPattern If(FilterFunctionType filter, ArrayRef<NestedPattern> nested) {
return NestedPattern(nested, [filter](const Instruction &inst) {
return NestedPattern(nested, [filter](Instruction &inst) {
return isAffineIfOp(inst) && filter(inst);
});
}
@ -146,7 +142,7 @@ NestedPattern For(NestedPattern child) {
return NestedPattern(child, isAffineForOp);
}
NestedPattern For(FilterFunctionType filter, NestedPattern child) {
return NestedPattern(child, [=](const Instruction &inst) {
return NestedPattern(child, [=](Instruction &inst) {
return isAffineForOp(inst) && filter(inst);
});
}
@ -154,24 +150,24 @@ NestedPattern For(ArrayRef<NestedPattern> nested) {
return NestedPattern(nested, isAffineForOp);
}
NestedPattern For(FilterFunctionType filter, ArrayRef<NestedPattern> nested) {
return NestedPattern(nested, [=](const Instruction &inst) {
return NestedPattern(nested, [=](Instruction &inst) {
return isAffineForOp(inst) && filter(inst);
});
}
// TODO(ntv): parallel annotation on loops.
bool isParallelLoop(const Instruction &inst) {
bool isParallelLoop(Instruction &inst) {
auto loop = inst.cast<AffineForOp>();
return loop || true; // loop->isParallel();
};
// TODO(ntv): reduction annotation on loops.
bool isReductionLoop(const Instruction &inst) {
bool isReductionLoop(Instruction &inst) {
auto loop = inst.cast<AffineForOp>();
return loop || true; // loop->isReduction();
};
bool isLoadOrStore(const Instruction &inst) {
bool isLoadOrStore(Instruction &inst) {
return inst.isa<LoadOp>() || inst.isa<StoreOp>();
};

View File

@ -39,7 +39,7 @@ using llvm::SmallDenseMap;
/// Populates 'loops' with IVs of the loops surrounding 'inst' ordered from
/// the outermost 'for' instruction to the innermost one.
void mlir::getLoopIVs(const Instruction &inst,
void mlir::getLoopIVs(Instruction &inst,
SmallVectorImpl<OpPointer<AffineForOp>> *loops) {
auto *currInst = inst.getParentInst();
OpPointer<AffineForOp> currAffineForOp;
@ -431,7 +431,7 @@ template LogicalResult mlir::boundCheckLoadOrStoreOp(OpPointer<StoreOp> storeOp,
// Returns in 'positions' the Block positions of 'inst' in each ancestor
// Block from the Block containing instruction, stopping at 'limitBlock'.
static void findInstPosition(const Instruction *inst, Block *limitBlock,
static void findInstPosition(Instruction *inst, Block *limitBlock,
SmallVectorImpl<unsigned> *positions) {
Block *block = inst->getBlock();
while (block != limitBlock) {
@ -653,8 +653,8 @@ bool MemRefAccess::isStore() const { return opInst->isa<StoreOp>(); }
/// Returns the nesting depth of this statement, i.e., the number of loops
/// surrounding this statement.
unsigned mlir::getNestingDepth(const Instruction &inst) {
const Instruction *currInst = &inst;
unsigned mlir::getNestingDepth(Instruction &inst) {
Instruction *currInst = &inst;
unsigned depth = 0;
while ((currInst = currInst->getParentInst())) {
if (currInst->isa<AffineForOp>())
@ -665,8 +665,7 @@ unsigned mlir::getNestingDepth(const Instruction &inst) {
/// Returns the number of surrounding loops common to 'loopsA' and 'loopsB',
/// where each lists loops from outer-most to inner-most in loop nest.
unsigned mlir::getNumCommonSurroundingLoops(const Instruction &A,
const Instruction &B) {
unsigned mlir::getNumCommonSurroundingLoops(Instruction &A, Instruction &B) {
SmallVector<OpPointer<AffineForOp>, 4> loopsA, loopsB;
getLoopIVs(A, &loopsA);
getLoopIVs(B, &loopsB);

View File

@ -180,7 +180,7 @@ AffineMap mlir::makePermutationMap(
enclosingLoopToVectorDim);
}
bool mlir::matcher::operatesOnSuperVectors(const Instruction &opInst,
bool mlir::matcher::operatesOnSuperVectors(Instruction &opInst,
VectorType subVectorType) {
// First, extract the vector type and ditinguish between:
// a. ops that *must* lower a super-vector (i.e. vector_transfer_read,

View File

@ -52,7 +52,7 @@ namespace {
///
class FuncVerifier {
public:
bool failure(const Twine &message, const Instruction &value) {
bool failure(const Twine &message, Instruction &value) {
return value.emitError(message);
}
@ -108,9 +108,9 @@ public:
bool verify();
bool verifyBlock(Block &block, bool isTopLevel);
bool verifyOperation(const Instruction &op);
bool verifyOperation(Instruction &op);
bool verifyDominance(Block &block);
bool verifyInstDominance(const Instruction &inst);
bool verifyInstDominance(Instruction &inst);
explicit FuncVerifier(Function &fn)
: fn(fn), identifierRegex("^[a-zA-Z_][a-zA-Z_0-9\\.\\$]*$") {}
@ -270,12 +270,12 @@ bool FuncVerifier::verifyBlock(Block &block, bool isTopLevel) {
}
/// Check the invariants of the specified operation.
bool FuncVerifier::verifyOperation(const Instruction &op) {
bool FuncVerifier::verifyOperation(Instruction &op) {
if (op.getFunction() != &fn)
return failure("operation in the wrong function", op);
// Check that operands are non-nil and structurally ok.
for (const auto *operand : op.getOperands()) {
for (auto *operand : op.getOperands()) {
if (!operand)
return failure("null operand found", op);
@ -322,7 +322,7 @@ bool FuncVerifier::verifyDominance(Block &block) {
return false;
}
bool FuncVerifier::verifyInstDominance(const Instruction &inst) {
bool FuncVerifier::verifyInstDominance(Instruction &inst) {
// Check that operands properly dominate this use.
for (unsigned operandNo = 0, e = inst.getNumOperands(); operandNo != e;
++operandNo) {

View File

@ -184,7 +184,7 @@ static bool isSameShapedVectorOrTensor(Type type1, Type type2) {
return false;
}
bool OpTrait::impl::verifyCompatibleOperandBroadcast(const Instruction *op) {
bool OpTrait::impl::verifyCompatibleOperandBroadcast(Instruction *op) {
assert(op->getNumOperands() == 2 &&
"only support broadcast check on two operands");
assert(op->getNumResults() == 1 &&

View File

@ -45,8 +45,8 @@ using namespace mlir;
using namespace mlir::edsc;
using namespace mlir::edsc::detail;
static void printDefininingStatement(llvm::raw_ostream &os, const Value &v) {
const auto *inst = v.getDefiningInst();
static void printDefininingStatement(llvm::raw_ostream &os, Value &v) {
auto *inst = v.getDefiningInst();
if (inst) {
inst->print(os);
return;

View File

@ -138,7 +138,7 @@ private:
void recordTypeReference(Type ty) { usedTypes.insert(ty); }
// Visit functions.
void visitInstruction(const Instruction *inst);
void visitInstruction(Instruction *inst);
void visitType(Type type);
void visitAttribute(Attribute attr);
@ -189,7 +189,7 @@ void ModuleState::visitAttribute(Attribute attr) {
}
}
void ModuleState::visitInstruction(const Instruction *inst) {
void ModuleState::visitInstruction(Instruction *inst) {
// Visit all the types used in the operation.
for (auto *operand : inst->getOperands())
visitType(operand->getType());
@ -1060,11 +1060,11 @@ public:
void printFunctionSignature();
// Methods to print instructions.
void print(const Instruction *inst);
void print(Instruction *inst);
void print(Block *block, bool printBlockArgs = true);
void printOperation(const Instruction *op);
void printGenericOp(const Instruction *op);
void printOperation(Instruction *op);
void printGenericOp(Instruction *op);
// Implement OpAsmPrinter.
raw_ostream &getStream() const { return os; }
@ -1085,7 +1085,7 @@ public:
void printFunctionReference(Function *func) {
return ModulePrinter::printFunctionReference(func);
}
void printOperand(const Value *value) { printValueID(value); }
void printOperand(Value *value) { printValueID(value); }
void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
ArrayRef<StringRef> elidedAttrs = {}) {
@ -1107,8 +1107,7 @@ public:
return it != blockIDs.end() ? it->second : ~0U;
}
void printSuccessorAndUseList(const Instruction *term,
unsigned index) override;
void printSuccessorAndUseList(Instruction *term, unsigned index) override;
/// Print a region.
void printRegion(Region &blocks, bool printEntryBlockArgs) override {
@ -1127,17 +1126,17 @@ public:
const static unsigned indentWidth = 2;
protected:
void numberValueID(const Value *value);
void numberValueID(Value *value);
void numberValuesInBlock(Block &block);
void printValueID(const Value *value, bool printResultNo = true) const;
void printValueID(Value *value, bool printResultNo = true) const;
private:
Function *function;
/// This is the value ID for each SSA value in the current function. If this
/// returns ~0, then the valueID has an entry in valueNames.
DenseMap<const Value *, unsigned> valueIDs;
DenseMap<const Value *, StringRef> valueNames;
DenseMap<Value *, unsigned> valueIDs;
DenseMap<Value *, StringRef> valueNames;
/// This is the block ID for each block in the current function.
DenseMap<Block *, unsigned> blockIDs;
@ -1191,7 +1190,7 @@ void FunctionPrinter::numberValuesInBlock(Block &block) {
}
}
void FunctionPrinter::numberValueID(const Value *value) {
void FunctionPrinter::numberValueID(Value *value) {
assert(!valueIDs.count(value) && "Value numbered multiple times");
SmallString<32> specialNameBuffer;
@ -1389,14 +1388,13 @@ void FunctionPrinter::print(Block *block, bool printBlockArgs) {
currentIndent -= indentWidth;
}
void FunctionPrinter::print(const Instruction *inst) {
void FunctionPrinter::print(Instruction *inst) {
os.indent(currentIndent);
printOperation(inst);
printTrailingLocation(inst->getLoc());
}
void FunctionPrinter::printValueID(const Value *value,
bool printResultNo) const {
void FunctionPrinter::printValueID(Value *value, bool printResultNo) const {
int resultNo = -1;
auto lookupValue = value;
@ -1434,7 +1432,7 @@ void FunctionPrinter::printValueID(const Value *value,
os << '#' << resultNo;
}
void FunctionPrinter::printOperation(const Instruction *op) {
void FunctionPrinter::printOperation(Instruction *op) {
if (op->getNumResults()) {
printValueID(op->getResult(0), /*printResultNo=*/false);
os << " = ";
@ -1454,7 +1452,7 @@ void FunctionPrinter::printOperation(const Instruction *op) {
printGenericOp(op);
}
void FunctionPrinter::printGenericOp(const Instruction *op) {
void FunctionPrinter::printGenericOp(Instruction *op) {
os << '"';
printEscapedString(op->getName().getStringRef(), os);
os << "\"(";
@ -1465,11 +1463,10 @@ void FunctionPrinter::printGenericOp(const Instruction *op) {
for (unsigned i = 0; i < numSuccessors; ++i)
totalNumSuccessorOperands += op->getNumSuccessorOperands(i);
unsigned numProperOperands = op->getNumOperands() - totalNumSuccessorOperands;
SmallVector<const Value *, 8> properOperands(
SmallVector<Value *, 8> properOperands(
op->operand_begin(), std::next(op->operand_begin(), numProperOperands));
interleaveComma(properOperands,
[&](const Value *value) { printValueID(value); });
interleaveComma(properOperands, [&](Value *value) { printValueID(value); });
os << ')';
@ -1490,7 +1487,7 @@ void FunctionPrinter::printGenericOp(const Instruction *op) {
// Print the type signature of the operation.
os << " : (";
interleaveComma(properOperands,
[&](const Value *value) { printType(value->getType()); });
[&](Value *value) { printType(value->getType()); });
os << ") -> ";
if (op->getNumResults() == 1 &&
@ -1499,7 +1496,7 @@ void FunctionPrinter::printGenericOp(const Instruction *op) {
} else {
os << '(';
interleaveComma(op->getResults(),
[&](const Value *result) { printType(result->getType()); });
[&](Value *result) { printType(result->getType()); });
os << ')';
}
@ -1508,7 +1505,7 @@ void FunctionPrinter::printGenericOp(const Instruction *op) {
printRegion(region, /*printEntryBlockArgs=*/true);
}
void FunctionPrinter::printSuccessorAndUseList(const Instruction *term,
void FunctionPrinter::printSuccessorAndUseList(Instruction *term,
unsigned index) {
printBlockName(term->getSuccessor(index));
@ -1518,11 +1515,10 @@ void FunctionPrinter::printSuccessorAndUseList(const Instruction *term,
os << '(';
interleaveComma(succOperands,
[this](const Value *operand) { printValueID(operand); });
[this](Value *operand) { printValueID(operand); });
os << " : ";
interleaveComma(succOperands, [this](const Value *operand) {
printType(operand->getType());
});
interleaveComma(succOperands,
[this](Value *operand) { printType(operand->getType()); });
os << ')';
}
@ -1585,7 +1581,7 @@ void IntegerSet::print(raw_ostream &os) const {
ModulePrinter(os, state).printIntegerSet(*this);
}
void Value::print(raw_ostream &os) const {
void Value::print(raw_ostream &os) {
switch (getKind()) {
case Value::Kind::BlockArgument:
// TODO: Improve this.
@ -1596,9 +1592,9 @@ void Value::print(raw_ostream &os) const {
}
}
void Value::dump() const { print(llvm::errs()); }
void Value::dump() { print(llvm::errs()); }
void Instruction::print(raw_ostream &os) const {
void Instruction::print(raw_ostream &os) {
auto *function = getFunction();
if (!function) {
os << "<<UNLINKED INSTRUCTION>>\n";
@ -1610,7 +1606,7 @@ void Instruction::print(raw_ostream &os) const {
FunctionPrinter(function, modulePrinter).print(this);
}
void Instruction::dump() const {
void Instruction::dump() {
print(llvm::errs());
llvm::errs() << "\n";
}

View File

@ -26,7 +26,7 @@ using namespace mlir;
//===----------------------------------------------------------------------===//
/// Returns the number of this argument.
unsigned BlockArgument::getArgNumber() const {
unsigned BlockArgument::getArgNumber() {
// Arguments are not stored in place, so we have to find it within the list.
auto argList = getOwner()->getArguments();
return std::distance(argList.begin(), llvm::find(argList, this));
@ -78,7 +78,7 @@ void Block::eraseFromFunction() {
/// Returns 'inst' if 'inst' lies in this block, or otherwise finds the
/// ancestor instruction of 'inst' that lies in this block. Returns nullptr if
/// the latter fails.
Instruction *Block::findAncestorInstInBlock(const Instruction &inst) {
Instruction *Block::findAncestorInstInBlock(Instruction &inst) {
// Traverse up the instruction hierarchy starting from the owner of operand to
// find the ancestor instruction that resides in the block of 'forInst'.
auto *currInst = const_cast<Instruction *>(&inst);
@ -109,7 +109,7 @@ bool Block::verifyInstOrder() {
std::next(instructions.begin()) == instructions.end())
return false;
const Instruction *prev = nullptr;
Instruction *prev = nullptr;
for (auto &i : *this) {
// The previous instruction must have a smaller order index than the next as
// it appears earlier in the list.
@ -306,12 +306,12 @@ void Region::cloneInto(Region *dest, BlockAndValueMapping &mapper,
// Clone the block arguments. The user might be deleting arguments to the
// block by specifying them in the mapper. If so, we don't add the
// argument to the cloned block.
for (const auto *arg : block.getArguments())
for (auto *arg : block.getArguments())
if (!mapper.contains(arg))
mapper.map(arg, newBlock->addArgument(arg->getType()));
// Clone and remap the instructions within this block.
for (const auto &inst : block)
for (auto &inst : block)
newBlock->push_back(inst.clone(mapper, context));
dest->push_back(newBlock);

View File

@ -33,7 +33,7 @@ using namespace mlir;
//===----------------------------------------------------------------------===//
/// Return the result number of this result.
unsigned InstResult::getResultNumber() const {
unsigned InstResult::getResultNumber() {
// Results are always stored consecutively, so use pointer subtraction to
// figure out what number this is.
return this - &getOwner()->getInstResults()[0];
@ -44,7 +44,7 @@ unsigned InstResult::getResultNumber() const {
//===----------------------------------------------------------------------===//
/// Return which operand this is in the operand list.
template <> unsigned InstOperand::getOperandNumber() const {
template <> unsigned InstOperand::getOperandNumber() {
return this - &getOwner()->getInstOperands()[0];
}
@ -53,7 +53,7 @@ template <> unsigned InstOperand::getOperandNumber() const {
//===----------------------------------------------------------------------===//
/// Return which operand this is in the operand list.
template <> unsigned BlockOperand::getOperandNumber() const {
template <> unsigned BlockOperand::getOperandNumber() {
return this - &getOwner()->getBlockOperands()[0];
}
@ -287,7 +287,7 @@ void Instruction::destroy() {
}
/// Return the context this operation is associated with.
MLIRContext *Instruction::getContext() const {
MLIRContext *Instruction::getContext() {
// If we have a result or operand type, that is a constant time way to get
// to the context.
if (getNumResults())
@ -300,11 +300,11 @@ MLIRContext *Instruction::getContext() const {
return getFunction()->getContext();
}
Instruction *Instruction::getParentInst() const {
Instruction *Instruction::getParentInst() {
return block ? block->getContainingInst() : nullptr;
}
Function *Instruction::getFunction() const {
Function *Instruction::getFunction() {
return block ? block->getFunction() : nullptr;
}
@ -339,14 +339,14 @@ void Instruction::walkPostOrder(
/// Emit a note about this instruction, reporting up to any diagnostic
/// handlers that may be listening.
void Instruction::emitNote(const Twine &message) const {
void Instruction::emitNote(const Twine &message) {
getContext()->emitDiagnostic(getLoc(), message,
MLIRContext::DiagnosticKind::Note);
}
/// Emit a warning about this instruction, reporting up to any diagnostic
/// handlers that may be listening.
void Instruction::emitWarning(const Twine &message) const {
void Instruction::emitWarning(const Twine &message) {
getContext()->emitDiagnostic(getLoc(), message,
MLIRContext::DiagnosticKind::Warning);
}
@ -355,7 +355,7 @@ void Instruction::emitWarning(const Twine &message) const {
/// any diagnostic handlers that may be listening. This function always
/// returns true. NOTE: This may terminate the containing application, only
/// use when the IR is in an inconsistent state.
bool Instruction::emitError(const Twine &message) const {
bool Instruction::emitError(const Twine &message) {
return getContext()->emitError(getLoc(), message);
}
@ -364,7 +364,7 @@ bool Instruction::emitError(const Twine &message) const {
/// of the parent block.
/// Note: This function has an average complexity of O(1), but worst case may
/// take O(N) where N is the number of instructions within the parent block.
bool Instruction::isBeforeInBlock(const Instruction *other) const {
bool Instruction::isBeforeInBlock(Instruction *other) {
assert(block && "Instructions without parent blocks have no order.");
assert(other && other->block == block &&
"Expected other instruction to have the same parent block.");
@ -490,7 +490,7 @@ void Instruction::dropAllReferences() {
}
/// Return true if there are no users of any results of this operation.
bool Instruction::use_empty() const {
bool Instruction::use_empty() {
for (auto *result : getResults())
if (!result->use_empty())
return false;
@ -502,10 +502,6 @@ void Instruction::setSuccessor(Block *block, unsigned index) {
getBlockOperands()[index].set(block);
}
auto Instruction::getNonSuccessorOperands() const -> const_operand_range {
return {const_operand_iterator(this, 0),
const_operand_iterator(this, getSuccessorOperandIndex(0))};
}
auto Instruction::getNonSuccessorOperands() -> operand_range {
return {operand_iterator(this, 0),
operand_iterator(this, getSuccessorOperandIndex(0))};
@ -513,7 +509,7 @@ auto Instruction::getNonSuccessorOperands() -> operand_range {
/// Get the index of the first operand of the successor at the provided
/// index.
unsigned Instruction::getSuccessorOperandIndex(unsigned index) const {
unsigned Instruction::getSuccessorOperandIndex(unsigned index) {
assert(!isKnownNonTerminator() && "only terminators may have successors");
assert(index < getNumSuccessors());
@ -527,13 +523,6 @@ unsigned Instruction::getSuccessorOperandIndex(unsigned index) const {
return getNumOperands() - postSuccessorOpCount;
}
auto Instruction::getSuccessorOperands(unsigned index) const
-> const_operand_range {
unsigned succOperandIndex = getSuccessorOperandIndex(index);
return {const_operand_iterator(this, succOperandIndex),
const_operand_iterator(this, succOperandIndex +
getNumSuccessorOperands(index))};
}
auto Instruction::getSuccessorOperands(unsigned index) -> operand_range {
unsigned succOperandIndex = getSuccessorOperandIndex(index);
return {operand_iterator(this, succOperandIndex),
@ -544,19 +533,16 @@ auto Instruction::getSuccessorOperands(unsigned index) -> operand_range {
/// Attempt to constant fold this operation with the specified constant
/// operand values. If successful, this fills in the results vector. If not,
/// results is unspecified.
LogicalResult
Instruction::constantFold(ArrayRef<Attribute> operands,
SmallVectorImpl<Attribute> &results) const {
auto *inst = const_cast<Instruction *>(this);
LogicalResult Instruction::constantFold(ArrayRef<Attribute> operands,
SmallVectorImpl<Attribute> &results) {
if (auto *abstractOp = getAbstractOperation()) {
// If we have a registered operation definition matching this one, use it to
// try to constant fold the operation.
if (succeeded(abstractOp->constantFoldHook(inst, operands, results)))
if (succeeded(abstractOp->constantFoldHook(this, operands, results)))
return success();
// Otherwise, fall back on the dialect hook to handle it.
return abstractOp->dialect.constantFoldHook(inst, operands, results);
return abstractOp->dialect.constantFoldHook(this, operands, results);
}
// If this operation hasn't been registered or doesn't have abstract
@ -564,7 +550,7 @@ Instruction::constantFold(ArrayRef<Attribute> operands,
auto opName = getName().getStringRef();
auto dialectPrefix = opName.split('.').first;
if (auto *dialect = getContext()->getRegisteredDialect(dialectPrefix))
return dialect->constantFoldHook(inst, operands, results);
return dialect->constantFoldHook(this, operands, results);
return failure();
}
@ -582,7 +568,7 @@ LogicalResult Instruction::fold(SmallVectorImpl<Value *> &results) {
/// Emit an error with the op name prefixed, like "'dim' op " which is
/// convenient for verifiers.
bool Instruction::emitOpError(const Twine &message) const {
bool Instruction::emitOpError(const Twine &message) {
return emitError(Twine('\'') + getName().getStringRef() + "' op " + message);
}
@ -596,7 +582,7 @@ bool Instruction::emitOpError(const Twine &message) const {
/// sub-instructions to the corresponding instruction that is copied, and adds
/// those mappings to the map.
Instruction *Instruction::clone(BlockAndValueMapping &mapper,
MLIRContext *context) const {
MLIRContext *context) {
SmallVector<Value *, 8> operands;
SmallVector<Block *, 2> successors;
@ -605,7 +591,7 @@ Instruction *Instruction::clone(BlockAndValueMapping &mapper,
if (getNumSuccessors() == 0) {
// Non-branching operations can just add all the operands.
for (auto *opValue : getOperands())
operands.push_back(mapper.lookupOrDefault(const_cast<Value *>(opValue)));
operands.push_back(mapper.lookupOrDefault(opValue));
} else {
// We add the operands separated by nullptr's for each successor.
unsigned firstSuccOperand =
@ -614,21 +600,18 @@ Instruction *Instruction::clone(BlockAndValueMapping &mapper,
unsigned i = 0;
for (; i != firstSuccOperand; ++i)
operands.push_back(
mapper.lookupOrDefault(const_cast<Value *>(InstOperands[i].get())));
operands.push_back(mapper.lookupOrDefault(InstOperands[i].get()));
successors.reserve(getNumSuccessors());
for (unsigned succ = 0, e = getNumSuccessors(); succ != e; ++succ) {
successors.push_back(
mapper.lookupOrDefault(const_cast<Block *>(getSuccessor(succ))));
successors.push_back(mapper.lookupOrDefault(getSuccessor(succ)));
// Add sentinel to delineate successor operands.
operands.push_back(nullptr);
// Remap the successors operands.
for (auto *operand : getSuccessorOperands(succ))
operands.push_back(
mapper.lookupOrDefault(const_cast<Value *>(operand)));
operands.push_back(mapper.lookupOrDefault(operand));
}
}
@ -652,7 +635,7 @@ Instruction *Instruction::clone(BlockAndValueMapping &mapper,
return newOp;
}
Instruction *Instruction::clone(MLIRContext *context) const {
Instruction *Instruction::clone(MLIRContext *context) {
BlockAndValueMapping mapper;
return clone(mapper, context);
}

View File

@ -93,20 +93,19 @@ void OpState::emitNote(const Twine &message) const {
// Op Trait implementations
//===----------------------------------------------------------------------===//
bool OpTrait::impl::verifyZeroOperands(const Instruction *op) {
bool OpTrait::impl::verifyZeroOperands(Instruction *op) {
if (op->getNumOperands() != 0)
return op->emitOpError("requires zero operands");
return false;
}
bool OpTrait::impl::verifyOneOperand(const Instruction *op) {
bool OpTrait::impl::verifyOneOperand(Instruction *op) {
if (op->getNumOperands() != 1)
return op->emitOpError("requires a single operand");
return false;
}
bool OpTrait::impl::verifyNOperands(const Instruction *op,
unsigned numOperands) {
bool OpTrait::impl::verifyNOperands(Instruction *op, unsigned numOperands) {
if (op->getNumOperands() != numOperands) {
return op->emitOpError("expected " + Twine(numOperands) +
" operands, but found " +
@ -115,7 +114,7 @@ bool OpTrait::impl::verifyNOperands(const Instruction *op,
return false;
}
bool OpTrait::impl::verifyAtLeastNOperands(const Instruction *op,
bool OpTrait::impl::verifyAtLeastNOperands(Instruction *op,
unsigned numOperands) {
if (op->getNumOperands() < numOperands)
return op->emitOpError("expected " + Twine(numOperands) +
@ -135,7 +134,7 @@ static Type getTensorOrVectorElementType(Type type) {
return type;
}
bool OpTrait::impl::verifyOperandsAreIntegerLike(const Instruction *op) {
bool OpTrait::impl::verifyOperandsAreIntegerLike(Instruction *op) {
for (auto *operand : op->getOperands()) {
auto type = getTensorOrVectorElementType(operand->getType());
if (!type.isIntOrIndex())
@ -144,7 +143,7 @@ bool OpTrait::impl::verifyOperandsAreIntegerLike(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifySameTypeOperands(const Instruction *op) {
bool OpTrait::impl::verifySameTypeOperands(Instruction *op) {
// Zero or one operand always have the "same" type.
unsigned nOperands = op->getNumOperands();
if (nOperands < 2)
@ -158,26 +157,25 @@ bool OpTrait::impl::verifySameTypeOperands(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifyZeroResult(const Instruction *op) {
bool OpTrait::impl::verifyZeroResult(Instruction *op) {
if (op->getNumResults() != 0)
return op->emitOpError("requires zero results");
return false;
}
bool OpTrait::impl::verifyOneResult(const Instruction *op) {
bool OpTrait::impl::verifyOneResult(Instruction *op) {
if (op->getNumResults() != 1)
return op->emitOpError("requires one result");
return false;
}
bool OpTrait::impl::verifyNResults(const Instruction *op,
unsigned numOperands) {
bool OpTrait::impl::verifyNResults(Instruction *op, unsigned numOperands) {
if (op->getNumResults() != numOperands)
return op->emitOpError("expected " + Twine(numOperands) + " results");
return false;
}
bool OpTrait::impl::verifyAtLeastNResults(const Instruction *op,
bool OpTrait::impl::verifyAtLeastNResults(Instruction *op,
unsigned numOperands) {
if (op->getNumResults() < numOperands)
return op->emitOpError("expected " + Twine(numOperands) +
@ -206,7 +204,7 @@ static bool verifyShapeMatch(Type type1, Type type2) {
return false;
}
bool OpTrait::impl::verifySameOperandsAndResultShape(const Instruction *op) {
bool OpTrait::impl::verifySameOperandsAndResultShape(Instruction *op) {
if (op->getNumOperands() == 0 || op->getNumResults() == 0)
return true;
@ -224,7 +222,7 @@ bool OpTrait::impl::verifySameOperandsAndResultShape(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifySameOperandsAndResultType(const Instruction *op) {
bool OpTrait::impl::verifySameOperandsAndResultType(Instruction *op) {
if (op->getNumOperands() == 0 || op->getNumResults() == 0)
return true;
@ -242,9 +240,9 @@ bool OpTrait::impl::verifySameOperandsAndResultType(const Instruction *op) {
return false;
}
static bool verifyBBArguments(
llvm::iterator_range<Instruction::const_operand_iterator> operands,
Block *destBB, const Instruction *op) {
static bool
verifyBBArguments(llvm::iterator_range<Instruction::operand_iterator> operands,
Block *destBB, Instruction *op) {
unsigned operandCount = std::distance(operands.begin(), operands.end());
if (operandCount != destBB->getNumArguments())
return op->emitError("branch has " + Twine(operandCount) +
@ -260,7 +258,7 @@ static bool verifyBBArguments(
return false;
}
static bool verifyTerminatorSuccessors(const Instruction *op) {
static bool verifyTerminatorSuccessors(Instruction *op) {
// Verify that the operands lines up with the BB arguments in the successor.
Function *fn = op->getFunction();
for (unsigned i = 0, e = op->getNumSuccessors(); i != e; ++i) {
@ -273,7 +271,7 @@ static bool verifyTerminatorSuccessors(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifyIsTerminator(const Instruction *op) {
bool OpTrait::impl::verifyIsTerminator(Instruction *op) {
Block *block = op->getBlock();
// Verify that the operation is at the end of the respective parent block.
if (!block || &block->back() != op)
@ -285,7 +283,7 @@ bool OpTrait::impl::verifyIsTerminator(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifyResultsAreBoolLike(const Instruction *op) {
bool OpTrait::impl::verifyResultsAreBoolLike(Instruction *op) {
for (auto *result : op->getResults()) {
auto elementType = getTensorOrVectorElementType(result->getType());
bool isBoolType = elementType.isInteger(1);
@ -296,7 +294,7 @@ bool OpTrait::impl::verifyResultsAreBoolLike(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifyResultsAreFloatLike(const Instruction *op) {
bool OpTrait::impl::verifyResultsAreFloatLike(Instruction *op) {
for (auto *result : op->getResults()) {
if (!getTensorOrVectorElementType(result->getType()).isa<FloatType>())
return op->emitOpError("requires a floating point type");
@ -305,7 +303,7 @@ bool OpTrait::impl::verifyResultsAreFloatLike(const Instruction *op) {
return false;
}
bool OpTrait::impl::verifyResultsAreIntegerLike(const Instruction *op) {
bool OpTrait::impl::verifyResultsAreIntegerLike(Instruction *op) {
for (auto *result : op->getResults()) {
auto type = getTensorOrVectorElementType(result->getType());
if (!type.isIntOrIndex())
@ -338,7 +336,7 @@ bool impl::parseBinaryOp(OpAsmParser *parser, OperationState *result) {
parser->addTypeToList(type, result->types);
}
void impl::printBinaryOp(const Instruction *op, OpAsmPrinter *p) {
void impl::printBinaryOp(Instruction *op, OpAsmPrinter *p) {
assert(op->getNumOperands() == 2 && "binary op should have two operands");
assert(op->getNumResults() == 1 && "binary op should have one result");
@ -377,7 +375,7 @@ bool impl::parseCastOp(OpAsmParser *parser, OperationState *result) {
parser->addTypeToList(dstType, result->types);
}
void impl::printCastOp(const Instruction *op, OpAsmPrinter *p) {
void impl::printCastOp(Instruction *op, OpAsmPrinter *p) {
*p << op->getName() << ' ' << *op->getOperand(0) << " : "
<< op->getOperand(0)->getType() << " to " << op->getResult(0)->getType();
}

View File

@ -29,7 +29,7 @@ Instruction *Value::getDefiningInst() {
}
/// Return the function that this Value is defined in.
Function *Value::getFunction() const {
Function *Value::getFunction() {
switch (getKind()) {
case Value::Kind::BlockArgument:
return cast<BlockArgument>(this)->getFunction();
@ -64,14 +64,14 @@ void IRObjectWithUseList::dropAllUses() {
//===----------------------------------------------------------------------===//
/// Return the function that this argument is defined in.
Function *BlockArgument::getFunction() const {
Function *BlockArgument::getFunction() {
if (auto *owner = getOwner())
return owner->getFunction();
return nullptr;
}
/// Returns if the current argument is a function argument.
bool BlockArgument::isFunctionArgument() const {
bool BlockArgument::isFunctionArgument() {
auto *containingFn = getFunction();
return containingFn && &containingFn->front() == getOwner();
}

View File

@ -36,7 +36,7 @@ using namespace mlir;
/// A custom binary operation printer that omits the "std." prefix from the
/// operation names.
void detail::printStandardBinaryOp(const Instruction *op, OpAsmPrinter *p) {
void detail::printStandardBinaryOp(Instruction *op, OpAsmPrinter *p) {
assert(op->getNumOperands() == 2 && "binary op should have two operands");
assert(op->getNumResults() == 1 && "binary op should have one result");
@ -68,8 +68,8 @@ StandardOpsDialect::StandardOpsDialect(MLIRContext *context)
>();
}
void mlir::printDimAndSymbolList(Instruction::const_operand_iterator begin,
Instruction::const_operand_iterator end,
void mlir::printDimAndSymbolList(Instruction::operand_iterator begin,
Instruction::operand_iterator end,
unsigned numDims, OpAsmPrinter *p) {
*p << '(';
p->printOperands(begin, begin + numDims);
@ -1803,8 +1803,7 @@ void ReturnOp::print(OpAsmPrinter *p) {
*p << " : ";
interleave(
operand_begin(), operand_end(),
[&](const Value *e) { p->printType(e->getType()); },
[&]() { *p << ", "; });
[&](Value *e) { p->printType(e->getType()); }, [&]() { *p << ", "; });
}
}

View File

@ -92,13 +92,6 @@ VectorTransferReadOp::getIndices() {
return {begin, end};
}
llvm::iterator_range<Instruction::const_operand_iterator>
VectorTransferReadOp::getIndices() const {
auto begin = getInstruction()->operand_begin() + Offsets::FirstIndexOffset;
auto end = begin + getMemRefType().getRank();
return {begin, end};
}
Optional<Value *> VectorTransferReadOp::getPaddingValue() {
auto memRefRank = getMemRefType().getRank();
if (getNumOperands() <= Offsets::FirstIndexOffset + memRefRank) {
@ -107,16 +100,7 @@ Optional<Value *> VectorTransferReadOp::getPaddingValue() {
return Optional<Value *>(getOperand(Offsets::FirstIndexOffset + memRefRank));
}
Optional<const Value *> VectorTransferReadOp::getPaddingValue() const {
auto memRefRank = getMemRefType().getRank();
if (getNumOperands() <= Offsets::FirstIndexOffset + memRefRank) {
return None;
}
return Optional<const Value *>(
getOperand(Offsets::FirstIndexOffset + memRefRank));
}
AffineMap VectorTransferReadOp::getPermutationMap() const {
AffineMap VectorTransferReadOp::getPermutationMap() {
return getAttrOfType<AffineMapAttr>(getPermutationMapAttrName()).getValue();
}
@ -134,7 +118,7 @@ void VectorTransferReadOp::print(OpAsmPrinter *p) {
// Construct the FunctionType and print it.
llvm::SmallVector<Type, 8> inputs{getMemRefType()};
// Must have at least one actual index, see verify.
const Value *firstIndex = *(getIndices().begin());
Value *firstIndex = *getIndices().begin();
Type indexType = firstIndex->getType();
inputs.append(getMemRefType().getRank(), indexType);
if (optionalPaddingValue) {
@ -309,14 +293,7 @@ VectorTransferWriteOp::getIndices() {
return {begin, end};
}
llvm::iterator_range<Instruction::const_operand_iterator>
VectorTransferWriteOp::getIndices() const {
auto begin = getInstruction()->operand_begin() + Offsets::FirstIndexOffset;
auto end = begin + getMemRefType().getRank();
return {begin, end};
}
AffineMap VectorTransferWriteOp::getPermutationMap() const {
AffineMap VectorTransferWriteOp::getPermutationMap() {
return getAttrOfType<AffineMapAttr>(getPermutationMapAttrName()).getValue();
}

View File

@ -59,7 +59,7 @@ private:
bool convertOneFunction(Function &func);
void connectPHINodes(Function &func);
bool convertBlock(Block &bb, bool ignoreArguments);
bool convertInstruction(const Instruction &inst, llvm::IRBuilder<> &builder);
bool convertInstruction(Instruction &inst, llvm::IRBuilder<> &builder);
template <typename Range>
SmallVector<llvm::Value *, 8> lookupValues(Range &&values);
@ -73,7 +73,7 @@ private:
// Mappings between original and translated values, used for lookups.
llvm::DenseMap<Function *, llvm::Function *> functionMapping;
llvm::DenseMap<const Value *, llvm::Value *> valueMapping;
llvm::DenseMap<Value *, llvm::Value *> valueMapping;
llvm::DenseMap<Block *, llvm::BasicBlock *> blockMapping;
};
} // end anonymous namespace
@ -185,7 +185,7 @@ template <typename Range>
SmallVector<llvm::Value *, 8> ModuleTranslation::lookupValues(Range &&values) {
SmallVector<llvm::Value *, 8> remapped;
remapped.reserve(llvm::size(values));
for (const Value *v : values) {
for (Value *v : values) {
remapped.push_back(valueMapping.lookup(v));
}
return remapped;
@ -195,7 +195,7 @@ SmallVector<llvm::Value *, 8> ModuleTranslation::lookupValues(Range &&values) {
// using the `builder`. LLVM IR Builder does not have a generic interface so
// this has to be a long chain of `if`s calling different functions with a
// different number of arguments.
bool ModuleTranslation::convertInstruction(const Instruction &inst,
bool ModuleTranslation::convertInstruction(Instruction &inst,
llvm::IRBuilder<> &builder) {
auto extractPosition = [](ArrayAttr attr) {
SmallVector<unsigned, 4> position;
@ -212,8 +212,7 @@ bool ModuleTranslation::convertInstruction(const Instruction &inst,
// itself. Otherwise, this is an indirect call and the callee is the first
// operand, look it up as a normal value. Return the llvm::Value representing
// the function result, which may be of llvm::VoidTy type.
auto convertCall = [this,
&builder](const Instruction &inst) -> llvm::Value * {
auto convertCall = [this, &builder](Instruction &inst) -> llvm::Value * {
auto operands = lookupValues(inst.getOperands());
ArrayRef<llvm::Value *> operandsRef(operands);
if (auto attr = inst.getAttrOfType<FunctionAttr>("callee")) {
@ -270,7 +269,7 @@ bool ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) {
auto predecessors = bb.getPredecessors();
unsigned numPredecessors =
std::distance(predecessors.begin(), predecessors.end());
for (const auto *arg : bb.getArguments()) {
for (auto *arg : bb.getArguments()) {
auto wrappedType = arg->getType().dyn_cast<LLVM::LLVMType>();
if (!wrappedType) {
arg->getType().getContext()->emitError(
@ -284,7 +283,7 @@ bool ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) {
}
// Traverse instructions.
for (const auto &inst : bb) {
for (auto &inst : bb) {
if (convertInstruction(inst, builder))
return true;
}
@ -294,8 +293,8 @@ bool ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) {
// Get the SSA value passed to the current block from the terminator instruction
// of its predecessor.
static const Value *getPHISourceValue(Block *current, Block *pred,
unsigned numArguments, unsigned index) {
static Value *getPHISourceValue(Block *current, Block *pred,
unsigned numArguments, unsigned index) {
auto &terminator = *pred->getTerminator();
if (terminator.isa<LLVM::BrOp>()) {
return terminator.getOperand(index);

View File

@ -39,7 +39,8 @@ using namespace mlir;
namespace {
// TODO(riverriddle) Handle commutative operations.
struct SimpleOperationInfo : public llvm::DenseMapInfo<Instruction *> {
static unsigned getHashValue(const Instruction *op) {
static unsigned getHashValue(const Instruction *opC) {
auto *op = const_cast<Instruction *>(opC);
// Hash the operations based upon their:
// - Instruction Name
// - Attributes
@ -50,7 +51,9 @@ struct SimpleOperationInfo : public llvm::DenseMapInfo<Instruction *> {
hash_combine_range(op->result_type_begin(), op->result_type_end()),
hash_combine_range(op->operand_begin(), op->operand_end()));
}
static bool isEqual(const Instruction *lhs, const Instruction *rhs) {
static bool isEqual(const Instruction *lhsC, const Instruction *rhsC) {
auto *lhs = const_cast<Instruction *>(lhsC);
auto *rhs = const_cast<Instruction *>(rhsC);
if (lhs == rhs)
return true;
if (lhs == getTombstoneKey() || lhs == getEmptyKey() ||

View File

@ -49,9 +49,8 @@ private:
// Utility that looks up a list of value in the value remapping table. Returns
// an empty vector if one of the values is not mapped yet.
SmallVector<Value *, 4>
lookupValues(const llvm::iterator_range<Instruction::const_operand_iterator>
&operands);
SmallVector<Value *, 4> lookupValues(
const llvm::iterator_range<Instruction::operand_iterator> &operands);
// Converts the given function to the dialect using hooks defined in
// `dialectConversion`. Returns the converted function or `nullptr` on error.
@ -102,10 +101,10 @@ private:
} // end namespace mlir
SmallVector<Value *, 4> impl::FunctionConversion::lookupValues(
const llvm::iterator_range<Instruction::const_operand_iterator> &operands) {
const llvm::iterator_range<Instruction::operand_iterator> &operands) {
SmallVector<Value *, 4> remapped;
remapped.reserve(llvm::size(operands));
for (const Value *operand : operands) {
for (Value *operand : operands) {
Value *value = mapping.lookupOrNull(operand);
if (!value)
return {};

View File

@ -477,7 +477,7 @@ bool DmaGeneration::runOnBlock(Block *block) {
// Get to the first load, store, or for op.
auto curBegin =
std::find_if(block->begin(), block->end(), [&](const Instruction &inst) {
std::find_if(block->begin(), block->end(), [&](Instruction &inst) {
return inst.isa<LoadOp>() || inst.isa<StoreOp>() ||
inst.isa<AffineForOp>();
});

View File

@ -142,7 +142,7 @@ struct LoopNestStateCollector {
};
// TODO(b/117228571) Replace when this is modeled through side-effects/op traits
static bool isMemRefDereferencingOp(const Instruction &op) {
static bool isMemRefDereferencingOp(Instruction &op) {
if (op.isa<LoadOp>() || op.isa<StoreOp>() || op.isa<DmaStartOp>() ||
op.isa<DmaWaitOp>())
return true;

View File

@ -192,7 +192,7 @@ struct MaterializationState {
VectorType superVectorType;
VectorType hwVectorType;
SmallVector<unsigned, 8> hwVectorInstance;
DenseMap<const Value *, Value *> *substitutionsMap;
DenseMap<Value *, Value *> *substitutionsMap;
};
struct MaterializeVectorsPass : public FunctionPass<MaterializeVectorsPass> {
@ -239,9 +239,9 @@ static SmallVector<unsigned, 8> delinearize(unsigned linearIndex,
return res;
}
static Instruction *
instantiate(FuncBuilder *b, Instruction *opInst, VectorType hwVectorType,
DenseMap<const Value *, Value *> *substitutionsMap);
static Instruction *instantiate(FuncBuilder *b, Instruction *opInst,
VectorType hwVectorType,
DenseMap<Value *, Value *> *substitutionsMap);
/// Not all Values belong to a program slice scoped within the immediately
/// enclosing loop.
@ -253,7 +253,7 @@ instantiate(FuncBuilder *b, Instruction *opInst, VectorType hwVectorType,
///
/// If substitution fails, returns nullptr.
static Value *substitute(Value *v, VectorType hwVectorType,
DenseMap<const Value *, Value *> *substitutionsMap) {
DenseMap<Value *, Value *> *substitutionsMap) {
auto it = substitutionsMap->find(v);
if (it == substitutionsMap->end()) {
auto *opInst = v->getDefiningInst();
@ -404,9 +404,9 @@ materializeAttributes(Instruction *opInst, VectorType hwVectorType) {
/// substitutionsMap.
///
/// If the underlying substitution fails, this fails too and returns nullptr.
static Instruction *
instantiate(FuncBuilder *b, Instruction *opInst, VectorType hwVectorType,
DenseMap<const Value *, Value *> *substitutionsMap) {
static Instruction *instantiate(FuncBuilder *b, Instruction *opInst,
VectorType hwVectorType,
DenseMap<Value *, Value *> *substitutionsMap) {
assert(!opInst->isa<VectorTransferReadOp>() &&
"Should call the function specialized for VectorTransferReadOp");
assert(!opInst->isa<VectorTransferWriteOp>() &&
@ -481,10 +481,10 @@ static AffineMap projectedPermutationMap(VectorTransferOpTy *transfer,
/// `hwVectorType` int the covering of the super-vector type. For a more
/// detailed description of the problem, see the description of
/// reindexAffineIndices.
static Instruction *
instantiate(FuncBuilder *b, VectorTransferReadOp *read, VectorType hwVectorType,
ArrayRef<unsigned> hwVectorInstance,
DenseMap<const Value *, Value *> *substitutionsMap) {
static Instruction *instantiate(FuncBuilder *b, VectorTransferReadOp *read,
VectorType hwVectorType,
ArrayRef<unsigned> hwVectorInstance,
DenseMap<Value *, Value *> *substitutionsMap) {
SmallVector<Value *, 8> indices =
map(makePtrDynCaster<Value>(), read->getIndices());
auto affineIndices =
@ -505,10 +505,10 @@ instantiate(FuncBuilder *b, VectorTransferReadOp *read, VectorType hwVectorType,
/// `hwVectorType` int the covering of th3e super-vector type. For a more
/// detailed description of the problem, see the description of
/// reindexAffineIndices.
static Instruction *
instantiate(FuncBuilder *b, VectorTransferWriteOp *write,
VectorType hwVectorType, ArrayRef<unsigned> hwVectorInstance,
DenseMap<const Value *, Value *> *substitutionsMap) {
static Instruction *instantiate(FuncBuilder *b, VectorTransferWriteOp *write,
VectorType hwVectorType,
ArrayRef<unsigned> hwVectorInstance,
DenseMap<Value *, Value *> *substitutionsMap) {
SmallVector<Value *, 8> indices =
map(makePtrDynCaster<Value>(), write->getIndices());
auto affineIndices =
@ -624,7 +624,7 @@ static bool emitSlice(MaterializationState *state,
// Fresh RAII instanceIndices and substitutionsMap.
MaterializationState scopedState = *state;
scopedState.hwVectorInstance = delinearize(idx, *ratio);
DenseMap<const Value *, Value *> substitutionMap;
DenseMap<Value *, Value *> substitutionMap;
scopedState.substitutionsMap = &substitutionMap;
// slice are topologically sorted, we can just clone them in order.
for (auto *inst : *slice) {
@ -749,7 +749,7 @@ void MaterializeVectorsPass::runOnFunction() {
// Capture terminators; i.e. vector_transfer_write ops involving a strict
// super-vector of subVectorType.
auto filter = [subVectorType](const Instruction &inst) {
auto filter = [subVectorType](Instruction &inst) {
if (!inst.isa<VectorTransferWriteOp>()) {
return false;
}

View File

@ -56,7 +56,7 @@ FunctionPassBase *mlir::createPipelineDataTransferPass() {
// Returns the position of the tag memref operand given a DMA instruction.
// Temporary utility: will be replaced when DmaStart/DmaFinish abstract op's are
// added. TODO(b/117228571)
static unsigned getTagMemRefPos(const Instruction &dmaInst) {
static unsigned getTagMemRefPos(Instruction &dmaInst) {
assert(dmaInst.isa<DmaStartOp>() || dmaInst.isa<DmaWaitOp>());
if (dmaInst.isa<DmaStartOp>()) {
// Second to last operand.
@ -323,7 +323,7 @@ void PipelineDataTransfer::runOnAffineForOp(OpPointer<AffineForOp> forOp) {
findMatchingStartFinishInsts(forOp, startWaitPairs);
// Store shift for instruction for later lookup for AffineApplyOp's.
DenseMap<const Instruction *, unsigned> instShiftMap;
DenseMap<Instruction *, unsigned> instShiftMap;
for (auto &pair : startWaitPairs) {
auto *dmaStartInst = pair.first;
assert(dmaStartInst->isa<DmaStartOp>());
@ -341,13 +341,13 @@ void PipelineDataTransfer::runOnAffineForOp(OpPointer<AffineForOp> forOp) {
SmallVector<Instruction *, 4> affineApplyInsts;
SmallVector<Value *, 4> operands(dmaStartInst->getOperands());
getReachableAffineApplyOps(operands, affineApplyInsts);
for (const auto *inst : affineApplyInsts) {
for (auto *inst : affineApplyInsts) {
instShiftMap[inst] = 0;
}
}
}
// Everything else (including compute ops and dma finish) are shifted by one.
for (const auto &inst : *forOp->getBody()) {
for (auto &inst : *forOp->getBody()) {
if (instShiftMap.find(&inst) == instShiftMap.end()) {
instShiftMap[&inst] = 1;
}

View File

@ -37,19 +37,19 @@ using namespace mlir;
/// Return true if this operation dereferences one or more memref's.
// Temporary utility: will be replaced when this is modeled through
// side-effects/op traits. TODO(b/117228571)
static bool isMemRefDereferencingOp(const Instruction &op) {
static bool isMemRefDereferencingOp(Instruction &op) {
if (op.isa<LoadOp>() || op.isa<StoreOp>() || op.isa<DmaStartOp>() ||
op.isa<DmaWaitOp>())
return true;
return false;
}
bool mlir::replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef,
bool mlir::replaceAllMemRefUsesWith(Value *oldMemRef, Value *newMemRef,
ArrayRef<Value *> extraIndices,
AffineMap indexRemap,
ArrayRef<Value *> extraOperands,
const Instruction *domInstFilter,
const Instruction *postDomInstFilter) {
Instruction *domInstFilter,
Instruction *postDomInstFilter) {
unsigned newMemRefRank = newMemRef->getType().cast<MemRefType>().getRank();
(void)newMemRefRank; // unused in opt mode
unsigned oldMemRefRank = oldMemRef->getType().cast<MemRefType>().getRank();
@ -167,7 +167,7 @@ bool mlir::replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef,
// Result types don't change. Both memref's are of the same elemental type.
state.types.reserve(opInst->getNumResults());
for (const auto *result : opInst->getResults())
for (auto *result : opInst->getResults())
state.types.push_back(result->getType());
// Attributes also do not change.

View File

@ -105,7 +105,7 @@ void VectorizerTestPass::testVectorShapeRatio(Function *f) {
VectorType::get(shape, FloatType::getF32(f->getContext()));
// Only filter instructions that operate on a strict super-vector and have one
// return. This makes testing easier.
auto filter = [subVectorType](const Instruction &inst) {
auto filter = [subVectorType](Instruction &inst) {
assert(subVectorType.getElementType() ==
FloatType::getF32(subVectorType.getContext()) &&
"Only f32 supported for now");
@ -150,7 +150,7 @@ static NestedPattern patternTestSlicingOps() {
using functional::map;
using matcher::Op;
// Match all OpInstructions with the kTestSlicingOpName name.
auto filter = [](const Instruction &inst) {
auto filter = [](Instruction &inst) {
return inst.getName().getStringRef() == kTestSlicingOpName;
};
return Op(filter);
@ -199,7 +199,7 @@ void VectorizerTestPass::testSlicing(Function *f) {
}
}
static bool customOpWithAffineMapAttribute(const Instruction &inst) {
static bool customOpWithAffineMapAttribute(Instruction &inst) {
return inst.getName().getStringRef() ==
VectorizerTestPass::kTestAffineMapOpName;
}
@ -225,11 +225,11 @@ void VectorizerTestPass::testComposeMaps(Function *f) {
simplifyAffineMap(res).print(outs() << "\nComposed map: ");
}
static bool affineApplyOp(const Instruction &inst) {
static bool affineApplyOp(Instruction &inst) {
return inst.isa<AffineApplyOp>();
}
static bool singleResultAffineApplyOpWithoutUses(const Instruction &inst) {
static bool singleResultAffineApplyOpWithoutUses(Instruction &inst) {
auto app = inst.dyn_cast<AffineApplyOp>();
return app && app->use_empty();
}

View File

@ -734,7 +734,7 @@ struct VectorizationState {
// Map of old scalar Instruction to new vectorized Instruction.
DenseMap<Instruction *, Instruction *> vectorizationMap;
// Map of old scalar Value to new vectorized Value.
DenseMap<const Value *, Value *> replacementMap;
DenseMap<Value *, Value *> replacementMap;
// The strategy drives which loop to vectorize by which amount.
const VectorizationStrategy *strategy;
// Use-def roots. These represent the starting points for the worklist in the
@ -755,7 +755,7 @@ struct VectorizationState {
void registerTerminal(Instruction *inst);
private:
void registerReplacement(const Value *key, Value *value);
void registerReplacement(Value *key, Value *value);
};
} // end namespace
@ -796,7 +796,7 @@ void VectorizationState::finishVectorizationPattern() {
}
}
void VectorizationState::registerReplacement(const Value *key, Value *value) {
void VectorizationState::registerReplacement(Value *key, Value *value) {
assert(replacementMap.count(key) == 0 && "replacement already registered");
replacementMap.insert(std::make_pair(key, value));
}
@ -858,8 +858,7 @@ static LogicalResult vectorizeAffineForOp(AffineForOp *loop, int64_t step,
using namespace functional;
loop->setStep(step);
FilterFunctionType notVectorizedThisPattern = [state](
const Instruction &inst) {
FilterFunctionType notVectorizedThisPattern = [state](Instruction &inst) {
if (!matcher::isLoadOrStore(inst)) {
return false;
}
@ -893,7 +892,7 @@ static LogicalResult vectorizeAffineForOp(AffineForOp *loop, int64_t step,
/// we can build a cost model and a search procedure.
static FilterFunctionType
isVectorizableLoopPtrFactory(unsigned fastestVaryingMemRefDimension) {
return [fastestVaryingMemRefDimension](const Instruction &forInst) {
return [fastestVaryingMemRefDimension](Instruction &forInst) {
auto loop = forInst.cast<AffineForOp>();
return isVectorizableLoopAlongFastestVaryingMemRefDim(
loop, fastestVaryingMemRefDimension);

View File

@ -47,5 +47,5 @@ def NS_AOp : Op<"a_op", [NoSideEffect]> {
// CHECK: bool fold(SmallVectorImpl<Value *> &results);
// CHECK: private:
// CHECK: friend class ::mlir::Instruction;
// CHECK: explicit AOp(const Instruction *state) : Op(state) {}
// CHECK: explicit AOp(Instruction *state) : Op(state) {}
// CHECK: };

View File

@ -321,8 +321,7 @@ void OpClass::writeDeclTo(raw_ostream &os) const {
}
os << "\nprivate:\n"
<< " friend class ::mlir::Instruction;\n";
os << " explicit " << className
<< "(const Instruction *state) : Op(state) {}\n"
os << " explicit " << className << "(Instruction *state) : Op(state) {}\n"
<< "};";
}