diff --git a/mlir/include/mlir/IR/Value.h b/mlir/include/mlir/IR/Value.h --- a/mlir/include/mlir/IR/Value.h +++ b/mlir/include/mlir/IR/Value.h @@ -249,7 +249,8 @@ namespace detail { /// The internal implementation of a BlockArgument. class BlockArgumentImpl : public IRObjectWithUseList { - BlockArgumentImpl(Type type, Block *owner) : type(type), owner(owner) {} + BlockArgumentImpl(Type type, Block *owner, int64_t index) + : type(type), owner(owner), index(index) {} /// The type of this argument. Type type; @@ -257,6 +258,9 @@ /// The owner of this argument. Block *owner; + /// The position in the argument list. + int64_t index; + /// Allow access to owner and constructor. friend BlockArgument; }; @@ -280,13 +284,16 @@ /// Set the type of this value. void setType(Type newType) { getImpl()->type = newType; } + /// Set the type of this value. + void setArgNumber(int64_t index) { getImpl()->index = index; } + /// Returns the number of this argument. - unsigned getArgNumber() const; + unsigned getArgNumber() const { return getImpl()->index; } private: /// Allocate a new argument with the given type and owner. - static BlockArgument create(Type type, Block *owner) { - return new detail::BlockArgumentImpl(type, owner); + static BlockArgument create(Type type, Block *owner, int64_t index) { + return new detail::BlockArgumentImpl(type, owner, index); } /// Destroy and deallocate this argument. diff --git a/mlir/lib/IR/Block.cpp b/mlir/lib/IR/Block.cpp --- a/mlir/lib/IR/Block.cpp +++ b/mlir/lib/IR/Block.cpp @@ -12,17 +12,6 @@ #include "llvm/ADT/BitVector.h" using namespace mlir; -//===----------------------------------------------------------------------===// -// BlockArgument -//===----------------------------------------------------------------------===// - -/// Returns the number of this argument. -unsigned BlockArgument::getArgNumber() const { - // 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)); -} - //===----------------------------------------------------------------------===// // Block //===----------------------------------------------------------------------===// @@ -150,7 +139,7 @@ } BlockArgument Block::addArgument(Type type) { - BlockArgument arg = BlockArgument::create(type, this); + BlockArgument arg = BlockArgument::create(type, this, arguments.size()); arguments.push_back(arg); return arg; } @@ -165,16 +154,30 @@ } BlockArgument Block::insertArgument(unsigned index, Type type) { - auto arg = BlockArgument::create(type, this); + auto arg = BlockArgument::create(type, this, index); assert(index <= arguments.size()); arguments.insert(arguments.begin() + index, arg); + for (BlockArgument arg : + llvm::make_range(arguments.begin() + index, arguments.end())) + arg.setArgNumber(index++); return arg; } +/// Insert one value to the given position of the argument list. The existing +/// arguments are shifted. The block is expected not to have predecessors. +BlockArgument Block::insertArgument(args_iterator it, Type type) { + assert(llvm::empty(getPredecessors()) && + "cannot insert arguments to blocks with predecessors"); + return insertArgument(it->getArgNumber(), type); +} + void Block::eraseArgument(unsigned index) { assert(index < arguments.size()); arguments[index].destroy(); arguments.erase(arguments.begin() + index); + for (BlockArgument arg : + llvm::make_range(arguments.begin() + index, arguments.end())) + arg.setArgNumber(index++); } void Block::eraseArguments(ArrayRef argIndices) { @@ -191,21 +194,11 @@ for (unsigned i = 0; i < originalNumArgs; ++i) if (eraseIndices.test(originalNumArgs - i - 1)) eraseArgument(originalNumArgs - i - 1); + int64_t index = 0; + for (BlockArgument arg : arguments) + arg.setArgNumber(index++); } -/// Insert one value to the given position of the argument list. The existing -/// arguments are shifted. The block is expected not to have predecessors. -BlockArgument Block::insertArgument(args_iterator it, Type type) { - assert(llvm::empty(getPredecessors()) && - "cannot insert arguments to blocks with predecessors"); - - // Use the args_iterator (on the BlockArgListType) to compute the insertion - // iterator in the underlying argument storage. - size_t distance = std::distance(args_begin(), it); - auto arg = BlockArgument::create(type, this); - arguments.insert(std::next(arguments.begin(), distance), arg); - return arg; -} //===----------------------------------------------------------------------===// // Terminator management