Index: mlir/include/mlir/Dialect/ControlFlow/IR/ControlFlowOps.td =================================================================== --- mlir/include/mlir/Dialect/ControlFlow/IR/ControlFlowOps.td +++ mlir/include/mlir/Dialect/ControlFlow/IR/ControlFlowOps.td @@ -162,7 +162,7 @@ let extraClassDeclaration = [{ // These are the indices into the dests list. - enum { trueIndex = 0, falseIndex = 1 }; + enum { trueIndex = 0, falseIndex = 1, trueODSIndex = 1, falseODSIndex = 2 }; // Accessors for operands to the 'true' destination. Value getTrueOperand(unsigned idx) { @@ -192,6 +192,26 @@ setOperand(getFalseDestOperandIndex() + idx, value); } + /// Replace the operands of a branch beginning at 'start' and + /// ending at 'start' + 'length' with the ones provided in 'operands'. + /// 'operands' may be smaller or larger than the range pointed to by + /// 'start'+'length'. + void setTrueOperands(unsigned start, unsigned int length, ValueRange values) { + setBranchOperands(trueODSIndex, start, length, values); + } + void setFalseOperands(unsigned start, unsigned int length, ValueRange values) { + setBranchOperands(falseODSIndex, start, length, values); + } + + /// Insert the given operands into the operand list of a branch at + /// the given 'index'. + void insertTrueOperands(unsigned start, ValueRange values) { + setTrueOperands(start, 0, values); + } + void insertFalseOperands(unsigned start, ValueRange values) { + setFalseOperands(start, 0, values); + } + operand_range getTrueOperands() { return getTrueDestOperands(); } operand_range getFalseOperands() { return getFalseDestOperands(); } @@ -210,6 +230,9 @@ unsigned getFalseDestOperandIndex() { return getTrueDestOperandIndex() + getNumTrueOperands(); } + /// Insert operands values on branch brIndex starting from operandIdx + void setBranchOperands(unsigned brODSIndex, unsigned int startIdx, + unsigned int length, ValueRange values); }]; let hasCanonicalizer = 1; Index: mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp =================================================================== --- mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp +++ mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp @@ -450,6 +450,29 @@ return nullptr; } +/// Replace the operands of a branch beginning at 'start' and +/// ending at 'start' + 'length' with the ones provided in 'operands'. +/// 'operands' may be smaller or larger than the range pointed to by +/// 'start'+'length'. +void CondBranchOp::setBranchOperands(unsigned brODSIndex, unsigned int startIdx, + unsigned int length, ValueRange values) { + auto range = getODSOperandIndexAndLength(brODSIndex); + assert(startIdx <= range.second && "insertion out of range"); + auto sizeAttr = (*this) + ->getAttr(getOperandSegmentSizesAttrName()) + .cast<::mlir::DenseIntElementsAttr>(); + + /// Update sizes + llvm::SmallVector sizes(sizeAttr.value_begin(), + sizeAttr.value_end()); + sizes[brODSIndex] += values.size() - length; + auto newAttr = DenseIntElementsAttr::get(sizeAttr.getType(), sizes); + (*this)->setAttr(getOperandSegmentSizesAttrName(), newAttr); + + /// Update operands + (*this)->setOperands(range.first + startIdx, length, values); +} + //===----------------------------------------------------------------------===// // SwitchOp //===----------------------------------------------------------------------===//