From: River Riddle Date: Tue, 20 Nov 2018 22:03:41 +0000 (-0800) Subject: Add functionality for erasing terminator successor operands and basic block arguments. X-Git-Tag: llvmorg-11-init~1466^2~2915 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5041e13c9653a9e18662132cc71790d477f1ecf0;p=platform%2Fupstream%2Fllvm.git Add functionality for erasing terminator successor operands and basic block arguments. PiperOrigin-RevId: 222303233 --- diff --git a/mlir/include/mlir/IR/BasicBlock.h b/mlir/include/mlir/IR/BasicBlock.h index 7220be524df2..72161f5b58f4 100644 --- a/mlir/include/mlir/IR/BasicBlock.h +++ b/mlir/include/mlir/IR/BasicBlock.h @@ -63,12 +63,15 @@ public: bool args_empty() const { return arguments.empty(); } - /// Add one value to the operand list. + /// Add one value to the argument list. BBArgument *addArgument(Type type); /// Add one argument to the argument list for each type specified in the list. llvm::iterator_range addArguments(ArrayRef types); + /// Erase the argument at 'index' and remove it from the argument list. + void eraseArgument(unsigned index); + unsigned getNumArguments() const { return arguments.size(); } BBArgument *getArgument(unsigned i) { return arguments[i]; } const BBArgument *getArgument(unsigned i) const { return arguments[i]; } @@ -258,6 +261,11 @@ public: return *this; } + /// Get the successor number in the predecessor terminator. + unsigned getSuccessorIndex() const { + return bbUseIterator->getOperandNumber(); + } + private: using BBUseIterator = SSAValueUseIterator; BBUseIterator bbUseIterator; @@ -316,6 +324,9 @@ public: BlockType *operator*() const { return this->object->getSuccessor(this->index); } + + /// Get the successor number in the terminator. + unsigned getSuccessorIndex() const { return this->index; } }; inline auto BasicBlock::succ_begin() const -> const_succ_iterator { diff --git a/mlir/include/mlir/IR/BuiltinOps.h b/mlir/include/mlir/IR/BuiltinOps.h index dec77ae7fe97..4916f0e5f134 100644 --- a/mlir/include/mlir/IR/BuiltinOps.h +++ b/mlir/include/mlir/IR/BuiltinOps.h @@ -119,8 +119,8 @@ public: /// Add a list of values to the operand list. void addOperands(ArrayRef values); - /// Erase a specific argument from the arg list. - // TODO: void eraseArgument(int Index); + /// Erase the operand at 'index' from the operand list. + void eraseOperand(unsigned index); private: friend class Operation; @@ -207,6 +207,9 @@ public: /// Add a list of values to the operand list. void addTrueOperands(ArrayRef values); + /// Erase the operand at 'index' from the true operand list. + void eraseTrueOperand(unsigned index); + // Accessors for operands to the 'false' destination. SSAValue *getFalseOperand(unsigned idx) { assert(idx < getNumFalseOperands()); @@ -246,6 +249,9 @@ public: /// Add a list of values to the false operand list. void addFalseOperands(ArrayRef values); + /// Erase the operand at 'index' from the false operand list. + void eraseFalseOperand(unsigned index); + private: /// Get the index of the first true destination operand. unsigned getTrueDestOperandIndex() { return 1; } diff --git a/mlir/include/mlir/IR/Instructions.h b/mlir/include/mlir/IR/Instructions.h index 1397e6fd5ae0..5e436acf11c5 100644 --- a/mlir/include/mlir/IR/Instructions.h +++ b/mlir/include/mlir/IR/Instructions.h @@ -227,8 +227,14 @@ public: /// index. void addSuccessorOperands(unsigned index, ArrayRef values); - /// Erase a specific argument from the arg list. - // TODO: void eraseSuccessorOperand(unsigned index, unsigned argIndex); + /// Erase a specific operand from the operand list of the successor at + /// 'index'. + void eraseSuccessorOperand(unsigned succIndex, unsigned opIndex) { + assert(succIndex < getNumSuccessors()); + assert(opIndex < getNumSuccessorOperands(succIndex)); + eraseOperand(getSuccessorOperandIndex(succIndex) + opIndex); + --getTrailingObjects()[succIndex]; + } /// Get the index of the first operand of the successor at the provided /// index. @@ -328,6 +334,9 @@ private: // does not have a virtual destructor. ~Instruction(); + /// Erase the operand at 'index'. + void eraseOperand(unsigned index); + friend struct llvm::ilist_traits; friend class BasicBlock; diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index 06108c60462e..622ed553d8aa 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -113,6 +113,7 @@ public: for (auto *value : values) addSuccessorOperand(index, value); } + void eraseSuccessorOperand(unsigned succIndex, unsigned opIndex); llvm::iterator_range getSuccessorOperands(unsigned index) const; llvm::iterator_range getSuccessorOperands(unsigned index); diff --git a/mlir/lib/IR/BasicBlock.cpp b/mlir/lib/IR/BasicBlock.cpp index cf677b34747f..8ba457af11d7 100644 --- a/mlir/lib/IR/BasicBlock.cpp +++ b/mlir/lib/IR/BasicBlock.cpp @@ -50,6 +50,21 @@ auto BasicBlock::addArguments(ArrayRef types) return {arguments.data() + initialSize, arguments.data() + arguments.size()}; } +void BasicBlock::eraseArgument(unsigned index) { + assert(index < arguments.size()); + + // Delete the argument. + delete arguments[index]; + arguments.erase(arguments.begin() + index); + + // Erase this argument from each of the predecessor's terminator. + for (auto predIt = pred_begin(), predE = pred_end(); predIt != predE; + ++predIt) { + auto *predTerminator = (*predIt)->getTerminator(); + predTerminator->eraseSuccessorOperand(predIt.getSuccessorIndex(), index); + } +} + //===----------------------------------------------------------------------===// // Terminator management //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/BuiltinOps.cpp b/mlir/lib/IR/BuiltinOps.cpp index fe1c4024c5e7..8e512dc3adb0 100644 --- a/mlir/lib/IR/BuiltinOps.cpp +++ b/mlir/lib/IR/BuiltinOps.cpp @@ -211,6 +211,10 @@ void BranchOp::addOperands(ArrayRef values) { return getOperation()->addSuccessorOperands(0, values); } +void BranchOp::eraseOperand(unsigned index) { + getOperation()->eraseSuccessorOperand(0, index); +} + //===----------------------------------------------------------------------===// // CondBranchOp //===----------------------------------------------------------------------===// @@ -290,6 +294,10 @@ void CondBranchOp::addTrueOperands(ArrayRef values) { return getOperation()->addSuccessorOperands(trueIndex, values); } +void CondBranchOp::eraseTrueOperand(unsigned index) { + getOperation()->eraseSuccessorOperand(trueIndex, index); +} + unsigned CondBranchOp::getNumFalseOperands() const { return getOperation()->getNumSuccessorOperands(falseIndex); } @@ -302,6 +310,10 @@ void CondBranchOp::addFalseOperands(ArrayRef values) { return getOperation()->addSuccessorOperands(falseIndex, values); } +void CondBranchOp::eraseFalseOperand(unsigned index) { + getOperation()->eraseSuccessorOperand(falseIndex, index); +} + //===----------------------------------------------------------------------===// // Constant*Op //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/Instructions.cpp b/mlir/lib/IR/Instructions.cpp index d1e3aab3d050..cd9bd594247b 100644 --- a/mlir/lib/IR/Instructions.cpp +++ b/mlir/lib/IR/Instructions.cpp @@ -188,6 +188,16 @@ Instruction::~Instruction() { successor.~BasicBlockOperand(); } +void Instruction::eraseOperand(unsigned index) { + assert(index < operands.size()); + + // Shift all operands down by 1. + for (unsigned i = index, e = operands.size() - 1; i != e; ++i) + operands[i].set(operands[i + 1].get()); + // Drop the last operand. + operands.pop_back(); +} + /// Destroy this instruction. void Instruction::destroy() { this->~Instruction(); diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp index bdf38745b709..728d2362c99d 100644 --- a/mlir/lib/IR/Operation.cpp +++ b/mlir/lib/IR/Operation.cpp @@ -168,6 +168,12 @@ void Operation::addSuccessorOperand(unsigned index, SSAValue *value) { return llvm::cast(this)->addSuccessorOperand( index, llvm::cast(value)); } +void Operation::eraseSuccessorOperand(unsigned succIndex, unsigned opIndex) { + assert(isTerminator() && "Only terminators have successors."); + assert(llvm::isa(this) && "Only instructions have successors."); + return llvm::cast(this)->eraseSuccessorOperand(succIndex, + opIndex); +} auto Operation::getSuccessorOperands(unsigned index) const -> llvm::iterator_range { assert(isTerminator() && "Only terminators have successors.");